Use user id instead of ice username

This commit is contained in:
dijunkun
2023-08-21 17:31:44 +08:00
parent 515f0c06bd
commit d5c1c26fc9
118 changed files with 26528 additions and 26275 deletions

View File

@@ -1,6 +1,6 @@
[signal server]
ip = localhost
port = 9095
port = 9090
[stun server]
ip = 120.77.216.215

View File

@@ -1,127 +1,127 @@
#include "ice_agent.h"
#include <string.h>
#include <iostream>
#include "log.h"
IceAgent::IceAgent(std::string &ip, uint16_t port) : ip_(ip), port_(port) {}
IceAgent::~IceAgent() {}
int IceAgent::CreateIceAgent(juice_cb_state_changed_t on_state_changed,
juice_cb_candidate_t on_candidate,
juice_cb_gathering_done_t on_gathering_done,
juice_cb_recv_t on_recv, void *user_ptr) {
// juice_set_log_level(JUICE_LOG_LEVEL_DEBUG);
juice_config_t config;
memset(&config, 0, sizeof(config));
LOG_INFO("stun server ip[{}] port[{}]", ip_, port_);
// STUN server example
config.stun_server_host = ip_.c_str();
config.stun_server_port = port_;
config.cb_state_changed = on_state_changed;
config.cb_candidate = on_candidate;
config.cb_gathering_done = on_gathering_done;
config.cb_recv = on_recv;
config.user_ptr = user_ptr;
agent_ = juice_create(&config);
return 0;
}
int IceAgent::DestoryIceAgent() {
juice_destroy(agent_);
return 0;
}
char *IceAgent::GenerateLocalSdp() {
if (nullptr == agent_) {
LOG_INFO("agent_ is nullptr");
return nullptr;
}
juice_get_local_description(agent_, local_sdp_, JUICE_MAX_SDP_STRING_LEN);
// LOG_INFO("Generate local sdp:[\n{}]", local_sdp_);
LOG_INFO("Generate local sdp");
return local_sdp_;
}
int IceAgent::SetRemoteSdp(const char *remote_sdp) {
LOG_INFO("Set remote sdp");
juice_set_remote_description(agent_, remote_sdp);
// LOG_INFO("Remote description:[\n{}]", remote_sdp);
return 0;
}
int IceAgent::GatherCandidates() {
LOG_INFO("[{}] Gather candidates", (void *)this);
juice_gather_candidates(agent_);
return 0;
}
juice_state_t IceAgent::GetIceState() {
state_ = juice_get_state(agent_);
return state_;
}
bool IceAgent::GetSelectedCandidates() {
char local[JUICE_MAX_CANDIDATE_SDP_STRING_LEN];
char remote[JUICE_MAX_CANDIDATE_SDP_STRING_LEN];
bool success = state_ == JUICE_STATE_COMPLETED;
if (success &= (juice_get_selected_candidates(
agent_, local, JUICE_MAX_CANDIDATE_SDP_STRING_LEN, remote,
JUICE_MAX_CANDIDATE_SDP_STRING_LEN) == 0)) {
LOG_INFO("Local candidate 1: {}", local);
LOG_INFO("Remote candidate 1: {}", remote);
if ((!strstr(local, "typ host") && !strstr(local, "typ prflx")) ||
(!strstr(remote, "typ host") && !strstr(remote, "typ prflx")))
success = false; // local connection should be possible
}
return success;
}
bool IceAgent::GetSelectedAddresses() {
char localAddr[JUICE_MAX_ADDRESS_STRING_LEN];
char remoteAddr[JUICE_MAX_ADDRESS_STRING_LEN];
bool success = state_ == JUICE_STATE_COMPLETED;
if (success &= (juice_get_selected_addresses(
agent_, localAddr, JUICE_MAX_ADDRESS_STRING_LEN,
remoteAddr, JUICE_MAX_ADDRESS_STRING_LEN) == 0)) {
LOG_INFO("Local address 1: {}", localAddr);
LOG_INFO("Remote address 1: {}", remoteAddr);
}
return success;
}
int IceAgent::AddRemoteCandidates(const char *remote_candidates) {
juice_add_remote_candidate(agent_, remote_candidates);
return 0;
}
int IceAgent::SetRemoteGatheringDone() {
juice_set_remote_gathering_done(agent_);
return 0;
}
int IceAgent::Send(const char *data, size_t size) {
juice_send(agent_, data, size);
return 0;
#include "ice_agent.h"
#include <string.h>
#include <iostream>
#include "log.h"
IceAgent::IceAgent(std::string &ip, uint16_t port) : ip_(ip), port_(port) {}
IceAgent::~IceAgent() {}
int IceAgent::CreateIceAgent(juice_cb_state_changed_t on_state_changed,
juice_cb_candidate_t on_candidate,
juice_cb_gathering_done_t on_gathering_done,
juice_cb_recv_t on_recv, void *user_ptr) {
// juice_set_log_level(JUICE_LOG_LEVEL_DEBUG);
juice_config_t config;
memset(&config, 0, sizeof(config));
LOG_INFO("stun server ip[{}] port[{}]", ip_, port_);
// STUN server example
config.stun_server_host = ip_.c_str();
config.stun_server_port = port_;
config.cb_state_changed = on_state_changed;
config.cb_candidate = on_candidate;
config.cb_gathering_done = on_gathering_done;
config.cb_recv = on_recv;
config.user_ptr = user_ptr;
agent_ = juice_create(&config);
return 0;
}
int IceAgent::DestoryIceAgent() {
juice_destroy(agent_);
return 0;
}
char *IceAgent::GenerateLocalSdp() {
if (nullptr == agent_) {
LOG_INFO("agent_ is nullptr");
return nullptr;
}
juice_get_local_description(agent_, local_sdp_, JUICE_MAX_SDP_STRING_LEN);
// LOG_INFO("Generate local sdp:[\n{}]", local_sdp_);
LOG_INFO("Generate local sdp");
return local_sdp_;
}
int IceAgent::SetRemoteSdp(const char *remote_sdp) {
LOG_INFO("[{}] Set remote sdp", (void *)this);
juice_set_remote_description(agent_, remote_sdp);
// LOG_INFO("Remote description:[\n{}]", remote_sdp);
return 0;
}
int IceAgent::GatherCandidates() {
LOG_INFO("[{}] Gather candidates", (void *)this);
juice_gather_candidates(agent_);
return 0;
}
juice_state_t IceAgent::GetIceState() {
state_ = juice_get_state(agent_);
return state_;
}
bool IceAgent::GetSelectedCandidates() {
char local[JUICE_MAX_CANDIDATE_SDP_STRING_LEN];
char remote[JUICE_MAX_CANDIDATE_SDP_STRING_LEN];
bool success = state_ == JUICE_STATE_COMPLETED;
if (success &= (juice_get_selected_candidates(
agent_, local, JUICE_MAX_CANDIDATE_SDP_STRING_LEN, remote,
JUICE_MAX_CANDIDATE_SDP_STRING_LEN) == 0)) {
LOG_INFO("Local candidate 1: {}", local);
LOG_INFO("Remote candidate 1: {}", remote);
if ((!strstr(local, "typ host") && !strstr(local, "typ prflx")) ||
(!strstr(remote, "typ host") && !strstr(remote, "typ prflx")))
success = false; // local connection should be possible
}
return success;
}
bool IceAgent::GetSelectedAddresses() {
char localAddr[JUICE_MAX_ADDRESS_STRING_LEN];
char remoteAddr[JUICE_MAX_ADDRESS_STRING_LEN];
bool success = state_ == JUICE_STATE_COMPLETED;
if (success &= (juice_get_selected_addresses(
agent_, localAddr, JUICE_MAX_ADDRESS_STRING_LEN,
remoteAddr, JUICE_MAX_ADDRESS_STRING_LEN) == 0)) {
LOG_INFO("Local address 1: {}", localAddr);
LOG_INFO("Remote address 1: {}", remoteAddr);
}
return success;
}
int IceAgent::AddRemoteCandidates(const char *remote_candidates) {
juice_add_remote_candidate(agent_, remote_candidates);
return 0;
}
int IceAgent::SetRemoteGatheringDone() {
juice_set_remote_gathering_done(agent_);
return 0;
}
int IceAgent::Send(const char *data, size_t size) {
juice_send(agent_, data, size);
return 0;
}

View File

@@ -1,46 +1,46 @@
#ifndef _ICE_AGENT_H_
#define _ICE_AGENT_H_
#include <iostream>
#include "juice/juice.h"
class IceAgent {
public:
IceAgent(std::string& ip, uint16_t port);
~IceAgent();
int CreateIceAgent(juice_cb_state_changed_t on_state_changed,
juice_cb_candidate_t on_candidate,
juice_cb_gathering_done_t on_gathering_done,
juice_cb_recv_t on_recv, void* user_ptr);
int DestoryIceAgent();
char* GenerateLocalSdp();
int SetRemoteSdp(const char* remote_sdp);
int GatherCandidates();
juice_state_t GetIceState();
bool GetSelectedCandidates();
bool GetSelectedAddresses();
int AddRemoteCandidates(const char* remote_candidates);
int SetRemoteGatheringDone();
int Send(const char* data, size_t size);
private:
std::string ip_ = "";
uint16_t port_ = 0;
juice_agent_t* agent_ = nullptr;
char local_sdp_[JUICE_MAX_SDP_STRING_LEN];
juice_state_t state_;
};
#ifndef _ICE_AGENT_H_
#define _ICE_AGENT_H_
#include <iostream>
#include "juice/juice.h"
class IceAgent {
public:
IceAgent(std::string& ip, uint16_t port);
~IceAgent();
int CreateIceAgent(juice_cb_state_changed_t on_state_changed,
juice_cb_candidate_t on_candidate,
juice_cb_gathering_done_t on_gathering_done,
juice_cb_recv_t on_recv, void* user_ptr);
int DestoryIceAgent();
char* GenerateLocalSdp();
int SetRemoteSdp(const char* remote_sdp);
int GatherCandidates();
juice_state_t GetIceState();
bool GetSelectedCandidates();
bool GetSelectedAddresses();
int AddRemoteCandidates(const char* remote_candidates);
int SetRemoteGatheringDone();
int Send(const char* data, size_t size);
private:
std::string ip_ = "";
uint16_t port_ = 0;
juice_agent_t* agent_ = nullptr;
char local_sdp_[JUICE_MAX_SDP_STRING_LEN];
juice_state_t state_;
};
#endif

View File

@@ -15,9 +15,11 @@ const std::vector<std::string> ice_status = {
"JUICE_STATE_COMPLETED", "JUICE_STATE_FAILED"};
IceTransmission::IceTransmission(
bool offer_peer, WsTransmission *ice_ws_transmission,
bool offer_peer, std::string remote_ice_username,
WsTransmission *ice_ws_transmission,
std::function<void(const char *, size_t)> on_receive_ice_msg)
: offer_peer_(offer_peer),
remote_ice_username_(remote_ice_username),
ice_ws_transport_(ice_ws_transmission),
on_receive_ice_msg_cb_(on_receive_ice_msg) {}
@@ -45,6 +47,7 @@ int IceTransmission::InitIceTransmission(std::string &ip, int port) {
if (ice_transmission_obj->offer_peer_) {
ice_transmission_obj->GetLocalSdp();
ice_transmission_obj->SendOffer();
LOG_INFO("[{}] SendOffer", (void *)ice_transmission_obj)
} else {
ice_transmission_obj->CreateAnswer();
ice_transmission_obj->SendAnswer();
@@ -90,10 +93,18 @@ int IceTransmission::CreateTransmission(const std::string &transmission_id) {
return 0;
}
int IceTransmission::JoinTransmission(const std::string &transmission_id) {
int IceTransmission::SetTransmissionId(const std::string &transmission_id) {
transmission_id_ = transmission_id;
return 0;
}
int IceTransmission::JoinTransmission(const std::string &transmission_id,
const std::string &user_id) {
LOG_INFO("Join transport");
offer_peer_ = true;
transmission_id_ = transmission_id;
user_id_ = user_id;
// if (SignalStatus::Connected != signal_status_) {
// LOG_ERROR("Not connect to signalserver");
@@ -112,6 +123,7 @@ int IceTransmission::GatherCandidates() {
int IceTransmission::GetLocalSdp() {
local_sdp_ = ice_agent_->GenerateLocalSdp();
LOG_INFO("Local ice username: [{}]", GetIceUsername(local_sdp_));
return 0;
}
@@ -127,7 +139,7 @@ int IceTransmission::AddRemoteCandidate(const std::string &remote_candidate) {
}
int IceTransmission::CreateOffer() {
LOG_INFO("Create offer");
LOG_INFO("[{}] Create offer", (void *)this);
GatherCandidates();
return 0;
}
@@ -135,6 +147,8 @@ int IceTransmission::CreateOffer() {
int IceTransmission::SendOffer() {
json message = {{"type", "offer"},
{"transmission_id", transmission_id_},
{"user_id", user_id_},
{"remote_peer", remote_ice_username_},
{"sdp", local_sdp_}};
// LOG_INFO("Send offer:\n{}", message.dump().c_str());
LOG_INFO("Send offer");
@@ -166,7 +180,7 @@ int IceTransmission::SendAnswer() {
{"transmission_id", transmission_id_},
{"sdp", local_sdp_},
{"guest", remote_ice_username_}};
// LOG_INFO("Send answer:\n{}", message.dump().c_str());
LOG_INFO("[{}] Send answer to [{}]", GetIceUsername(local_sdp_),
remote_ice_username_);

View File

@@ -8,7 +8,8 @@
class IceTransmission {
public:
IceTransmission(bool offer_peer, WsTransmission *ice_ws_transmission,
IceTransmission(bool offer_peer, std::string remote_ice_username,
WsTransmission *ice_ws_transmission,
std::function<void(const char *, size_t)> on_receive_ice_msg);
~IceTransmission();
@@ -18,7 +19,10 @@ class IceTransmission {
int DestroyIceTransmission();
int CreateTransmission(const std::string &transmission_id);
int JoinTransmission(const std::string &transmission_id);
int JoinTransmission(const std::string &transmission_id,
const std::string &user_id);
int SetTransmissionId(const std::string &transmission_id);
int SendData(const char *data, size_t size);
@@ -55,12 +59,13 @@ class IceTransmission {
std::function<void(const char *, size_t)> on_receive_ice_msg_cb_ = nullptr;
std::string local_sdp_;
std::string remote_sdp_;
std::string remote_ice_username_;
std::string local_candidates_;
std::string remote_candidates_;
unsigned int connection_id_ = 0;
std::string transmission_id_ = "";
std::string user_id_ = "";
bool offer_peer_ = true;
std::string remote_ice_username_ = "";
};
#endif

View File

@@ -1,38 +1,39 @@
#ifndef _X_H_
#define _X_H_
#include <stdint.h>
#include <stdlib.h>
enum ws_status { WS_CONNECTING = 0, WS_OPEN, WS_FAILED, WS_CLOSED, WS_UNKNOWN };
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Peer PeerPtr;
typedef void (*OnReceiveBuffer)(unsigned char*, size_t, const char*,
const size_t);
typedef void (*NetStatusReport)(const unsigned short, const unsigned short);
typedef struct {
const char* cfg_path;
OnReceiveBuffer on_receive_buffer;
NetStatusReport net_status_report;
} Params;
PeerPtr* CreatePeer(const Params* params);
int CreateConnection(PeerPtr* peer_ptr);
int JoinConnection(PeerPtr* peer_ptr, const char* connection_id);
int SendData(PeerPtr* peer_ptr, const char* data, size_t size);
#ifdef __cplusplus
}
#endif
#ifndef _X_H_
#define _X_H_
#include <stdint.h>
#include <stdlib.h>
enum ws_status { WS_CONNECTING = 0, WS_OPEN, WS_FAILED, WS_CLOSED, WS_UNKNOWN };
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Peer PeerPtr;
typedef void (*OnReceiveBuffer)(unsigned char*, size_t, const char*,
const size_t);
typedef void (*NetStatusReport)(const unsigned short, const unsigned short);
typedef struct {
const char* cfg_path;
OnReceiveBuffer on_receive_buffer;
NetStatusReport net_status_report;
} Params;
PeerPtr* CreatePeer(const Params* params);
int CreateConnection(PeerPtr* peer_ptr);
int JoinConnection(PeerPtr* peer_ptr, const char* transmission_id,
const char* user_id);
int SendData(PeerPtr* peer_ptr, const char* data, size_t size);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,127 +1,127 @@
#ifndef _LOG_H_
#define _LOG_H_
#include <chrono>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include "spdlog/common.h"
#include "spdlog/logger.h"
#include "spdlog/sinks/base_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h"
using namespace std::chrono;
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
// SPDLOG_TRACE(...)
// SPDLOG_DEBUG(...)
// SPDLOG_INFO(...)
// SPDLOG_WARN(...)
// SPDLOG_ERROR(...)
// SPDLOG_CRITICAL(...)
#ifdef SIGNAL_LOGGER
constexpr auto LOGGER_NAME = "siganl";
#else
constexpr auto LOGGER_NAME = "rtc";
#endif
#define LOG_INFO(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
combined_logger->flush_on(spdlog::level::info); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_INFO(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_INFO(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#define LOG_WARN(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_WARN(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_WARN(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#define LOG_ERROR(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_ERROR(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_ERROR(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#define LOG_FATAL(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_CRITICAL(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_CRITICAL(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#endif
#ifndef _LOG_H_
#define _LOG_H_
#include <chrono>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include "spdlog/common.h"
#include "spdlog/logger.h"
#include "spdlog/sinks/base_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h"
using namespace std::chrono;
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
// SPDLOG_TRACE(...)
// SPDLOG_DEBUG(...)
// SPDLOG_INFO(...)
// SPDLOG_WARN(...)
// SPDLOG_ERROR(...)
// SPDLOG_CRITICAL(...)
#ifdef SIGNAL_LOGGER
constexpr auto LOGGER_NAME = "siganl";
#else
constexpr auto LOGGER_NAME = "rtc";
#endif
#define LOG_INFO(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
combined_logger->flush_on(spdlog::level::info); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_INFO(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_INFO(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#define LOG_WARN(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_WARN(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_WARN(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#define LOG_ERROR(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_ERROR(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_ERROR(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#define LOG_FATAL(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_CRITICAL(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_CRITICAL(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#endif

View File

@@ -1,257 +1,320 @@
#include "peer_connection.h"
#include <regex>
#include "INIReader.h"
#include "common.h"
#include "log.h"
#include "nlohmann/json.hpp"
using nlohmann::json;
static const std::map<std::string, unsigned int> siganl_types{
{"ws_connection_id", 1},
{"offer", 2},
{"transmission_id", 3},
{"remote_sdp", 4},
{"candidate", 5}};
PeerConnection::PeerConnection() {}
PeerConnection::~PeerConnection() {}
int PeerConnection::Create(PeerConnectionParams params,
const std::string &transmission_id) {
INIReader reader(params.cfg_path);
cfg_signal_server_ip_ = reader.Get("signal server", "ip", "-1");
cfg_signal_server_port_ = reader.Get("signal server", "port", "-1");
cfg_stun_server_ip_ = reader.Get("stun server", "ip", "-1");
cfg_stun_server_port_ = reader.Get("stun server", "port", "-1");
std::regex regex("\n");
LOG_INFO("Read config success");
signal_server_port_ = stoi(cfg_signal_server_port_);
stun_server_port_ = stoi(cfg_stun_server_port_);
on_receive_ws_msg_ = [this](const std::string &msg) {
auto j = json::parse(msg);
std::string type = j["type"];
LOG_INFO("msg type :{}", type.c_str());
switch (HASH_STRING_PIECE(type.c_str())) {
case "ws_connection_id"_H: {
ws_connection_id_ = j["ws_connection_id"].get<unsigned int>();
LOG_INFO("Receive local peer websocket connection id [{}]",
ws_connection_id_);
signal_status_ = SignalStatus::Connected;
break;
}
case "transmission_id"_H: {
if (j["status"].get<std::string>() == "success") {
transmission_id_ = j["transmission_id"].get<std::string>();
LOG_INFO("Create transmission success with id [{}]",
transmission_id_);
} else if (j["status"].get<std::string>() == "fail") {
LOG_WARN("Create transmission failed with id [{}], due to [{}]",
transmission_id_, j["reason"].get<std::string>().c_str());
}
break;
}
case "offer"_H: {
std::string remote_sdp = j["sdp"].get<std::string>();
if (remote_sdp.empty()) {
LOG_INFO("Invalid remote sdp");
} else {
std::string ice_username = GetIceUsername(remote_sdp);
LOG_INFO("Receive remote sdp from [{}]", ice_username);
// IceTransmission *ice_transmission =
// new IceTransmission(false, ws_transport_, on_receive_ice_msg_);
ice_transmission_list_[ice_username] =
new IceTransmission(false, ws_transport_, on_receive_ice_msg_);
ice_transmission_list_[ice_username]->InitIceTransmission(
cfg_stun_server_ip_, stun_server_port_);
ice_transmission_list_[ice_username]->SetRemoteSdp(remote_sdp);
ice_transmission_list_[ice_username]->GatherCandidates();
}
break;
}
default: {
// ice_transmission_->OnReceiveMessage(msg);
break;
}
}
};
on_receive_ice_msg_ = [this](const char *data, size_t size) {
std::string msg(data, size);
LOG_INFO("Receive data: [{}]", msg.c_str());
};
ws_transport_ = new WsTransmission(on_receive_ws_msg_);
uri_ = "ws://" + cfg_signal_server_ip_ + ":" + cfg_signal_server_port_;
if (ws_transport_) {
ws_transport_->Connect(uri_);
}
do {
LOG_INFO("GetSignalStatus = {}", GetSignalStatus());
} while (SignalStatus::Connected != GetSignalStatus());
// ice_transmission_->CreateTransmission(transmission_id);
json message = {{"type", "create_transmission"},
{"transmission_id", transmission_id}};
if (ws_transport_) {
ws_transport_->Send(message.dump());
LOG_INFO("Send create transmission request: {}", message.dump().c_str());
}
return 0;
}
int PeerConnection::Join(PeerConnectionParams params,
const std::string &transmission_id) {
INIReader reader(params.cfg_path);
cfg_signal_server_ip_ = reader.Get("signal server", "ip", "-1");
cfg_signal_server_port_ = reader.Get("signal server", "port", "-1");
cfg_stun_server_ip_ = reader.Get("stun server", "ip", "-1");
cfg_stun_server_port_ = reader.Get("stun server", "port", "-1");
std::regex regex("\n");
LOG_INFO("Read config success");
signal_server_port_ = stoi(cfg_signal_server_port_);
stun_server_port_ = stoi(cfg_stun_server_port_);
on_receive_ws_msg_ = [this](const std::string &msg) {
do {
} while (ice_transmission_list_.empty());
auto j = json::parse(msg);
std::string type = j["type"];
LOG_INFO("msg type :{}", type.c_str());
switch (HASH_STRING_PIECE(type.c_str())) {
case "ws_connection_id"_H: {
ws_connection_id_ = j["ws_connection_id"].get<unsigned int>();
LOG_INFO("Receive local peer websocket connection id [{}]",
ws_connection_id_);
signal_status_ = SignalStatus::Connected;
break;
}
case "offer"_H: {
std::string remote_sdp = j["sdp"].get<std::string>();
if (remote_sdp.empty()) {
LOG_INFO("Invalid remote sdp");
} else {
std::string ice_username = GetIceUsername(remote_sdp);
LOG_INFO("Receive remote sdp from [{}]", ice_username);
// IceTransmission *ice_transmission =
// new IceTransmission(false, ws_transport_, on_receive_ice_msg_);
ice_transmission_list_[ice_username] =
new IceTransmission(false, ws_transport_, on_receive_ice_msg_);
ice_transmission_list_[ice_username]->InitIceTransmission(
cfg_stun_server_ip_, stun_server_port_);
ice_transmission_list_[ice_username]->SetRemoteSdp(remote_sdp);
ice_transmission_list_[ice_username]->GatherCandidates();
}
break;
}
case "remote_sdp"_H: {
std::string remote_sdp = j["sdp"].get<std::string>();
if (remote_sdp.empty()) {
LOG_INFO("remote_sdp is empty");
} else {
std::string ice_username = GetIceUsername(remote_sdp);
LOG_INFO("Receive remote sdp from [{}]", ice_username);
// LOG_INFO("Receive remote sdp [{}]", remote_sdp);
if (ice_transmission_list_.size() == 1 &&
ice_transmission_list_.begin()->first == "self") {
ice_transmission_list_["self"]->SetRemoteSdp(remote_sdp);
} else if (ice_transmission_list_.find(ice_username) ==
ice_transmission_list_.end()) {
ice_transmission_list_[ice_username] =
new IceTransmission(false, ws_transport_, on_receive_ice_msg_);
ice_transmission_list_[ice_username]->InitIceTransmission(
cfg_stun_server_ip_, stun_server_port_);
ice_transmission_list_[ice_username]->SetRemoteSdp(remote_sdp);
}
// if (!offer_peer_) {
// GatherCandidates();
// }
}
break;
}
case "candidate"_H: {
std::string remote_sdp_with_candidates = j["sdp"].get<std::string>();
std::string ice_username = GetIceUsername(remote_sdp_with_candidates);
LOG_INFO("Receive remote candidates from [{}]", ice_username);
// LOG_INFO("Receive candidate [{}]", candidate);
ice_transmission_list_[ice_username]->AddRemoteCandidate(
remote_sdp_with_candidates);
break;
}
default: {
ice_transmission_->OnReceiveMessage(msg);
break;
}
}
};
on_receive_ice_msg_ = [this](const char *data, size_t size) {
std::string msg(data, size);
LOG_INFO("Receive data: [{}]", msg.c_str());
};
transmission_id_ = transmission_id;
ws_transport_ = new WsTransmission(on_receive_ws_msg_);
uri_ = "ws://" + cfg_signal_server_ip_ + ":" + cfg_signal_server_port_;
if (ws_transport_) {
ws_transport_->Connect(uri_);
}
ice_transmission_list_["self"] =
new IceTransmission(true, ws_transport_, on_receive_ice_msg_);
ice_transmission_list_["self"]->InitIceTransmission(cfg_stun_server_ip_,
stun_server_port_);
// ice_transmission_ =
// new IceTransmission(true, ws_transport_, on_receive_ice_msg_);
// ice_transmission_->InitIceTransmission(cfg_stun_server_ip,
// stun_server_port);
do {
// LOG_INFO("GetSignalStatus = {}", GetSignalStatus());
} while (SignalStatus::Connected != GetSignalStatus());
// ice_transmission_->JoinTransmission(transmission_id_);
ice_transmission_list_["self"]->JoinTransmission(transmission_id_);
return 0;
}
int PeerConnection::Destroy() {
if (ws_transport_) {
delete ws_transport_;
}
return 0;
}
SignalStatus PeerConnection::GetSignalStatus() { return signal_status_; }
int PeerConnection::SendData(const char *data, size_t size) {
for (auto ice_trans : ice_transmission_list_) {
ice_trans.second->SendData(data, size);
}
return 0;
#include "peer_connection.h"
#include <regex>
#include "INIReader.h"
#include "common.h"
#include "log.h"
#include "nlohmann/json.hpp"
using nlohmann::json;
static const std::map<std::string, unsigned int> siganl_types{
{"ws_connection_id", 1},
{"offer", 2},
{"transmission_id", 3},
{"remote_sdp", 4},
{"candidate", 5}};
PeerConnection::PeerConnection() {}
PeerConnection::~PeerConnection() {}
int PeerConnection::Create(PeerConnectionParams params,
const std::string &transmission_id,
const std::string &user_id) {
user_id_ = user_id;
INIReader reader(params.cfg_path);
cfg_signal_server_ip_ = reader.Get("signal server", "ip", "-1");
cfg_signal_server_port_ = reader.Get("signal server", "port", "-1");
cfg_stun_server_ip_ = reader.Get("stun server", "ip", "-1");
cfg_stun_server_port_ = reader.Get("stun server", "port", "-1");
std::regex regex("\n");
LOG_INFO("Read config success");
signal_server_port_ = stoi(cfg_signal_server_port_);
stun_server_port_ = stoi(cfg_stun_server_port_);
on_receive_ws_msg_ = [this](const std::string &msg) {
auto j = json::parse(msg);
std::string type = j["type"];
LOG_INFO("msg type :{}", type.c_str());
switch (HASH_STRING_PIECE(type.c_str())) {
case "ws_connection_id"_H: {
ws_connection_id_ = j["ws_connection_id"].get<unsigned int>();
LOG_INFO("Receive local peer websocket connection id [{}]",
ws_connection_id_);
signal_status_ = SignalStatus::Connected;
break;
}
case "transmission_id"_H: {
if (j["status"].get<std::string>() == "success") {
transmission_id_ = j["transmission_id"].get<std::string>();
LOG_INFO("Create transmission success with id [{}]",
transmission_id_);
} else if (j["status"].get<std::string>() == "fail") {
LOG_WARN("Create transmission failed with id [{}], due to [{}]",
transmission_id_, j["reason"].get<std::string>().c_str());
}
break;
}
case "offer"_H: {
std::string remote_sdp = j["sdp"].get<std::string>();
if (remote_sdp.empty()) {
LOG_INFO("Invalid remote sdp");
} else {
std::string ice_username = GetIceUsername(remote_sdp);
LOG_INFO("Receive remote sdp from [{}]", ice_username);
// IceTransmission *ice_transmission =
// new IceTransmission(false, ws_transport_, on_receive_ice_msg_);
ice_transmission_list_[ice_username] = new IceTransmission(
false, ice_username, ws_transport_, on_receive_ice_msg_);
ice_transmission_list_[ice_username]->InitIceTransmission(
cfg_stun_server_ip_, stun_server_port_);
ice_transmission_list_[ice_username]->SetTransmissionId(
transmission_id_);
ice_transmission_list_[ice_username]->SetRemoteSdp(remote_sdp);
ice_transmission_list_[ice_username]->GatherCandidates();
}
break;
}
default: {
// ice_transmission_->OnReceiveMessage(msg);
break;
}
}
};
on_receive_ice_msg_ = [this](const char *data, size_t size) {
std::string msg(data, size);
LOG_INFO("Receive data: [{}]", msg.c_str());
};
ws_transport_ = new WsTransmission(on_receive_ws_msg_);
uri_ = "ws://" + cfg_signal_server_ip_ + ":" + cfg_signal_server_port_;
if (ws_transport_) {
ws_transport_->Connect(uri_);
}
do {
LOG_INFO("GetSignalStatus = {}", GetSignalStatus());
} while (SignalStatus::Connected != GetSignalStatus());
json message = {{"type", "create_transmission"},
{"user_id", user_id},
{"transmission_id", transmission_id}};
if (ws_transport_) {
ws_transport_->Send(message.dump());
LOG_INFO("Send create transmission request: {}", message.dump().c_str());
}
return 0;
}
int PeerConnection::Join(PeerConnectionParams params,
const std::string &transmission_id,
const std::string &user_id) {
// Todo: checkout user_id unique or not
user_id_ = user_id;
INIReader reader(params.cfg_path);
cfg_signal_server_ip_ = reader.Get("signal server", "ip", "-1");
cfg_signal_server_port_ = reader.Get("signal server", "port", "-1");
cfg_stun_server_ip_ = reader.Get("stun server", "ip", "-1");
cfg_stun_server_port_ = reader.Get("stun server", "port", "-1");
std::regex regex("\n");
LOG_INFO("Read config success");
signal_server_port_ = stoi(cfg_signal_server_port_);
stun_server_port_ = stoi(cfg_stun_server_port_);
on_receive_ws_msg_ = [this](const std::string &msg) {
// do {
// } while (ice_transmission_list_.empty());
auto j = json::parse(msg);
std::string type = j["type"];
LOG_INFO("msg type :{}", type);
switch (HASH_STRING_PIECE(type.c_str())) {
case "transmission_members"_H: {
transmission_member_list_ = j["transmission_members"];
std::string transmission_id = j["transmission_id"];
LOG_INFO("Transmission [{}] members: [", transmission_id);
for (auto member : transmission_member_list_) {
LOG_INFO("{}", member);
}
LOG_INFO("]");
if (transmission_member_list_.size() == 1 &&
transmission_member_list_[0] == "host") {
ice_transmission_list_["host"] = new IceTransmission(
true, "host", ws_transport_, on_receive_ice_msg_);
ice_transmission_list_["host"]->InitIceTransmission(
cfg_stun_server_ip_, stun_server_port_);
ice_transmission_list_["host"]->JoinTransmission(transmission_id,
user_id_);
} else {
for (auto &member : transmission_member_list_) {
ice_transmission_list_[member] = new IceTransmission(
true, member, ws_transport_, on_receive_ice_msg_);
ice_transmission_list_[member]->InitIceTransmission(
cfg_stun_server_ip_, stun_server_port_);
ice_transmission_list_[member]->JoinTransmission(transmission_id,
user_id_);
}
}
break;
}
case "ws_connection_id"_H: {
ws_connection_id_ = j["ws_connection_id"].get<unsigned int>();
LOG_INFO("Receive local peer websocket connection id [{}]",
ws_connection_id_);
signal_status_ = SignalStatus::Connected;
break;
}
case "offer"_H: {
std::string remote_sdp = j["sdp"].get<std::string>();
if (remote_sdp.empty()) {
LOG_INFO("Invalid remote sdp");
} else {
std::string ice_username = GetIceUsername(remote_sdp);
LOG_INFO("Receive remote sdp from [{}]", ice_username);
// IceTransmission *ice_transmission =
// new IceTransmission(false, ws_transport_, on_receive_ice_msg_);
ice_transmission_list_[ice_username] = new IceTransmission(
false, ice_username, ws_transport_, on_receive_ice_msg_);
ice_transmission_list_[ice_username]->InitIceTransmission(
cfg_stun_server_ip_, stun_server_port_);
ice_transmission_list_[ice_username]->SetRemoteSdp(remote_sdp);
ice_transmission_list_[ice_username]->GatherCandidates();
}
break;
}
case "remote_sdp"_H: {
std::string remote_sdp = j["sdp"].get<std::string>();
if (remote_sdp.empty()) {
LOG_INFO("remote_sdp is empty");
} else {
std::string ice_username = GetIceUsername(remote_sdp);
LOG_INFO("Receive remote sdp from [{}]", ice_username);
// LOG_INFO("Receive remote sdp [{}]", remote_sdp);
// if (ice_transmission_list_.size() == 1 &&
// ice_transmission_list_.begin()->first == "host") {
// ice_transmission_list_["host"]->SetRemoteSdp(remote_sdp);
// } else if (ice_transmission_list_.find(ice_username) ==
// ice_transmission_list_.end()) {
// ice_transmission_list_[ice_username] = new IceTransmission(
// false, ice_username, ws_transport_, on_receive_ice_msg_);
// ice_transmission_list_[ice_username]->InitIceTransmission(
// cfg_stun_server_ip_, stun_server_port_);
// ice_transmission_list_[ice_username]->SetRemoteSdp(remote_sdp);
// }
if (ice_transmission_list_.size() == 1 &&
ice_transmission_list_.begin()->first == "host") {
ice_transmission_list_["host"]->SetRemoteSdp(remote_sdp);
} else if (ice_transmission_list_.find(ice_username) !=
ice_transmission_list_.end()) {
ice_transmission_list_[ice_username]->SetRemoteSdp(remote_sdp);
}
// if (!offer_peer_) {
// GatherCandidates();
// }
}
break;
}
case "candidate"_H: {
std::string remote_sdp_with_candidates = j["sdp"].get<std::string>();
std::string ice_username = GetIceUsername(remote_sdp_with_candidates);
LOG_INFO("Receive remote candidates from [{}]", ice_username);
// LOG_INFO("Receive candidate [{}]", candidate);
ice_transmission_list_[ice_username]->AddRemoteCandidate(
remote_sdp_with_candidates);
break;
}
default: {
ice_transmission_->OnReceiveMessage(msg);
break;
}
}
};
on_receive_ice_msg_ = [this](const char *data, size_t size) {
std::string msg(data, size);
LOG_INFO("Receive data: [{}]", msg.c_str());
};
transmission_id_ = transmission_id;
ws_transport_ = new WsTransmission(on_receive_ws_msg_);
uri_ = "ws://" + cfg_signal_server_ip_ + ":" + cfg_signal_server_port_;
if (ws_transport_) {
ws_transport_->Connect(uri_);
}
// ice_transmission_list_["self"] =
// new IceTransmission(true, ws_transport_, on_receive_ice_msg_);
// ice_transmission_list_["self"]->InitIceTransmission(cfg_stun_server_ip_,
// stun_server_port_);
// ice_transmission_ =
// new IceTransmission(true, ws_transport_, on_receive_ice_msg_);
// ice_transmission_->InitIceTransmission(cfg_stun_server_ip,
// stun_server_port);
do {
// LOG_INFO("GetSignalStatus = {}", GetSignalStatus());
} while (SignalStatus::Connected != GetSignalStatus());
RequestTransmissionMemberList(transmission_id_);
// ice_transmission_->JoinTransmission(transmission_id_);
// ice_transmission_list_["self"]->JoinTransmission(transmission_id_);
return 0;
}
int PeerConnection::RequestTransmissionMemberList(
const std::string &transmission_id) {
LOG_INFO("Request member list");
json message = {{"type", "query_members"},
{"transmission_id", transmission_id_}};
if (ws_transport_) {
ws_transport_->Send(message.dump());
}
return 0;
}
int PeerConnection::Destroy() {
if (ws_transport_) {
delete ws_transport_;
}
return 0;
}
SignalStatus PeerConnection::GetSignalStatus() { return signal_status_; }
int PeerConnection::SendData(const char *data, size_t size) {
for (auto ice_trans : ice_transmission_list_) {
ice_trans.second->SendData(data, size);
}
return 0;
}

View File

@@ -1,55 +1,62 @@
#ifndef _PEER_CONNECTION_H_
#define _PEER_CONNECTION_H_
#include <iostream>
#include <map>
#include "ice_transmission.h"
#include "ws_transmission.h"
enum SignalStatus { Connecting = 0, Connected, Closed };
typedef void (*OnReceiveBuffer)(unsigned char *, size_t, const char *,
const size_t);
typedef void (*NetStatusReport)(const unsigned short, const unsigned short);
typedef struct {
const char *cfg_path;
OnReceiveBuffer on_receive_buffer;
NetStatusReport net_status_report;
} PeerConnectionParams;
class PeerConnection {
public:
PeerConnection();
~PeerConnection();
public:
int Create(PeerConnectionParams params, const std::string &id = "");
int Join(PeerConnectionParams params, const std::string &id);
int Destroy();
SignalStatus GetSignalStatus();
int SendData(const char *data, size_t size);
private:
std::string uri_ = "";
std::string cfg_signal_server_ip_;
std::string cfg_signal_server_port_;
std::string cfg_stun_server_ip_;
std::string cfg_stun_server_port_;
int signal_server_port_ = 0;
int stun_server_port_ = 0;
WsTransmission *ws_transport_ = nullptr;
IceTransmission *ice_transmission_ = nullptr;
std::map<std::string, IceTransmission *> ice_transmission_list_;
std::function<void(const std::string &)> on_receive_ws_msg_ = nullptr;
std::function<void(const char *, size_t)> on_receive_ice_msg_ = nullptr;
unsigned int ws_connection_id_ = 0;
std::string transmission_id_ = "";
SignalStatus signal_status_ = SignalStatus::Closed;
};
#ifndef _PEER_CONNECTION_H_
#define _PEER_CONNECTION_H_
#include <iostream>
#include <map>
#include "ice_transmission.h"
#include "ws_transmission.h"
enum SignalStatus { Connecting = 0, Connected, Closed };
typedef void (*OnReceiveBuffer)(unsigned char *, size_t, const char *,
const size_t);
typedef void (*NetStatusReport)(const unsigned short, const unsigned short);
typedef struct {
const char *cfg_path;
OnReceiveBuffer on_receive_buffer;
NetStatusReport net_status_report;
} PeerConnectionParams;
class PeerConnection {
public:
PeerConnection();
~PeerConnection();
public:
int Create(PeerConnectionParams params,
const std::string &transmission_id = "",
const std::string &user_id = "");
int Join(PeerConnectionParams params, const std::string &transmission_id,
const std::string &user_id = "");
int Destroy();
int RequestTransmissionMemberList(const std::string &transmission_id);
SignalStatus GetSignalStatus();
int SendData(const char *data, size_t size);
private:
std::string uri_ = "";
std::string cfg_signal_server_ip_;
std::string cfg_signal_server_port_;
std::string cfg_stun_server_ip_;
std::string cfg_stun_server_port_;
int signal_server_port_ = 0;
int stun_server_port_ = 0;
WsTransmission *ws_transport_ = nullptr;
IceTransmission *ice_transmission_ = nullptr;
std::vector<std::string> transmission_member_list_;
std::map<std::string, IceTransmission *> ice_transmission_list_;
std::function<void(const std::string &)> on_receive_ws_msg_ = nullptr;
std::function<void(const char *, size_t)> on_receive_ice_msg_ = nullptr;
unsigned int ws_connection_id_ = 0;
std::string user_id_ = "";
std::string transmission_id_ = "";
SignalStatus signal_status_ = SignalStatus::Closed;
};
#endif

View File

@@ -1,45 +1,49 @@
#include "x_inner.h"
#include <iostream>
#include <nlohmann/json.hpp>
#include "ice_agent.h"
#include "log.h"
#include "ws_transmission.h"
#include "x.h"
using nlohmann::json;
static PeerConnection *peer_connection;
PeerPtr *CreatePeer(const Params *params) {
PeerPtr *peer_ptr = new PeerPtr;
peer_ptr->peer_connection = new PeerConnection();
peer_ptr->pc_params.cfg_path = params->cfg_path;
peer_ptr->pc_params.on_receive_buffer = params->on_receive_buffer;
peer_ptr->pc_params.net_status_report = params->net_status_report;
return peer_ptr;
}
int CreateConnection(PeerPtr *peer_ptr) {
peer_ptr->peer_connection->Create(peer_ptr->pc_params);
return 0;
}
int CreateConnection(PeerPtr *peer_ptr, const char *connection_id) {
peer_ptr->peer_connection->Create(peer_ptr->pc_params, connection_id);
return 0;
}
int JoinConnection(PeerPtr *peer_ptr, const char *connection_id) {
peer_ptr->peer_connection->Join(peer_ptr->pc_params, connection_id);
return 0;
}
int SendData(PeerPtr *peer_ptr, const char *data, size_t size) {
peer_ptr->peer_connection->SendData(data, size);
return 0;
}
#include "x_inner.h"
#include <iostream>
#include <nlohmann/json.hpp>
#include "ice_agent.h"
#include "log.h"
#include "ws_transmission.h"
#include "x.h"
using nlohmann::json;
static PeerConnection *peer_connection;
PeerPtr *CreatePeer(const Params *params) {
PeerPtr *peer_ptr = new PeerPtr;
peer_ptr->peer_connection = new PeerConnection();
peer_ptr->pc_params.cfg_path = params->cfg_path;
peer_ptr->pc_params.on_receive_buffer = params->on_receive_buffer;
peer_ptr->pc_params.net_status_report = params->net_status_report;
return peer_ptr;
}
int CreateConnection(PeerPtr *peer_ptr) {
peer_ptr->peer_connection->Create(peer_ptr->pc_params);
return 0;
}
int CreateConnection(PeerPtr *peer_ptr, const char *transmission_id,
const char *user_id) {
peer_ptr->peer_connection->Create(peer_ptr->pc_params, transmission_id,
user_id);
return 0;
}
int JoinConnection(PeerPtr *peer_ptr, const char *transmission_id,
const char *user_id) {
peer_ptr->peer_connection->Join(peer_ptr->pc_params, transmission_id,
user_id);
return 0;
}
int SendData(PeerPtr *peer_ptr, const char *data, size_t size) {
peer_ptr->peer_connection->SendData(data, size);
return 0;
}
int rtc() { return 0; }

View File

@@ -1,11 +1,11 @@
#ifndef _X_INNER_H_
#define _X_INNER_H_
#include "peer_connection.h"
struct Peer {
PeerConnection *peer_connection;
PeerConnectionParams pc_params;
};
#ifndef _X_INNER_H_
#define _X_INNER_H_
#include "peer_connection.h"
struct Peer {
PeerConnection *peer_connection;
PeerConnectionParams pc_params;
};
#endif

View File

@@ -1,136 +1,136 @@
#include "ws_core.h"
#include <cstdlib>
#include <iostream>
#include <sstream>
#include "log.h"
WsCore::WsCore() {
m_endpoint_.clear_access_channels(websocketpp::log::alevel::all);
m_endpoint_.clear_error_channels(websocketpp::log::elevel::all);
m_endpoint_.init_asio();
m_endpoint_.start_perpetual();
m_thread_ = websocketpp::lib::make_shared<websocketpp::lib::thread>(
&client::run, &m_endpoint_);
}
WsCore::~WsCore() {
m_endpoint_.stop_perpetual();
if (GetStatus() != "Open") {
// Only close open connections
return;
}
websocketpp::lib::error_code ec;
m_endpoint_.close(connection_handle_, websocketpp::close::status::going_away,
"", ec);
if (ec) {
LOG_INFO("> Error closing connection {}", ec.message());
}
m_thread_->join();
}
int WsCore::Connect(std::string const &uri) {
websocketpp::lib::error_code ec;
client::connection_ptr con = m_endpoint_.get_connection(uri, ec);
connection_handle_ = con->get_handle();
if (ec) {
LOG_INFO("> Connect initialization error: {}", ec.message());
return -1;
}
con->set_open_handler(websocketpp::lib::bind(
&WsCore::OnOpen, this, &m_endpoint_, websocketpp::lib::placeholders::_1));
con->set_fail_handler(websocketpp::lib::bind(
&WsCore::OnFail, this, &m_endpoint_, websocketpp::lib::placeholders::_1));
con->set_close_handler(
websocketpp::lib::bind(&WsCore::OnClose, this, &m_endpoint_,
websocketpp::lib::placeholders::_1));
// con->set_ping_handler(websocketpp::lib::bind(
// &WsCore::on_ping,
// this,
// websocketpp::lib::placeholders::_1,
// websocketpp::lib::placeholders::_2
// ));
con->set_pong_handler(websocketpp::lib::bind(
&WsCore::OnPong, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2));
con->set_pong_timeout(1000);
con->set_pong_timeout_handler(websocketpp::lib::bind(
&WsCore::OnPongTimeout, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2));
con->set_message_handler(websocketpp::lib::bind(
&WsCore::OnMessage, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2));
m_endpoint_.connect(con);
return 0;
}
void WsCore::Close(websocketpp::close::status::value code, std::string reason) {
websocketpp::lib::error_code ec;
m_endpoint_.close(connection_handle_, code, reason, ec);
if (ec) {
LOG_INFO("> Error initiating close: {}", ec.message());
}
}
void WsCore::Send(std::string message) {
websocketpp::lib::error_code ec;
m_endpoint_.send(connection_handle_, message,
websocketpp::frame::opcode::text, ec);
if (ec) {
LOG_INFO("> Error sending message: {}", ec.message());
return;
}
}
void WsCore::Ping() {
websocketpp::lib::error_code ec;
std::string message = "ping";
m_endpoint_.ping(connection_handle_, message, ec);
if (ec) {
LOG_INFO("> Error sending ping");
return;
}
}
const std::string &WsCore::GetStatus() { return connection_status_; }
void WsCore::OnOpen(client *c, websocketpp::connection_hdl hdl) {
connection_status_ = "Open";
}
void WsCore::OnFail(client *c, websocketpp::connection_hdl hdl) {
connection_status_ = "Failed";
}
void WsCore::OnClose(client *c, websocketpp::connection_hdl hdl) {
connection_status_ = "Closed";
}
void WsCore::OnPong(websocketpp::connection_hdl, std::string msg) {}
void WsCore::OnPongTimeout(websocketpp::connection_hdl, std::string msg) {}
void WsCore::OnMessage(websocketpp::connection_hdl, client::message_ptr msg) {
OnReceiveMessage(msg->get_payload());
#include "ws_core.h"
#include <cstdlib>
#include <iostream>
#include <sstream>
#include "log.h"
WsCore::WsCore() {
m_endpoint_.clear_access_channels(websocketpp::log::alevel::all);
m_endpoint_.clear_error_channels(websocketpp::log::elevel::all);
m_endpoint_.init_asio();
m_endpoint_.start_perpetual();
m_thread_ = websocketpp::lib::make_shared<websocketpp::lib::thread>(
&client::run, &m_endpoint_);
}
WsCore::~WsCore() {
m_endpoint_.stop_perpetual();
if (GetStatus() != "Open") {
// Only close open connections
return;
}
websocketpp::lib::error_code ec;
m_endpoint_.close(connection_handle_, websocketpp::close::status::going_away,
"", ec);
if (ec) {
LOG_INFO("> Error closing connection {}", ec.message());
}
m_thread_->join();
}
int WsCore::Connect(std::string const &uri) {
websocketpp::lib::error_code ec;
client::connection_ptr con = m_endpoint_.get_connection(uri, ec);
connection_handle_ = con->get_handle();
if (ec) {
LOG_INFO("> Connect initialization error: {}", ec.message());
return -1;
}
con->set_open_handler(websocketpp::lib::bind(
&WsCore::OnOpen, this, &m_endpoint_, websocketpp::lib::placeholders::_1));
con->set_fail_handler(websocketpp::lib::bind(
&WsCore::OnFail, this, &m_endpoint_, websocketpp::lib::placeholders::_1));
con->set_close_handler(
websocketpp::lib::bind(&WsCore::OnClose, this, &m_endpoint_,
websocketpp::lib::placeholders::_1));
// con->set_ping_handler(websocketpp::lib::bind(
// &WsCore::on_ping,
// this,
// websocketpp::lib::placeholders::_1,
// websocketpp::lib::placeholders::_2
// ));
con->set_pong_handler(websocketpp::lib::bind(
&WsCore::OnPong, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2));
con->set_pong_timeout(1000);
con->set_pong_timeout_handler(websocketpp::lib::bind(
&WsCore::OnPongTimeout, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2));
con->set_message_handler(websocketpp::lib::bind(
&WsCore::OnMessage, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2));
m_endpoint_.connect(con);
return 0;
}
void WsCore::Close(websocketpp::close::status::value code, std::string reason) {
websocketpp::lib::error_code ec;
m_endpoint_.close(connection_handle_, code, reason, ec);
if (ec) {
LOG_INFO("> Error initiating close: {}", ec.message());
}
}
void WsCore::Send(std::string message) {
websocketpp::lib::error_code ec;
m_endpoint_.send(connection_handle_, message,
websocketpp::frame::opcode::text, ec);
if (ec) {
LOG_INFO("> Error sending message: {}", ec.message());
return;
}
}
void WsCore::Ping() {
websocketpp::lib::error_code ec;
std::string message = "ping";
m_endpoint_.ping(connection_handle_, message, ec);
if (ec) {
LOG_INFO("> Error sending ping");
return;
}
}
const std::string &WsCore::GetStatus() { return connection_status_; }
void WsCore::OnOpen(client *c, websocketpp::connection_hdl hdl) {
connection_status_ = "Open";
}
void WsCore::OnFail(client *c, websocketpp::connection_hdl hdl) {
connection_status_ = "Failed";
}
void WsCore::OnClose(client *c, websocketpp::connection_hdl hdl) {
connection_status_ = "Closed";
}
void WsCore::OnPong(websocketpp::connection_hdl, std::string msg) {}
void WsCore::OnPongTimeout(websocketpp::connection_hdl, std::string msg) {}
void WsCore::OnMessage(websocketpp::connection_hdl, client::message_ptr msg) {
OnReceiveMessage(msg->get_payload());
}

View File

@@ -1,54 +1,54 @@
#ifndef _WS_CORE_H_
#define _WS_CORE_H_
#include <map>
#include <sstream>
#include <string>
#include "websocketpp/client.hpp"
#include "websocketpp/common/memory.hpp"
#include "websocketpp/common/thread.hpp"
#include "websocketpp/config/asio_no_tls_client.hpp"
typedef websocketpp::client<websocketpp::config::asio_client> client;
class WsCore {
public:
WsCore();
virtual ~WsCore();
int Connect(std::string const &uri);
void Close(websocketpp::close::status::value code, std::string reason);
void Send(std::string message);
void Ping();
const std::string &GetStatus();
// Callback
void OnOpen(client *c, websocketpp::connection_hdl hdl);
void OnFail(client *c, websocketpp::connection_hdl hdl);
void OnClose(client *c, websocketpp::connection_hdl hdl);
void OnPong(websocketpp::connection_hdl, std::string msg);
void OnPongTimeout(websocketpp::connection_hdl, std::string msg);
void OnMessage(websocketpp::connection_hdl, client::message_ptr msg);
virtual void OnReceiveMessage(const std::string &msg) = 0;
private:
client m_endpoint_;
websocketpp::connection_hdl connection_handle_;
websocketpp::lib::shared_ptr<websocketpp::lib::thread> m_thread_;
std::string connection_status_ = "Connecting";
};
#ifndef _WS_CORE_H_
#define _WS_CORE_H_
#include <map>
#include <sstream>
#include <string>
#include "websocketpp/client.hpp"
#include "websocketpp/common/memory.hpp"
#include "websocketpp/common/thread.hpp"
#include "websocketpp/config/asio_no_tls_client.hpp"
typedef websocketpp::client<websocketpp::config::asio_client> client;
class WsCore {
public:
WsCore();
virtual ~WsCore();
int Connect(std::string const &uri);
void Close(websocketpp::close::status::value code, std::string reason);
void Send(std::string message);
void Ping();
const std::string &GetStatus();
// Callback
void OnOpen(client *c, websocketpp::connection_hdl hdl);
void OnFail(client *c, websocketpp::connection_hdl hdl);
void OnClose(client *c, websocketpp::connection_hdl hdl);
void OnPong(websocketpp::connection_hdl, std::string msg);
void OnPongTimeout(websocketpp::connection_hdl, std::string msg);
void OnMessage(websocketpp::connection_hdl, client::message_ptr msg);
virtual void OnReceiveMessage(const std::string &msg) = 0;
private:
client m_endpoint_;
websocketpp::connection_hdl connection_handle_;
websocketpp::lib::shared_ptr<websocketpp::lib::thread> m_thread_;
std::string connection_status_ = "Connecting";
};
#endif

View File

@@ -1,16 +1,16 @@
#include "ws_transmission.h"
#include "log.h"
WsTransmission::WsTransmission(
std::function<void(const std::string &)> on_receive_msg_cb)
: on_receive_msg_(on_receive_msg_cb) {}
WsTransmission::~WsTransmission() {}
void WsTransmission::OnReceiveMessage(const std::string &msg) {
// LOG_INFO("Receive msg: {}", msg);
if (on_receive_msg_) {
on_receive_msg_(msg);
}
#include "ws_transmission.h"
#include "log.h"
WsTransmission::WsTransmission(
std::function<void(const std::string &)> on_receive_msg_cb)
: on_receive_msg_(on_receive_msg_cb) {}
WsTransmission::~WsTransmission() {}
void WsTransmission::OnReceiveMessage(const std::string &msg) {
// LOG_INFO("Receive msg: {}", msg);
if (on_receive_msg_) {
on_receive_msg_(msg);
}
}

View File

@@ -1,18 +1,18 @@
#ifndef _WS_TRANSMISSION_H_
#define _WS_TRANSMISSION_H_
#include "ws_core.h"
class WsTransmission : public WsCore {
public:
WsTransmission(std::function<void(const std::string &)> on_receive_msg_cb);
~WsTransmission();
public:
void OnReceiveMessage(const std::string &msg);
private:
std::function<void(const std::string &)> on_receive_msg_ = nullptr;
};
#ifndef _WS_TRANSMISSION_H_
#define _WS_TRANSMISSION_H_
#include "ws_core.h"
class WsTransmission : public WsCore {
public:
WsTransmission(std::function<void(const std::string &)> on_receive_msg_cb);
~WsTransmission();
public:
void OnReceiveMessage(const std::string &msg);
private:
std::function<void(const std::string &)> on_receive_msg_ = nullptr;
};
#endif

View File

@@ -1,27 +1,28 @@
#include <iostream>
#include "x.h"
int main(int argc, char** argv) {
Params params;
params.cfg_path = "../../../../config/config.ini";
std::string transmission_id = "000000";
// std::cout << "Please input which transmisson want to join: ";
// std::cin >> transmission_id;
PeerPtr* peer = CreatePeer(&params);
JoinConnection(peer, transmission_id.c_str());
std::string msg = "Offer peer";
int i = 100;
while (i--) {
getchar();
std::cout << "Send data: [" << msg << "]" << std::endl;
SendData(peer, msg.data(), msg.size());
}
getchar();
return 0;
}
#include <iostream>
#include "x.h"
int main(int argc, char** argv) {
Params params;
params.cfg_path = "../../../../config/config.ini";
std::string transmission_id = "000000";
std::string user_id = argv[1];
// std::cout << "Please input which transmisson want to join: ";
// std::cin >> transmission_id;
PeerPtr* peer = CreatePeer(&params);
JoinConnection(peer, transmission_id.c_str(), user_id.c_str());
std::string msg = "Offer peer";
int i = 100;
while (i--) {
getchar();
std::cout << "Send data: [" << msg << "]" << std::endl;
SendData(peer, msg.data(), msg.size());
}
getchar();
return 0;
}

View File

@@ -1,23 +1,23 @@
#include <iostream>
#include "x.h"
int main(int argc, char** argv) {
Params params;
params.cfg_path = "../../../../config/config.ini";
PeerPtr* peer = CreatePeer(&params);
CreateConnection(peer);
std::string msg = "Answer peer";
int i = 100;
while (i--) {
getchar();
std::cout << "Send data: [" << msg << "]" << std::endl;
SendData(peer, msg.data(), msg.size());
}
getchar();
return 0;
}
#include <iostream>
#include "x.h"
int main(int argc, char** argv) {
Params params;
params.cfg_path = "../../../../config/config.ini";
PeerPtr* peer = CreatePeer(&params);
CreateConnection(peer);
std::string msg = "Answer peer";
int i = 100;
while (i--) {
getchar();
std::cout << "Send data: [" << msg << "]" << std::endl;
SendData(peer, msg.data(), msg.size());
}
getchar();
return 0;
}

View File

@@ -1,17 +1,17 @@
#include <iostream>
#include "signal_server.h"
int main(int argc, char* argv[]) {
SignalServer s;
std::string port = "";
if (argc > 1) {
port = argv[1];
} else {
port = "9090";
}
std::cout << "Port: " << port << std::endl;
s.run(std::stoi(port));
return 0;
#include <iostream>
#include "signal_server.h"
int main(int argc, char* argv[]) {
SignalServer s;
std::string port = "";
if (argc > 1) {
port = argv[1];
} else {
port = "9090";
}
std::cout << "Port: " << port << std::endl;
s.run(std::stoi(port));
return 0;
}

View File

@@ -72,6 +72,7 @@ bool SignalServer::on_pong(websocketpp::connection_hdl hdl, std::string s) {
}
void SignalServer::run(uint16_t port) {
server_.set_reuse_addr(true);
server_.listen(port);
// Queues a connection accept operation
@@ -95,6 +96,7 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl,
switch (HASH_STRING_PIECE(type.c_str())) {
case "create_transmission"_H: {
std::string transmission_id = j["transmission_id"].get<std::string>();
std::string user_id = j["user_id"].get<std::string>();
LOG_INFO("Receive create transmission request with id [{}]",
transmission_id);
if (transmission_list_.find(transmission_id) ==
@@ -111,7 +113,16 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl,
transmission_id);
}
transmission_list_.insert(transmission_id);
transmission_manager_.BindHostToTransmission(hdl, transmission_id);
transmission_manager_.BindWsHandleToTransmission(hdl, transmission_id);
transmission_manager_.BindUserIdToTransmission(user_id,
transmission_id);
transmission_manager_.BindUserIdToWsHandle(user_id, hdl);
transmission_manager_.BindUserNameToUserId("host", user_id);
// if (transmission_manager_.GetUsername(hdl).empty()) {
// transmission_manager_.BindUsernameToWsHandle("host", hdl);
// }
LOG_INFO("Create transmission id [{}]", transmission_id);
json message = {{"type", "transmission_id"},
@@ -129,37 +140,6 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl,
break;
}
case "offer"_H: {
std::string transmission_id = j["transmission_id"].get<std::string>();
std::string sdp = j["sdp"].get<std::string>();
// LOG_INFO("Receive transmission id [{}] with offer sdp [{}]",
// transmission_id, sdp);
transmission_manager_.BindGuestToTransmission(hdl, transmission_id);
std::string guest_username = GetIceUsername(sdp);
transmission_manager_.BindGuestUsernameToWsHandle(guest_username, hdl);
websocketpp::connection_hdl host_hdl =
transmission_manager_.GetHostOfTransmission(transmission_id);
std::vector<websocketpp::connection_hdl> guest_hdl_list =
transmission_manager_.GetAllGuestsOfTransmission(transmission_id);
// LOG_INFO("send offer sdp [{}]", sdp);
json message = {
{"type", "offer"}, {"sdp", sdp}, {"guest", guest_username}};
LOG_INFO("[{}] send offer sdp to host", guest_username);
send_msg(host_hdl, message);
LOG_INFO("Size of guest_hdl_list: {}", guest_hdl_list.size());
for (auto guest_hdl : guest_hdl_list) {
if (guest_hdl.lock().get() != hdl.lock().get()) {
LOG_INFO("[{}] send offer sdp to [{}]", guest_username,
transmission_manager_.GetGuestUsername(guest_hdl));
send_msg(guest_hdl, message);
}
}
break;
}
case "query_members"_H: {
std::string transmission_id = j["transmission_id"].get<std::string>();
std::vector<std::string> member_list =
@@ -169,23 +149,44 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl,
{"transmission_id", transmission_id},
{"transmission_members", member_list},
{"status", "success"}};
LOG_INFO("Send member_list: [{}]", message.dump());
send_msg(hdl, message);
break;
}
case "offer"_H: {
std::string transmission_id = j["transmission_id"].get<std::string>();
std::string sdp = j["sdp"].get<std::string>();
std::string remote_peer = j["remote_peer"].get<std::string>();
// LOG_INFO("Receive transmission id [{}] with offer sdp [{}]",
// transmission_id, sdp);
transmission_manager_.BindWsHandleToTransmission(hdl, transmission_id);
std::string offer_peer = GetIceUsername(sdp);
transmission_manager_.BindUsernameToWsHandle(offer_peer, hdl);
websocketpp::connection_hdl destination_hdl =
transmission_manager_.GetWsHandle(remote_peer);
json message = {{"type", "offer"}, {"sdp", sdp}};
LOG_INFO("[{}] send offer sdp to [{}]", offer_peer, remote_peer);
send_msg(destination_hdl, message);
break;
}
case "answer"_H: {
std::string transmission_id = j["transmission_id"].get<std::string>();
std::string sdp = j["sdp"].get<std::string>();
std::string guest_ice_username = j["guest"].get<std::string>();
std::string host_ice_username = GetIceUsername(sdp);
if (transmission_manager_.GetHostUsername(hdl).empty()) {
transmission_manager_.BindHostUsernameToWsHandle(host_ice_username,
hdl);
if (transmission_manager_.GetUsername(hdl) == "host") {
LOG_INFO("Update transmission [{}] [host] to [{}]", transmission_id,
host_ice_username);
transmission_manager_.UpdateUsernameToWsHandle(host_ice_username, hdl);
}
// LOG_INFO("Receive transmission id [{}] with answer sdp [{}]",
// transmission_id, sdp);
websocketpp::connection_hdl guest_hdl =
transmission_manager_.GetGuestWsHandle(guest_ice_username);
transmission_manager_.GetWsHandle(guest_ice_username);
// LOG_INFO("send answer sdp [{}]", sdp);
LOG_INFO("[{}] send answer sdp to [{}]", host_ice_username,

View File

@@ -1,51 +1,51 @@
#ifndef _SIGNAL_SERVER_H_
#define _SIGNAL_SERVER_H_
#include <functional>
#include <map>
#include <nlohmann/json.hpp>
#include <set>
#include <string>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include "transmission_manager.h"
using nlohmann::json;
typedef websocketpp::server<websocketpp::config::asio> server;
typedef unsigned int connection_id;
typedef std::string room_id;
class SignalServer {
public:
SignalServer();
~SignalServer();
bool on_open(websocketpp::connection_hdl hdl);
bool on_close(websocketpp::connection_hdl hdl);
bool on_ping(websocketpp::connection_hdl hdl, std::string s);
bool on_pong(websocketpp::connection_hdl hdl, std::string s);
void run(uint16_t port);
void on_message(websocketpp::connection_hdl hdl, server::message_ptr msg);
void send_msg(websocketpp::connection_hdl hdl, json message);
private:
server server_;
std::map<websocketpp::connection_hdl, connection_id,
std::owner_less<websocketpp::connection_hdl>>
ws_connections_;
std::map<room_id, connection_id> rooms_;
unsigned int ws_connection_id_ = 0;
std::set<std::string> transmission_list_;
TransmissionManager transmission_manager_;
};
#ifndef _SIGNAL_SERVER_H_
#define _SIGNAL_SERVER_H_
#include <functional>
#include <map>
#include <nlohmann/json.hpp>
#include <set>
#include <string>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include "transmission_manager.h"
using nlohmann::json;
typedef websocketpp::server<websocketpp::config::asio> server;
typedef unsigned int connection_id;
typedef std::string room_id;
class SignalServer {
public:
SignalServer();
~SignalServer();
bool on_open(websocketpp::connection_hdl hdl);
bool on_close(websocketpp::connection_hdl hdl);
bool on_ping(websocketpp::connection_hdl hdl, std::string s);
bool on_pong(websocketpp::connection_hdl hdl, std::string s);
void run(uint16_t port);
void on_message(websocketpp::connection_hdl hdl, server::message_ptr msg);
void send_msg(websocketpp::connection_hdl hdl, json message);
private:
server server_;
std::map<websocketpp::connection_hdl, connection_id,
std::owner_less<websocketpp::connection_hdl>>
ws_connections_;
std::map<room_id, connection_id> rooms_;
unsigned int ws_connection_id_ = 0;
std::set<std::string> transmission_list_;
TransmissionManager transmission_manager_;
};
#endif

View File

@@ -6,101 +6,114 @@ TransmissionManager::TransmissionManager() {}
TransmissionManager::~TransmissionManager() {}
bool TransmissionManager::BindHostToTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) {
if (transmission_host_list_.find(transmission_id) !=
transmission_host_list_.end()) {
LOG_WARN("Transmission already has a host [{}]",
transmission_host_list_[transmission_id].lock().get());
return false;
} else {
transmission_host_list_[transmission_id] = hdl;
}
return true;
}
// bool TransmissionManager::BindHostToTransmission(
// websocketpp::connection_hdl hdl, const std::string& transmission_id) {
// if (transmission_host_list_.find(transmission_id) !=
// transmission_host_list_.end()) {
// LOG_WARN("Transmission already has a host [{}]",
// transmission_host_list_[transmission_id].lock().get());
// return false;
// } else {
// transmission_host_list_[transmission_id] = hdl;
// }
// return true;
// }
bool TransmissionManager::BindGuestToTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) {
if (transmission_guest_list_.find(transmission_id) !=
transmission_guest_list_.end()) {
transmission_guest_list_[transmission_id].push_back(hdl);
} else {
std::vector<websocketpp::connection_hdl> guest_hdl_list;
guest_hdl_list.push_back(hdl);
transmission_guest_list_[transmission_id] = guest_hdl_list;
}
return true;
}
// bool TransmissionManager::BindGuestToTransmission(
// websocketpp::connection_hdl hdl, const std::string& transmission_id) {
// if (transmission_guest_list_.find(transmission_id) !=
// transmission_guest_list_.end()) {
// transmission_guest_list_[transmission_id].push_back(hdl);
// } else {
// std::vector<websocketpp::connection_hdl> guest_hdl_list;
// guest_hdl_list.push_back(hdl);
// transmission_guest_list_[transmission_id] = guest_hdl_list;
// }
// return true;
// }
bool TransmissionManager::ReleaseHostFromTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) {
return true;
}
// bool TransmissionManager::ReleaseHostFromTransmission(
// websocketpp::connection_hdl hdl, const std::string& transmission_id) {
// return true;
// }
bool TransmissionManager::ReleaseGuestFromTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) {
return true;
}
// bool TransmissionManager::ReleaseGuestFromTransmission(
// websocketpp::connection_hdl hdl, const std::string& transmission_id) {
// return true;
// }
bool TransmissionManager::BindHostUsernameToWsHandle(
const std::string& host_username, websocketpp::connection_hdl hdl) {
if (transmission_host_username_list_.find(host_username) !=
transmission_host_username_list_.end()) {
LOG_ERROR("Guest already bind to username [{}]", host_username.c_str());
return false;
} else {
transmission_host_username_list_[host_username] = hdl;
}
return true;
}
// bool TransmissionManager::BindHostUsernameToWsHandle(
// websocketpp::connection_hdl hdl) {
// if (transmission_host_username_list_.find("host") !=
// transmission_host_username_list_.end()) {
// LOG_ERROR("Host already exist");
// return false;
// } else {
// transmission_host_username_list_["host"] = hdl;
// }
// return true;
// }
bool TransmissionManager::BindGuestUsernameToWsHandle(
const std::string& guest_username, websocketpp::connection_hdl hdl) {
if (transmission_guest_username_list_.find(guest_username) !=
transmission_guest_username_list_.end()) {
LOG_ERROR("Guest already bind to username [{}]", guest_username.c_str());
return false;
} else {
transmission_guest_username_list_[guest_username] = hdl;
}
return true;
}
// bool TransmissionManager::UpdateHostUsernameToWsHandle(
// const std::string& host_username, websocketpp::connection_hdl hdl) {
// if (transmission_host_username_list_.find("host") ==
// transmission_host_username_list_.end()) {
// LOG_ERROR("Host not exist");
// return false;
// }
// transmission_host_username_list_.erase("host");
// transmission_host_username_list_[host_username] = hdl;
websocketpp::connection_hdl TransmissionManager::GetHostOfTransmission(
const std::string& transmission_id) {
if (transmission_host_list_.find(transmission_id) !=
transmission_host_list_.end()) {
return transmission_host_list_[transmission_id];
} else {
websocketpp::connection_hdl hdl;
return hdl;
}
}
// return true;
// }
std::string TransmissionManager::GetHostUsername(
websocketpp::connection_hdl hdl) {
for (auto host : transmission_host_username_list_) {
if (host.second.lock().get() == hdl.lock().get()) return host.first;
}
// bool TransmissionManager::BindGuestUsernameToWsHandle(
// const std::string& guest_username, websocketpp::connection_hdl hdl) {
// if (transmission_guest_username_list_.find(guest_username) !=
// transmission_guest_username_list_.end()) {
// LOG_ERROR("Guest already bind to username [{}]", guest_username.c_str());
// return false;
// } else {
// transmission_guest_username_list_[guest_username] = hdl;
// }
// return true;
// }
return "";
}
// websocketpp::connection_hdl TransmissionManager::GetHostOfTransmission(
// const std::string& transmission_id) {
// if (transmission_host_list_.find(transmission_id) !=
// transmission_host_list_.end()) {
// return transmission_host_list_[transmission_id];
// } else {
// websocketpp::connection_hdl hdl;
// return hdl;
// }
// }
std::string TransmissionManager::GetGuestUsername(
websocketpp::connection_hdl hdl) {
for (auto guest : transmission_guest_username_list_) {
if (guest.second.lock().get() == hdl.lock().get()) return guest.first;
}
// std::string TransmissionManager::GetHostUsername(
// websocketpp::connection_hdl hdl) {
// for (auto host : transmission_host_username_list_) {
// if (host.second.lock().get() == hdl.lock().get()) return host.first;
// }
return "";
}
// return "";
// }
// std::string TransmissionManager::GetGuestUsername(
// websocketpp::connection_hdl hdl) {
// for (auto guest : transmission_guest_username_list_) {
// if (guest.second.lock().get() == hdl.lock().get()) return guest.first;
// }
// return "";
// }
std::vector<websocketpp::connection_hdl>
TransmissionManager::GetAllGuestsOfTransmission(
const std::string& transmission_id) {
if (transmission_guest_list_.find(transmission_id) !=
transmission_guest_list_.end()) {
return transmission_guest_list_[transmission_id];
if (transmission_user_ws_hdl_list_.find(transmission_id) !=
transmission_user_ws_hdl_list_.end()) {
return transmission_user_ws_hdl_list_[transmission_id];
} else {
return std::vector<websocketpp::connection_hdl>();
}
@@ -121,12 +134,127 @@ std::vector<std::string> TransmissionManager::GetAllMembersOfTransmission(
const std::string& transmission_id) {
std::vector<std::string> member_list;
member_list.push_back(
GetHostUsername(GetHostOfTransmission(transmission_id)));
for (auto guest_hdl : GetAllGuestsOfTransmission(transmission_id)) {
member_list.push_back(GetGuestUsername(guest_hdl));
member_list.push_back(GetUsername(guest_hdl));
}
return member_list;
}
bool TransmissionManager::BindWsHandleToTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) {
if (transmission_user_ws_hdl_list_.find(transmission_id) ==
transmission_user_ws_hdl_list_.end()) {
transmission_user_ws_hdl_list_[transmission_id].push_back(hdl);
return true;
} else {
auto hdl_list = transmission_user_ws_hdl_list_[transmission_id];
for (auto h : hdl_list) {
if (h.lock().get() == hdl.lock().get()) {
LOG_ERROR("Ws handle [{}] already bind to transmission [{}]",
hdl.lock().get(), transmission_id);
return false;
}
}
transmission_user_ws_hdl_list_[transmission_id].push_back(hdl);
}
return true;
}
bool TransmissionManager::BindUserIdToTransmission(
const std::string& user_id, const std::string& transmission_id) {
if (transmission_user_id_list_.find(transmission_id) ==
transmission_user_id_list_.end()) {
transmission_user_id_list_[transmission_id].push_back(user_id);
return true;
} else {
auto user_id_list = transmission_user_id_list_[transmission_id];
for (auto id : user_id_list) {
if (id == user_id) {
LOG_ERROR("User id [{}] already bind to transmission [{}]", user_id,
transmission_id);
return false;
}
}
transmission_user_id_list_[transmission_id].push_back(user_id);
}
return true;
}
bool TransmissionManager::BindUserIdToWsHandle(
const std::string& user_id, websocketpp::connection_hdl hdl) {
if (user_id_ws_hdl_list_.find(user_id) != user_id_ws_hdl_list_.end()) {
LOG_ERROR("User id already bind to websocket handle [{}]", user_id,
hdl.lock().get());
return false;
} else {
user_id_ws_hdl_list_[user_id] = hdl;
}
return true;
}
bool TransmissionManager::BindUserNameToUserId(const std::string& user_name,
const std::string& user_id) {
if (user_name_user_id_list_.find(user_id) == user_name_user_id_list_.end()) {
user_name_user_id_list_[user_id].push_back(user_name);
return true;
} else {
auto user_name_list = user_name_user_id_list_[user_id];
for (auto name : user_name_list) {
if (name == user_name) {
LOG_ERROR("User name [{}] already bind to user id [{}]", user_name,
user_id);
return false;
}
}
user_name_user_id_list_[user_id].push_back(user_name);
}
return true;
}
bool TransmissionManager::ReleaseWsHandleFromTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) {
return true;
}
bool TransmissionManager::BindUsernameToWsHandle(
const std::string& username, websocketpp::connection_hdl hdl) {
if (username_ws_hdl_list_.find(username) != username_ws_hdl_list_.end()) {
LOG_ERROR("Guest already bind to username [{}]", username.c_str());
return false;
} else {
username_ws_hdl_list_[username] = hdl;
}
return true;
}
bool TransmissionManager::UpdateUsernameToWsHandle(
const std::string& username, websocketpp::connection_hdl hdl) {
if (username_ws_hdl_list_.find("host") == username_ws_hdl_list_.end()) {
LOG_ERROR("Host not exist");
return false;
}
username_ws_hdl_list_.erase("host");
username_ws_hdl_list_[username] = hdl;
return true;
}
std::string TransmissionManager::GetUsername(websocketpp::connection_hdl hdl) {
for (auto guest : username_ws_hdl_list_) {
if (guest.second.lock().get() == hdl.lock().get()) return guest.first;
}
LOG_ERROR("No user with websocket handle [{}]", hdl.lock().get());
return "";
}
websocketpp::connection_hdl TransmissionManager::GetWsHandle(
const std::string& username) {
if (username_ws_hdl_list_.find(username) != username_ws_hdl_list_.end()) {
return username_ws_hdl_list_[username];
} else {
websocketpp::connection_hdl hdl;
return hdl;
}
}

View File

@@ -11,22 +11,23 @@ class TransmissionManager {
~TransmissionManager();
public:
bool BindHostToTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id);
bool BindGuestToTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id);
bool ReleaseHostFromTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id);
bool ReleaseGuestFromTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id);
// bool BindHostToTransmission(websocketpp::connection_hdl hdl,
// const std::string& transmission_id);
// bool BindGuestToTransmission(websocketpp::connection_hdl hdl,
// const std::string& transmission_id);
// bool ReleaseHostFromTransmission(websocketpp::connection_hdl hdl,
// const std::string& transmission_id);
// bool ReleaseGuestFromTransmission(websocketpp::connection_hdl hdl,
// const std::string& transmission_id);
bool BindHostUsernameToWsHandle(const std::string& host_username,
websocketpp::connection_hdl hdl);
bool BindGuestUsernameToWsHandle(const std::string& guest_username,
websocketpp::connection_hdl hdl);
// bool BindHostUsernameToWsHandle(websocketpp::connection_hdl hdl);
// bool UpdateHostUsernameToWsHandle(const std::string& host_username,
// websocketpp::connection_hdl hdl);
// bool BindGuestUsernameToWsHandle(const std::string& guest_username,
// websocketpp::connection_hdl hdl);
std::string GetHostUsername(websocketpp::connection_hdl hdl);
std::string GetGuestUsername(websocketpp::connection_hdl hdl);
// std::string GetHostUsername(websocketpp::connection_hdl hdl);
// std::string GetGuestUsername(websocketpp::connection_hdl hdl);
websocketpp::connection_hdl GetHostOfTransmission(
const std::string& transmission_id);
@@ -38,6 +39,25 @@ class TransmissionManager {
std::vector<std::string> GetAllMembersOfTransmission(
const std::string& transmission_id);
public:
bool BindWsHandleToTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id);
bool BindUserIdToTransmission(const std::string& user_id,
const std::string& transmission_id);
bool BindUserIdToWsHandle(const std::string& user_id,
websocketpp::connection_hdl hdl);
bool BindUserNameToUserId(const std::string& user_name,
const std::string& user_id);
bool ReleaseWsHandleFromTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id);
bool BindUsernameToWsHandle(const std::string& username,
websocketpp::connection_hdl hdl);
bool UpdateUsernameToWsHandle(const std::string& username,
websocketpp::connection_hdl hdl);
std::string GetUsername(websocketpp::connection_hdl hdl);
websocketpp::connection_hdl GetWsHandle(const std::string& username);
private:
std::map<std::string, websocketpp::connection_hdl> transmission_host_list_;
std::map<std::string, std::vector<websocketpp::connection_hdl>>
@@ -47,6 +67,15 @@ class TransmissionManager {
transmission_host_username_list_;
std::map<std::string, websocketpp::connection_hdl>
transmission_guest_username_list_;
private:
std::map<std::string, std::vector<websocketpp::connection_hdl>>
transmission_user_ws_hdl_list_;
std::map<std::string, std::vector<std::string>> transmission_user_id_list_;
std::map<std::string, websocketpp::connection_hdl> user_id_ws_hdl_list_;
std::map<std::string, std::vector<std::string>> user_name_user_id_list_;
std::map<std::string, websocketpp::connection_hdl> username_ws_hdl_list_;
};
#endif

View File

@@ -1,28 +1,28 @@
# - Config file for the websocketpp package
# It defines the following variables
# WEBSOCKETPP_FOUND - indicates that the module was found
# WEBSOCKETPP_INCLUDE_DIR - include directories
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was websocketpp-config.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
####################################################################################
set_and_check(WEBSOCKETPP_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")
set(WEBSOCKETPP_FOUND TRUE)
#This is a bit of a hack, but it works well. It also allows continued support of CMake 2.8
if(${CMAKE_VERSION} VERSION_GREATER 3.0.0 OR ${CMAKE_VERSION} VERSION_EQUAL 3.0.0)
add_library(websocketpp::websocketpp INTERFACE IMPORTED)
set_target_properties(websocketpp::websocketpp PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WEBSOCKETPP_INCLUDE_DIR}")
endif()
# - Config file for the websocketpp package
# It defines the following variables
# WEBSOCKETPP_FOUND - indicates that the module was found
# WEBSOCKETPP_INCLUDE_DIR - include directories
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was websocketpp-config.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
####################################################################################
set_and_check(WEBSOCKETPP_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")
set(WEBSOCKETPP_FOUND TRUE)
#This is a bit of a hack, but it works well. It also allows continued support of CMake 2.8
if(${CMAKE_VERSION} VERSION_GREATER 3.0.0 OR ${CMAKE_VERSION} VERSION_EQUAL 3.0.0)
add_library(websocketpp::websocketpp INTERFACE IMPORTED)
set_target_properties(websocketpp::websocketpp PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WEBSOCKETPP_INCLUDE_DIR}")
endif()

View File

@@ -1,88 +1,88 @@
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is equal to the requested version.
# The tweak version component is ignored.
# The variable CVF_VERSION must be set before calling configure_file().
if (PACKAGE_FIND_VERSION_RANGE)
message(AUTHOR_WARNING
"`find_package()` specify a version range but the version strategy "
"(ExactVersion) of the module `${PACKAGE_FIND_NAME}` is incompatible "
"with this request. Only the lower endpoint of the range will be used.")
endif()
set(PACKAGE_VERSION "0.8.2")
if("0.8.2" MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") # strip the tweak version
set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
set(CVF_VERSION_MINOR "${CMAKE_MATCH_2}")
set(CVF_VERSION_PATCH "${CMAKE_MATCH_3}")
if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}")
endif()
if(NOT CVF_VERSION_MINOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_MINOR "${CVF_VERSION_MINOR}")
endif()
if(NOT CVF_VERSION_PATCH VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_PATCH "${CVF_VERSION_PATCH}")
endif()
set(CVF_VERSION_NO_TWEAK "${CVF_VERSION_MAJOR}.${CVF_VERSION_MINOR}.${CVF_VERSION_PATCH}")
else()
set(CVF_VERSION_NO_TWEAK "0.8.2")
endif()
if(PACKAGE_FIND_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") # strip the tweak version
set(REQUESTED_VERSION_MAJOR "${CMAKE_MATCH_1}")
set(REQUESTED_VERSION_MINOR "${CMAKE_MATCH_2}")
set(REQUESTED_VERSION_PATCH "${CMAKE_MATCH_3}")
if(NOT REQUESTED_VERSION_MAJOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_MAJOR "${REQUESTED_VERSION_MAJOR}")
endif()
if(NOT REQUESTED_VERSION_MINOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_MINOR "${REQUESTED_VERSION_MINOR}")
endif()
if(NOT REQUESTED_VERSION_PATCH VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_PATCH "${REQUESTED_VERSION_PATCH}")
endif()
set(REQUESTED_VERSION_NO_TWEAK
"${REQUESTED_VERSION_MAJOR}.${REQUESTED_VERSION_MINOR}.${REQUESTED_VERSION_PATCH}")
else()
set(REQUESTED_VERSION_NO_TWEAK "${PACKAGE_FIND_VERSION}")
endif()
if(REQUESTED_VERSION_NO_TWEAK STREQUAL CVF_VERSION_NO_TWEAK)
set(PACKAGE_VERSION_COMPATIBLE TRUE)
else()
set(PACKAGE_VERSION_COMPATIBLE FALSE)
endif()
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
# if the installed project requested no architecture check, don't perform the check
if("FALSE")
return()
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "")
return()
endif()
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8")
math(EXPR installedBits "8 * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is equal to the requested version.
# The tweak version component is ignored.
# The variable CVF_VERSION must be set before calling configure_file().
if (PACKAGE_FIND_VERSION_RANGE)
message(AUTHOR_WARNING
"`find_package()` specify a version range but the version strategy "
"(ExactVersion) of the module `${PACKAGE_FIND_NAME}` is incompatible "
"with this request. Only the lower endpoint of the range will be used.")
endif()
set(PACKAGE_VERSION "0.8.2")
if("0.8.2" MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") # strip the tweak version
set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
set(CVF_VERSION_MINOR "${CMAKE_MATCH_2}")
set(CVF_VERSION_PATCH "${CMAKE_MATCH_3}")
if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}")
endif()
if(NOT CVF_VERSION_MINOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_MINOR "${CVF_VERSION_MINOR}")
endif()
if(NOT CVF_VERSION_PATCH VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_PATCH "${CVF_VERSION_PATCH}")
endif()
set(CVF_VERSION_NO_TWEAK "${CVF_VERSION_MAJOR}.${CVF_VERSION_MINOR}.${CVF_VERSION_PATCH}")
else()
set(CVF_VERSION_NO_TWEAK "0.8.2")
endif()
if(PACKAGE_FIND_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") # strip the tweak version
set(REQUESTED_VERSION_MAJOR "${CMAKE_MATCH_1}")
set(REQUESTED_VERSION_MINOR "${CMAKE_MATCH_2}")
set(REQUESTED_VERSION_PATCH "${CMAKE_MATCH_3}")
if(NOT REQUESTED_VERSION_MAJOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_MAJOR "${REQUESTED_VERSION_MAJOR}")
endif()
if(NOT REQUESTED_VERSION_MINOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_MINOR "${REQUESTED_VERSION_MINOR}")
endif()
if(NOT REQUESTED_VERSION_PATCH VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_PATCH "${REQUESTED_VERSION_PATCH}")
endif()
set(REQUESTED_VERSION_NO_TWEAK
"${REQUESTED_VERSION_MAJOR}.${REQUESTED_VERSION_MINOR}.${REQUESTED_VERSION_PATCH}")
else()
set(REQUESTED_VERSION_NO_TWEAK "${PACKAGE_FIND_VERSION}")
endif()
if(REQUESTED_VERSION_NO_TWEAK STREQUAL CVF_VERSION_NO_TWEAK)
set(PACKAGE_VERSION_COMPATIBLE TRUE)
else()
set(PACKAGE_VERSION_COMPATIBLE FALSE)
endif()
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
# if the installed project requested no architecture check, don't perform the check
if("FALSE")
return()
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "")
return()
endif()
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8")
math(EXPR installedBits "8 * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()

View File

@@ -1,178 +1,178 @@
/*
******
base64.hpp is a repackaging of the base64.cpp and base64.h files into a
single header suitable for use as a header only library. This conversion was
done by Peter Thorson (webmaster@zaphoyd.com) in 2012. All modifications to
the code are redistributed under the same license as the original, which is
listed below.
******
base64.cpp and base64.h
Copyright (C) 2004-2008 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
#ifndef _BASE64_HPP_
#define _BASE64_HPP_
#include <string>
namespace websocketpp {
static std::string const base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
/// Test whether a character is a valid base64 character
/**
* @param c The character to test
* @return true if c is a valid base64 character
*/
static inline bool is_base64(unsigned char c) {
return (c == 43 || // +
(c >= 47 && c <= 57) || // /-9
(c >= 65 && c <= 90) || // A-Z
(c >= 97 && c <= 122)); // a-z
}
/// Encode a char buffer into a base64 string
/**
* @param input The input data
* @param len The length of input in bytes
* @return A base64 encoded string representing input
*/
inline std::string base64_encode(unsigned char const * input, size_t len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (len--) {
char_array_3[i++] = *(input++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) +
((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) +
((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++) {
ret += base64_chars[char_array_4[i]];
}
i = 0;
}
}
if (i) {
for(j = i; j < 3; j++) {
char_array_3[j] = '\0';
}
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) +
((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) +
((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++) {
ret += base64_chars[char_array_4[j]];
}
while((i++ < 3)) {
ret += '=';
}
}
return ret;
}
/// Encode a string into a base64 string
/**
* @param input The input data
* @return A base64 encoded string representing input
*/
inline std::string base64_encode(std::string const & input) {
return base64_encode(
reinterpret_cast<const unsigned char *>(input.data()),
input.size()
);
}
/// Decode a base64 encoded string into a string of raw bytes
/**
* @param input The base64 encoded input data
* @return A string representing the decoded raw bytes
*/
inline std::string base64_decode(std::string const & input) {
size_t in_len = input.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( input[in_] != '=') && is_base64(input[in_])) {
char_array_4[i++] = input[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++) {
char_array_4[i] = static_cast<unsigned char>(base64_chars.find(char_array_4[i]));
}
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++) {
ret += char_array_3[i];
}
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = static_cast<unsigned char>(base64_chars.find(char_array_4[j]));
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) {
ret += static_cast<std::string::value_type>(char_array_3[j]);
}
}
return ret;
}
} // namespace websocketpp
#endif // _BASE64_HPP_
/*
******
base64.hpp is a repackaging of the base64.cpp and base64.h files into a
single header suitable for use as a header only library. This conversion was
done by Peter Thorson (webmaster@zaphoyd.com) in 2012. All modifications to
the code are redistributed under the same license as the original, which is
listed below.
******
base64.cpp and base64.h
Copyright (C) 2004-2008 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
#ifndef _BASE64_HPP_
#define _BASE64_HPP_
#include <string>
namespace websocketpp {
static std::string const base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
/// Test whether a character is a valid base64 character
/**
* @param c The character to test
* @return true if c is a valid base64 character
*/
static inline bool is_base64(unsigned char c) {
return (c == 43 || // +
(c >= 47 && c <= 57) || // /-9
(c >= 65 && c <= 90) || // A-Z
(c >= 97 && c <= 122)); // a-z
}
/// Encode a char buffer into a base64 string
/**
* @param input The input data
* @param len The length of input in bytes
* @return A base64 encoded string representing input
*/
inline std::string base64_encode(unsigned char const * input, size_t len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (len--) {
char_array_3[i++] = *(input++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) +
((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) +
((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++) {
ret += base64_chars[char_array_4[i]];
}
i = 0;
}
}
if (i) {
for(j = i; j < 3; j++) {
char_array_3[j] = '\0';
}
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) +
((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) +
((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++) {
ret += base64_chars[char_array_4[j]];
}
while((i++ < 3)) {
ret += '=';
}
}
return ret;
}
/// Encode a string into a base64 string
/**
* @param input The input data
* @return A base64 encoded string representing input
*/
inline std::string base64_encode(std::string const & input) {
return base64_encode(
reinterpret_cast<const unsigned char *>(input.data()),
input.size()
);
}
/// Decode a base64 encoded string into a string of raw bytes
/**
* @param input The base64 encoded input data
* @return A string representing the decoded raw bytes
*/
inline std::string base64_decode(std::string const & input) {
size_t in_len = input.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( input[in_] != '=') && is_base64(input[in_])) {
char_array_4[i++] = input[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++) {
char_array_4[i] = static_cast<unsigned char>(base64_chars.find(char_array_4[i]));
}
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++) {
ret += char_array_3[i];
}
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = static_cast<unsigned char>(base64_chars.find(char_array_4[j]));
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) {
ret += static_cast<std::string::value_type>(char_array_3[j]);
}
}
return ret;
}
} // namespace websocketpp
#endif // _BASE64_HPP_

View File

@@ -1,33 +1,33 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CLIENT_HPP
#define WEBSOCKETPP_CLIENT_HPP
#include <websocketpp/roles/client_endpoint.hpp>
#endif //WEBSOCKETPP_CLIENT_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CLIENT_HPP
#define WEBSOCKETPP_CLIENT_HPP
#include <websocketpp/roles/client_endpoint.hpp>
#endif //WEBSOCKETPP_CLIENT_HPP

View File

@@ -1,353 +1,353 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CLOSE_HPP
#define WEBSOCKETPP_CLOSE_HPP
/** \file
* A package of types and methods for manipulating WebSocket close codes.
*/
#include <websocketpp/error.hpp>
#include <websocketpp/common/network.hpp>
#include <websocketpp/common/stdint.hpp>
#include <websocketpp/utf8_validator.hpp>
#include <string>
namespace websocketpp {
/// A package of types and methods for manipulating WebSocket close codes.
namespace close {
/// A package of types and methods for manipulating WebSocket close status'
namespace status {
/// The type of a close code value.
typedef uint16_t value;
/// A blank value for internal use.
static value const blank = 0;
/// Close the connection without a WebSocket close handshake.
/**
* This special value requests that the WebSocket connection be closed
* without performing the WebSocket closing handshake. This does not comply
* with RFC6455, but should be safe to do if necessary. This could be useful
* for clients that need to disconnect quickly and cannot afford the
* complete handshake.
*/
static value const omit_handshake = 1;
/// Close the connection with a forced TCP drop.
/**
* This special value requests that the WebSocket connection be closed by
* forcibly dropping the TCP connection. This will leave the other side of
* the connection with a broken connection and some expensive timeouts. this
* should not be done except in extreme cases or in cases of malicious
* remote endpoints.
*/
static value const force_tcp_drop = 2;
/// Normal closure, meaning that the purpose for which the connection was
/// established has been fulfilled.
static value const normal = 1000;
/// The endpoint was "going away", such as a server going down or a browser
/// navigating away from a page.
static value const going_away = 1001;
/// A protocol error occurred.
static value const protocol_error = 1002;
/// The connection was terminated because an endpoint received a type of
/// data it cannot accept.
/**
* (e.g., an endpoint that understands only text data MAY send this if it
* receives a binary message).
*/
static value const unsupported_data = 1003;
/// A dummy value to indicate that no status code was received.
/**
* This value is illegal on the wire.
*/
static value const no_status = 1005;
/// A dummy value to indicate that the connection was closed abnormally.
/**
* In such a case there was no close frame to extract a value from. This
* value is illegal on the wire.
*/
static value const abnormal_close = 1006;
/// An endpoint received message data inconsistent with its type.
/**
* For example: Invalid UTF8 bytes in a text message.
*/
static value const invalid_payload = 1007;
/// An endpoint received a message that violated its policy.
/**
* This is a generic status code that can be returned when there is no other
* more suitable status code (e.g., 1003 or 1009) or if there is a need to
* hide specific details about the policy.
*/
static value const policy_violation = 1008;
/// An endpoint received a message too large to process.
static value const message_too_big = 1009;
/// A client expected the server to accept a required extension request
/**
* The list of extensions that are needed SHOULD appear in the /reason/ part
* of the Close frame. Note that this status code is not used by the server,
* because it can fail the WebSocket handshake instead.
*/
static value const extension_required = 1010;
/// An endpoint encountered an unexpected condition that prevented it from
/// fulfilling the request.
static value const internal_endpoint_error = 1011;
/// Indicates that the service is restarted. A client may reconnect and if
/// if it chooses to do so, should reconnect using a randomized delay of
/// 5-30s
static value const service_restart = 1012;
/// Indicates that the service is experiencing overload. A client should
/// only connect to a different IP (when there are multiple for the target)
/// or reconnect to the same IP upon user action.
static value const try_again_later = 1013;
/// Indicates that the server was acting as a gateway or proxy and received
/// an invalid response from the upstream server. This is similar to 502
/// HTTP Status Code.
static value const bad_gateway = 1014;
/// An endpoint failed to perform a TLS handshake
/**
* Designated for use in applications expecting a status code to indicate
* that the connection was closed due to a failure to perform a TLS
* handshake (e.g., the server certificate can't be verified). This value is
* illegal on the wire.
*/
static value const tls_handshake = 1015;
/// A generic subprotocol error
/**
* Indicates that a subprotocol error occurred. Typically this involves
* receiving a message that is not formatted as a valid message for the
* subprotocol in use.
*/
static value const subprotocol_error = 3000;
/// A invalid subprotocol data
/**
* Indicates that data was received that violated the specification of the
* subprotocol in use.
*/
static value const invalid_subprotocol_data = 3001;
/// First value in range reserved for future protocol use
static value const rsv_start = 1016;
/// Last value in range reserved for future protocol use
static value const rsv_end = 2999;
/// Test whether a close code is in a reserved range
/**
* @param [in] code The code to test
* @return Whether or not code is reserved
*/
inline bool reserved(value code) {
return ((code >= rsv_start && code <= rsv_end) ||
code == 1004);
}
/// First value in range that is always invalid on the wire
static value const invalid_low = 999;
/// Last value in range that is always invalid on the wire
static value const invalid_high = 5000;
/// Test whether a close code is invalid on the wire
/**
* @param [in] code The code to test
* @return Whether or not code is invalid on the wire
*/
inline bool invalid(value code) {
return (code <= invalid_low || code >= invalid_high ||
code == no_status || code == abnormal_close ||
code == tls_handshake);
}
/// Determine if the code represents an unrecoverable error
/**
* There is a class of errors for which once they are discovered normal
* WebSocket functionality can no longer occur. This function determines
* if a given code is one of these values. This information is used to
* determine if the system has the capability of waiting for a close
* acknowledgement or if it should drop the TCP connection immediately
* after sending its close frame.
*
* @param [in] code The value to test.
* @return True if the code represents an unrecoverable error
*/
inline bool terminal(value code) {
return (code == protocol_error || code == invalid_payload ||
code == policy_violation || code == message_too_big ||
code == internal_endpoint_error);
}
/// Return a human readable interpretation of a WebSocket close code
/**
* See https://tools.ietf.org/html/rfc6455#section-7.4 for more details.
*
* @since 0.3.0
*
* @param [in] code The code to look up.
* @return A human readable interpretation of the code.
*/
inline std::string get_string(value code) {
switch (code) {
case normal:
return "Normal close";
case going_away:
return "Going away";
case protocol_error:
return "Protocol error";
case unsupported_data:
return "Unsupported data";
case no_status:
return "No status set";
case abnormal_close:
return "Abnormal close";
case invalid_payload:
return "Invalid payload";
case policy_violation:
return "Policy violoation";
case message_too_big:
return "Message too big";
case extension_required:
return "Extension required";
case internal_endpoint_error:
return "Internal endpoint error";
case service_restart:
return "Service restart";
case try_again_later:
return "Try again later";
case bad_gateway:
return "Bad gateway";
case tls_handshake:
return "TLS handshake failure";
case subprotocol_error:
return "Generic subprotocol error";
case invalid_subprotocol_data:
return "Invalid subprotocol data";
default:
return "Unknown";
}
}
} // namespace status
/// Type used to convert close statuses between integer and wire representations
union code_converter {
uint16_t i;
char c[2];
};
/// Extract a close code value from a close payload
/**
* If there is no close value (ie string is empty) status::no_status is
* returned. If a code couldn't be extracted (usually do to a short or
* otherwise mangled payload) status::protocol_error is returned and the ec
* value is flagged as an error. Note that this case is different than the case
* where protocol error is received over the wire.
*
* If the value is in an invalid or reserved range ec is set accordingly.
*
* @param [in] payload Close frame payload value received over the wire.
* @param [out] ec Set to indicate what error occurred, if any.
* @return The extracted value
*/
inline status::value extract_code(std::string const & payload, lib::error_code
& ec)
{
ec = lib::error_code();
if (payload.size() == 0) {
return status::no_status;
} else if (payload.size() == 1) {
ec = make_error_code(error::bad_close_code);
return status::protocol_error;
}
code_converter val;
val.c[0] = payload[0];
val.c[1] = payload[1];
status::value code(ntohs(val.i));
if (status::invalid(code)) {
ec = make_error_code(error::invalid_close_code);
}
if (status::reserved(code)) {
ec = make_error_code(error::reserved_close_code);
}
return code;
}
/// Extract the reason string from a close payload
/**
* The string should be a valid UTF8 message. error::invalid_utf8 will be set if
* the function extracts a reason that is not valid UTF8.
*
* @param [in] payload The payload string to extract a reason from.
* @param [out] ec Set to indicate what error occurred, if any.
* @return The reason string.
*/
inline std::string extract_reason(std::string const & payload, lib::error_code
& ec)
{
std::string reason;
ec = lib::error_code();
if (payload.size() > 2) {
reason.append(payload.begin()+2,payload.end());
}
if (!websocketpp::utf8_validator::validate(reason)) {
ec = make_error_code(error::invalid_utf8);
}
return reason;
}
} // namespace close
} // namespace websocketpp
#endif // WEBSOCKETPP_CLOSE_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CLOSE_HPP
#define WEBSOCKETPP_CLOSE_HPP
/** \file
* A package of types and methods for manipulating WebSocket close codes.
*/
#include <websocketpp/error.hpp>
#include <websocketpp/common/network.hpp>
#include <websocketpp/common/stdint.hpp>
#include <websocketpp/utf8_validator.hpp>
#include <string>
namespace websocketpp {
/// A package of types and methods for manipulating WebSocket close codes.
namespace close {
/// A package of types and methods for manipulating WebSocket close status'
namespace status {
/// The type of a close code value.
typedef uint16_t value;
/// A blank value for internal use.
static value const blank = 0;
/// Close the connection without a WebSocket close handshake.
/**
* This special value requests that the WebSocket connection be closed
* without performing the WebSocket closing handshake. This does not comply
* with RFC6455, but should be safe to do if necessary. This could be useful
* for clients that need to disconnect quickly and cannot afford the
* complete handshake.
*/
static value const omit_handshake = 1;
/// Close the connection with a forced TCP drop.
/**
* This special value requests that the WebSocket connection be closed by
* forcibly dropping the TCP connection. This will leave the other side of
* the connection with a broken connection and some expensive timeouts. this
* should not be done except in extreme cases or in cases of malicious
* remote endpoints.
*/
static value const force_tcp_drop = 2;
/// Normal closure, meaning that the purpose for which the connection was
/// established has been fulfilled.
static value const normal = 1000;
/// The endpoint was "going away", such as a server going down or a browser
/// navigating away from a page.
static value const going_away = 1001;
/// A protocol error occurred.
static value const protocol_error = 1002;
/// The connection was terminated because an endpoint received a type of
/// data it cannot accept.
/**
* (e.g., an endpoint that understands only text data MAY send this if it
* receives a binary message).
*/
static value const unsupported_data = 1003;
/// A dummy value to indicate that no status code was received.
/**
* This value is illegal on the wire.
*/
static value const no_status = 1005;
/// A dummy value to indicate that the connection was closed abnormally.
/**
* In such a case there was no close frame to extract a value from. This
* value is illegal on the wire.
*/
static value const abnormal_close = 1006;
/// An endpoint received message data inconsistent with its type.
/**
* For example: Invalid UTF8 bytes in a text message.
*/
static value const invalid_payload = 1007;
/// An endpoint received a message that violated its policy.
/**
* This is a generic status code that can be returned when there is no other
* more suitable status code (e.g., 1003 or 1009) or if there is a need to
* hide specific details about the policy.
*/
static value const policy_violation = 1008;
/// An endpoint received a message too large to process.
static value const message_too_big = 1009;
/// A client expected the server to accept a required extension request
/**
* The list of extensions that are needed SHOULD appear in the /reason/ part
* of the Close frame. Note that this status code is not used by the server,
* because it can fail the WebSocket handshake instead.
*/
static value const extension_required = 1010;
/// An endpoint encountered an unexpected condition that prevented it from
/// fulfilling the request.
static value const internal_endpoint_error = 1011;
/// Indicates that the service is restarted. A client may reconnect and if
/// if it chooses to do so, should reconnect using a randomized delay of
/// 5-30s
static value const service_restart = 1012;
/// Indicates that the service is experiencing overload. A client should
/// only connect to a different IP (when there are multiple for the target)
/// or reconnect to the same IP upon user action.
static value const try_again_later = 1013;
/// Indicates that the server was acting as a gateway or proxy and received
/// an invalid response from the upstream server. This is similar to 502
/// HTTP Status Code.
static value const bad_gateway = 1014;
/// An endpoint failed to perform a TLS handshake
/**
* Designated for use in applications expecting a status code to indicate
* that the connection was closed due to a failure to perform a TLS
* handshake (e.g., the server certificate can't be verified). This value is
* illegal on the wire.
*/
static value const tls_handshake = 1015;
/// A generic subprotocol error
/**
* Indicates that a subprotocol error occurred. Typically this involves
* receiving a message that is not formatted as a valid message for the
* subprotocol in use.
*/
static value const subprotocol_error = 3000;
/// A invalid subprotocol data
/**
* Indicates that data was received that violated the specification of the
* subprotocol in use.
*/
static value const invalid_subprotocol_data = 3001;
/// First value in range reserved for future protocol use
static value const rsv_start = 1016;
/// Last value in range reserved for future protocol use
static value const rsv_end = 2999;
/// Test whether a close code is in a reserved range
/**
* @param [in] code The code to test
* @return Whether or not code is reserved
*/
inline bool reserved(value code) {
return ((code >= rsv_start && code <= rsv_end) ||
code == 1004);
}
/// First value in range that is always invalid on the wire
static value const invalid_low = 999;
/// Last value in range that is always invalid on the wire
static value const invalid_high = 5000;
/// Test whether a close code is invalid on the wire
/**
* @param [in] code The code to test
* @return Whether or not code is invalid on the wire
*/
inline bool invalid(value code) {
return (code <= invalid_low || code >= invalid_high ||
code == no_status || code == abnormal_close ||
code == tls_handshake);
}
/// Determine if the code represents an unrecoverable error
/**
* There is a class of errors for which once they are discovered normal
* WebSocket functionality can no longer occur. This function determines
* if a given code is one of these values. This information is used to
* determine if the system has the capability of waiting for a close
* acknowledgement or if it should drop the TCP connection immediately
* after sending its close frame.
*
* @param [in] code The value to test.
* @return True if the code represents an unrecoverable error
*/
inline bool terminal(value code) {
return (code == protocol_error || code == invalid_payload ||
code == policy_violation || code == message_too_big ||
code == internal_endpoint_error);
}
/// Return a human readable interpretation of a WebSocket close code
/**
* See https://tools.ietf.org/html/rfc6455#section-7.4 for more details.
*
* @since 0.3.0
*
* @param [in] code The code to look up.
* @return A human readable interpretation of the code.
*/
inline std::string get_string(value code) {
switch (code) {
case normal:
return "Normal close";
case going_away:
return "Going away";
case protocol_error:
return "Protocol error";
case unsupported_data:
return "Unsupported data";
case no_status:
return "No status set";
case abnormal_close:
return "Abnormal close";
case invalid_payload:
return "Invalid payload";
case policy_violation:
return "Policy violoation";
case message_too_big:
return "Message too big";
case extension_required:
return "Extension required";
case internal_endpoint_error:
return "Internal endpoint error";
case service_restart:
return "Service restart";
case try_again_later:
return "Try again later";
case bad_gateway:
return "Bad gateway";
case tls_handshake:
return "TLS handshake failure";
case subprotocol_error:
return "Generic subprotocol error";
case invalid_subprotocol_data:
return "Invalid subprotocol data";
default:
return "Unknown";
}
}
} // namespace status
/// Type used to convert close statuses between integer and wire representations
union code_converter {
uint16_t i;
char c[2];
};
/// Extract a close code value from a close payload
/**
* If there is no close value (ie string is empty) status::no_status is
* returned. If a code couldn't be extracted (usually do to a short or
* otherwise mangled payload) status::protocol_error is returned and the ec
* value is flagged as an error. Note that this case is different than the case
* where protocol error is received over the wire.
*
* If the value is in an invalid or reserved range ec is set accordingly.
*
* @param [in] payload Close frame payload value received over the wire.
* @param [out] ec Set to indicate what error occurred, if any.
* @return The extracted value
*/
inline status::value extract_code(std::string const & payload, lib::error_code
& ec)
{
ec = lib::error_code();
if (payload.size() == 0) {
return status::no_status;
} else if (payload.size() == 1) {
ec = make_error_code(error::bad_close_code);
return status::protocol_error;
}
code_converter val;
val.c[0] = payload[0];
val.c[1] = payload[1];
status::value code(ntohs(val.i));
if (status::invalid(code)) {
ec = make_error_code(error::invalid_close_code);
}
if (status::reserved(code)) {
ec = make_error_code(error::reserved_close_code);
}
return code;
}
/// Extract the reason string from a close payload
/**
* The string should be a valid UTF8 message. error::invalid_utf8 will be set if
* the function extracts a reason that is not valid UTF8.
*
* @param [in] payload The payload string to extract a reason from.
* @param [out] ec Set to indicate what error occurred, if any.
* @return The reason string.
*/
inline std::string extract_reason(std::string const & payload, lib::error_code
& ec)
{
std::string reason;
ec = lib::error_code();
if (payload.size() > 2) {
reason.append(payload.begin()+2,payload.end());
}
if (!websocketpp::utf8_validator::validate(reason)) {
ec = make_error_code(error::invalid_utf8);
}
return reason;
}
} // namespace close
} // namespace websocketpp
#endif // WEBSOCKETPP_CLOSE_HPP

View File

@@ -1,141 +1,141 @@
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_ASIO_HPP
#define WEBSOCKETPP_COMMON_ASIO_HPP
// This file goes to some length to preserve compatibility with versions of
// boost older than 1.49 (where the first modern steady_timer timer based on
// boost/std chrono was introduced.
//
// For the versions older than 1.49, the deadline_timer is used instead. this
// brings in dependencies on boost date_time and it has a different interface
// that is normalized by the `lib::asio::is_neg` and `lib::asio::milliseconds`
// wrappers provided by this file.
//
// The primary reason for this continued support is that boost 1.48 is the
// default and not easily changeable version of boost supplied by the package
// manager of popular Linux distributions like Ubuntu 12.04 LTS. Once the need
// for this has passed this should be cleaned up and simplified.
#ifdef ASIO_STANDALONE
#include <asio/version.hpp>
#if (ASIO_VERSION/100000) == 1 && ((ASIO_VERSION/100)%1000) < 8
static_assert(false, "The minimum version of standalone Asio is 1.8.0");
#endif
#include <asio.hpp>
#include <asio/steady_timer.hpp>
#include <websocketpp/common/chrono.hpp>
#else
#include <boost/version.hpp>
// See note above about boost <1.49 compatibility. If we are running on
// boost > 1.48 pull in the steady timer and chrono library
#if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 48
#include <boost/asio/steady_timer.hpp>
#include <websocketpp/common/chrono.hpp>
#endif
#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef ASIO_STANDALONE
namespace asio {
using namespace ::asio;
// Here we assume that we will be using std::error_code with standalone
// Asio. This is probably a good assumption, but it is possible in rare
// cases that local Asio versions would be used.
using std::errc;
// See note above about boost <1.49 compatibility. Because we require
// a standalone Asio version of 1.8+ we are guaranteed to have
// steady_timer available. By convention we require the chrono library
// (either boost or std) for use with standalone Asio.
template <typename T>
bool is_neg(T duration) {
return duration.count() < 0;
}
inline lib::chrono::milliseconds milliseconds(long duration) {
return lib::chrono::milliseconds(duration);
}
} // namespace asio
#else
namespace asio {
using namespace boost::asio;
// See note above about boost <1.49 compatibility
#if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 48
// Using boost::asio >=1.49 so we use chrono and steady_timer
template <typename T>
bool is_neg(T duration) {
return duration.count() < 0;
}
// If boost believes it has std::chrono available it will use it
// so we should also use it for things that relate to boost, even
// if the library would otherwise use boost::chrono.
#if defined(BOOST_ASIO_HAS_STD_CHRONO)
inline std::chrono::milliseconds milliseconds(long duration) {
return std::chrono::milliseconds(duration);
}
#else
inline lib::chrono::milliseconds milliseconds(long duration) {
return lib::chrono::milliseconds(duration);
}
#endif
#else
// Using boost::asio <1.49 we pretend a deadline timer is a steady
// timer and wrap the negative detection and duration conversion
// appropriately.
typedef boost::asio::deadline_timer steady_timer;
template <typename T>
bool is_neg(T duration) {
return duration.is_negative();
}
inline boost::posix_time::time_duration milliseconds(long duration) {
return boost::posix_time::milliseconds(duration);
}
#endif
using boost::system::error_code;
namespace errc = boost::system::errc;
} // namespace asio
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_ASIO_HPP
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_ASIO_HPP
#define WEBSOCKETPP_COMMON_ASIO_HPP
// This file goes to some length to preserve compatibility with versions of
// boost older than 1.49 (where the first modern steady_timer timer based on
// boost/std chrono was introduced.
//
// For the versions older than 1.49, the deadline_timer is used instead. this
// brings in dependencies on boost date_time and it has a different interface
// that is normalized by the `lib::asio::is_neg` and `lib::asio::milliseconds`
// wrappers provided by this file.
//
// The primary reason for this continued support is that boost 1.48 is the
// default and not easily changeable version of boost supplied by the package
// manager of popular Linux distributions like Ubuntu 12.04 LTS. Once the need
// for this has passed this should be cleaned up and simplified.
#ifdef ASIO_STANDALONE
#include <asio/version.hpp>
#if (ASIO_VERSION/100000) == 1 && ((ASIO_VERSION/100)%1000) < 8
static_assert(false, "The minimum version of standalone Asio is 1.8.0");
#endif
#include <asio.hpp>
#include <asio/steady_timer.hpp>
#include <websocketpp/common/chrono.hpp>
#else
#include <boost/version.hpp>
// See note above about boost <1.49 compatibility. If we are running on
// boost > 1.48 pull in the steady timer and chrono library
#if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 48
#include <boost/asio/steady_timer.hpp>
#include <websocketpp/common/chrono.hpp>
#endif
#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef ASIO_STANDALONE
namespace asio {
using namespace ::asio;
// Here we assume that we will be using std::error_code with standalone
// Asio. This is probably a good assumption, but it is possible in rare
// cases that local Asio versions would be used.
using std::errc;
// See note above about boost <1.49 compatibility. Because we require
// a standalone Asio version of 1.8+ we are guaranteed to have
// steady_timer available. By convention we require the chrono library
// (either boost or std) for use with standalone Asio.
template <typename T>
bool is_neg(T duration) {
return duration.count() < 0;
}
inline lib::chrono::milliseconds milliseconds(long duration) {
return lib::chrono::milliseconds(duration);
}
} // namespace asio
#else
namespace asio {
using namespace boost::asio;
// See note above about boost <1.49 compatibility
#if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 48
// Using boost::asio >=1.49 so we use chrono and steady_timer
template <typename T>
bool is_neg(T duration) {
return duration.count() < 0;
}
// If boost believes it has std::chrono available it will use it
// so we should also use it for things that relate to boost, even
// if the library would otherwise use boost::chrono.
#if defined(BOOST_ASIO_HAS_STD_CHRONO)
inline std::chrono::milliseconds milliseconds(long duration) {
return std::chrono::milliseconds(duration);
}
#else
inline lib::chrono::milliseconds milliseconds(long duration) {
return lib::chrono::milliseconds(duration);
}
#endif
#else
// Using boost::asio <1.49 we pretend a deadline timer is a steady
// timer and wrap the negative detection and duration conversion
// appropriately.
typedef boost::asio::deadline_timer steady_timer;
template <typename T>
bool is_neg(T duration) {
return duration.is_negative();
}
inline boost::posix_time::time_duration milliseconds(long duration) {
return boost::posix_time::milliseconds(duration);
}
#endif
using boost::system::error_code;
namespace errc = boost::system::errc;
} // namespace asio
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_ASIO_HPP

View File

@@ -1,39 +1,39 @@
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_ASIO_SSL_HPP
#define WEBSOCKETPP_COMMON_ASIO_SSL_HPP
// NOTE: This file must be included before common/asio.hpp
#ifdef ASIO_STANDALONE
#include <asio/ssl.hpp>
#else
#include <boost/asio/ssl.hpp>
#endif
#endif // WEBSOCKETPP_COMMON_ASIO_SSL_HPP
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_ASIO_SSL_HPP
#define WEBSOCKETPP_COMMON_ASIO_SSL_HPP
// NOTE: This file must be included before common/asio.hpp
#ifdef ASIO_STANDALONE
#include <asio/ssl.hpp>
#else
#include <boost/asio/ssl.hpp>
#endif
#endif // WEBSOCKETPP_COMMON_ASIO_SSL_HPP

View File

@@ -1,68 +1,68 @@
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_CHRONO_HPP
#define WEBSOCKETPP_COMMON_CHRONO_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 functional header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_CHRONO_
#ifndef _WEBSOCKETPP_CPP11_CHRONO_
#define _WEBSOCKETPP_CPP11_CHRONO_
#endif
#endif
// If we're on Visual Studio 2012 or higher and haven't explicitly disabled
// the use of C++11 chrono header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1700 && !defined _WEBSOCKETPP_NO_CPP11_CHRONO_
#ifndef _WEBSOCKETPP_CPP11_CHRONO_
#define _WEBSOCKETPP_CPP11_CHRONO_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_CHRONO_
#include <chrono>
#else
#include <boost/chrono.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_CHRONO_
namespace chrono = std::chrono;
#else
namespace chrono = boost::chrono;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_CHRONO_HPP
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_CHRONO_HPP
#define WEBSOCKETPP_COMMON_CHRONO_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 functional header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_CHRONO_
#ifndef _WEBSOCKETPP_CPP11_CHRONO_
#define _WEBSOCKETPP_CPP11_CHRONO_
#endif
#endif
// If we're on Visual Studio 2012 or higher and haven't explicitly disabled
// the use of C++11 chrono header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1700 && !defined _WEBSOCKETPP_NO_CPP11_CHRONO_
#ifndef _WEBSOCKETPP_CPP11_CHRONO_
#define _WEBSOCKETPP_CPP11_CHRONO_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_CHRONO_
#include <chrono>
#else
#include <boost/chrono.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_CHRONO_
namespace chrono = std::chrono;
#else
namespace chrono = boost::chrono;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_CHRONO_HPP

View File

@@ -1,52 +1,52 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_CONNECTION_HDL_HPP
#define WEBSOCKETPP_COMMON_CONNECTION_HDL_HPP
#include <websocketpp/common/memory.hpp>
namespace websocketpp {
/// A handle to uniquely identify a connection.
/**
* This type uniquely identifies a connection. It is implemented as a weak
* pointer to the connection in question. This provides uniqueness across
* multiple endpoints and ensures that IDs never conflict or run out.
*
* It is safe to make copies of this handle, store those copies in containers,
* and use them from other threads.
*
* This handle can be upgraded to a full shared_ptr using
* `endpoint::get_con_from_hdl()` from within a handler fired by the connection
* that owns the handler.
*/
typedef lib::weak_ptr<void> connection_hdl;
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_CONNECTION_HDL_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_CONNECTION_HDL_HPP
#define WEBSOCKETPP_COMMON_CONNECTION_HDL_HPP
#include <websocketpp/common/memory.hpp>
namespace websocketpp {
/// A handle to uniquely identify a connection.
/**
* This type uniquely identifies a connection. It is implemented as a weak
* pointer to the connection in question. This provides uniqueness across
* multiple endpoints and ensures that IDs never conflict or run out.
*
* It is safe to make copies of this handle, store those copies in containers,
* and use them from other threads.
*
* This handle can be upgraded to a full shared_ptr using
* `endpoint::get_con_from_hdl()` from within a handler fired by the connection
* that owns the handler.
*/
typedef lib::weak_ptr<void> connection_hdl;
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_CONNECTION_HDL_HPP

View File

@@ -1,162 +1,162 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_CPP11_HPP
#define WEBSOCKETPP_COMMON_CPP11_HPP
/**
* This header sets up some constants based on the state of C++11 support
*/
// Hide clang feature detection from other compilers
#ifndef __has_feature // Optional of course.
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
#endif
#ifndef __has_extension
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
#endif
// The code below attempts to use information provided by the build system or
// user supplied defines to selectively enable C++11 language and library
// features. In most cases features that are targeted individually may also be
// selectively disabled via an associated _WEBSOCKETPP_NOXXX_ define.
#if defined(_WEBSOCKETPP_CPP11_STL_) || __cplusplus >= 201103L || defined(_WEBSOCKETPP_CPP11_STRICT_)
// This check tests for blanket c++11 coverage. It can be activated in one
// of three ways. Either the compiler itself reports that it is a full
// C++11 compiler via the __cplusplus macro or the user/build system
// supplies one of the two preprocessor defines below:
// This is defined to allow other WebSocket++ common headers to enable
// C++11 features when they are detected by this file rather than
// duplicating the above logic in every common header.
#define _WEBSOCKETPP_CPP11_INTERNAL_
// _WEBSOCKETPP_CPP11_STRICT_
//
// This define reports to WebSocket++ that 100% of the language and library
// features of C++11 are available. Using this define on a non-C++11
// compiler will result in problems.
// _WEBSOCKETPP_CPP11_STL_
//
// This define enables *most* C++11 options that were implemented early on
// by compilers. It is typically used for compilers that have many, but not
// all C++11 features. It should be safe to use on GCC 4.7-4.8 and perhaps
// earlier.
#ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
#endif
#ifndef _WEBSOCKETPP_CONSTEXPR_TOKEN_
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr
#endif
#ifndef _WEBSOCKETPP_INITIALIZER_LISTS_
#define _WEBSOCKETPP_INITIALIZER_LISTS_
#endif
#ifndef _WEBSOCKETPP_NULLPTR_TOKEN_
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
#endif
#ifndef _WEBSOCKETPP_MOVE_SEMANTICS_
#define _WEBSOCKETPP_MOVE_SEMANTICS_
#endif
#ifndef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#define _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#endif
#ifndef __GNUC__
// GCC as of version 4.9 (latest) does not support std::put_time yet.
// so ignore it
#define _WEBSOCKETPP_PUTTIME_
#endif
#else
// In the absence of a blanket define, try to use compiler versions or
// feature testing macros to selectively enable what we can.
// Test for noexcept
#ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_
#ifdef _WEBSOCKETPP_NOEXCEPT_
// build system says we have noexcept
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
#else
#if __has_feature(cxx_noexcept)
// clang feature detect says we have noexcept
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
#elif defined(_MSC_VER) && _MSC_VER >= 1900
// Visual Studio 2015+ has noexcept
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
#else
// assume we don't have noexcept
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_
#endif
#endif
#endif
// Test for constexpr
#ifndef _WEBSOCKETPP_CONSTEXPR_TOKEN_
#ifdef _WEBSOCKETPP_CONSTEXPR_
// build system says we have constexpr
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr
#else
#if __has_feature(cxx_constexpr)
// clang feature detect says we have constexpr
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr
#elif defined(_MSC_VER) && _MSC_VER >= 1900
// Visual Studio 2015+ has constexpr
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr
#else
// assume we don't have constexpr
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_
#endif
#endif
#endif
// Enable initializer lists on clang when available.
#if __has_feature(cxx_generalized_initializers) && !defined(_WEBSOCKETPP_INITIALIZER_LISTS_)
#define _WEBSOCKETPP_INITIALIZER_LISTS_
#endif
// Test for nullptr
#ifndef _WEBSOCKETPP_NULLPTR_TOKEN_
#ifdef _WEBSOCKETPP_NULLPTR_
// build system says we have nullptr
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
#else
#if __has_feature(cxx_nullptr)
// clang feature detect says we have nullptr
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
#elif defined(_MSC_VER) &&_MSC_VER >= 1600
// Visual Studio version that has nullptr
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
#else
// assume we don't have nullptr
#define _WEBSOCKETPP_NULLPTR_TOKEN_ 0
#endif
#endif
#endif
#endif
#endif // WEBSOCKETPP_COMMON_CPP11_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_CPP11_HPP
#define WEBSOCKETPP_COMMON_CPP11_HPP
/**
* This header sets up some constants based on the state of C++11 support
*/
// Hide clang feature detection from other compilers
#ifndef __has_feature // Optional of course.
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
#endif
#ifndef __has_extension
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
#endif
// The code below attempts to use information provided by the build system or
// user supplied defines to selectively enable C++11 language and library
// features. In most cases features that are targeted individually may also be
// selectively disabled via an associated _WEBSOCKETPP_NOXXX_ define.
#if defined(_WEBSOCKETPP_CPP11_STL_) || __cplusplus >= 201103L || defined(_WEBSOCKETPP_CPP11_STRICT_)
// This check tests for blanket c++11 coverage. It can be activated in one
// of three ways. Either the compiler itself reports that it is a full
// C++11 compiler via the __cplusplus macro or the user/build system
// supplies one of the two preprocessor defines below:
// This is defined to allow other WebSocket++ common headers to enable
// C++11 features when they are detected by this file rather than
// duplicating the above logic in every common header.
#define _WEBSOCKETPP_CPP11_INTERNAL_
// _WEBSOCKETPP_CPP11_STRICT_
//
// This define reports to WebSocket++ that 100% of the language and library
// features of C++11 are available. Using this define on a non-C++11
// compiler will result in problems.
// _WEBSOCKETPP_CPP11_STL_
//
// This define enables *most* C++11 options that were implemented early on
// by compilers. It is typically used for compilers that have many, but not
// all C++11 features. It should be safe to use on GCC 4.7-4.8 and perhaps
// earlier.
#ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
#endif
#ifndef _WEBSOCKETPP_CONSTEXPR_TOKEN_
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr
#endif
#ifndef _WEBSOCKETPP_INITIALIZER_LISTS_
#define _WEBSOCKETPP_INITIALIZER_LISTS_
#endif
#ifndef _WEBSOCKETPP_NULLPTR_TOKEN_
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
#endif
#ifndef _WEBSOCKETPP_MOVE_SEMANTICS_
#define _WEBSOCKETPP_MOVE_SEMANTICS_
#endif
#ifndef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#define _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#endif
#ifndef __GNUC__
// GCC as of version 4.9 (latest) does not support std::put_time yet.
// so ignore it
#define _WEBSOCKETPP_PUTTIME_
#endif
#else
// In the absence of a blanket define, try to use compiler versions or
// feature testing macros to selectively enable what we can.
// Test for noexcept
#ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_
#ifdef _WEBSOCKETPP_NOEXCEPT_
// build system says we have noexcept
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
#else
#if __has_feature(cxx_noexcept)
// clang feature detect says we have noexcept
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
#elif defined(_MSC_VER) && _MSC_VER >= 1900
// Visual Studio 2015+ has noexcept
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
#else
// assume we don't have noexcept
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_
#endif
#endif
#endif
// Test for constexpr
#ifndef _WEBSOCKETPP_CONSTEXPR_TOKEN_
#ifdef _WEBSOCKETPP_CONSTEXPR_
// build system says we have constexpr
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr
#else
#if __has_feature(cxx_constexpr)
// clang feature detect says we have constexpr
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr
#elif defined(_MSC_VER) && _MSC_VER >= 1900
// Visual Studio 2015+ has constexpr
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr
#else
// assume we don't have constexpr
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_
#endif
#endif
#endif
// Enable initializer lists on clang when available.
#if __has_feature(cxx_generalized_initializers) && !defined(_WEBSOCKETPP_INITIALIZER_LISTS_)
#define _WEBSOCKETPP_INITIALIZER_LISTS_
#endif
// Test for nullptr
#ifndef _WEBSOCKETPP_NULLPTR_TOKEN_
#ifdef _WEBSOCKETPP_NULLPTR_
// build system says we have nullptr
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
#else
#if __has_feature(cxx_nullptr)
// clang feature detect says we have nullptr
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
#elif defined(_MSC_VER) &&_MSC_VER >= 1600
// Visual Studio version that has nullptr
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
#else
// assume we don't have nullptr
#define _WEBSOCKETPP_NULLPTR_TOKEN_ 0
#endif
#endif
#endif
#endif
#endif // WEBSOCKETPP_COMMON_CPP11_HPP

View File

@@ -1,105 +1,105 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_FUNCTIONAL_HPP
#define WEBSOCKETPP_COMMON_FUNCTIONAL_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 functional header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_
#ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
#endif
#endif
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
// the use of C++11 functional header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_
#ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_
#include <functional>
#else
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/ref.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_
using std::function;
using std::bind;
using std::ref;
namespace placeholders = std::placeholders;
// There are some cases where a C++11 compiler balks at using std::ref
// but a C++03 compiler using boost function requires boost::ref. As such
// lib::ref is not useful in these cases. Instead this macro allows the use
// of boost::ref in the case of a boost compile or no reference wrapper at
// all in the case of a C++11 compile
#define _WEBSOCKETPP_REF(x) x
template <typename T>
void clear_function(T & x) {
x = nullptr;
}
#else
using boost::function;
using boost::bind;
using boost::ref;
namespace placeholders {
/// \todo this feels hacky, is there a better way?
using ::_1;
using ::_2;
using ::_3;
}
// See above definition for more details on what this is and why it exists
#define _WEBSOCKETPP_REF(x) boost::ref(x)
template <typename T>
void clear_function(T & x) {
x.clear();
}
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_FUNCTIONAL_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_FUNCTIONAL_HPP
#define WEBSOCKETPP_COMMON_FUNCTIONAL_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 functional header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_
#ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
#endif
#endif
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
// the use of C++11 functional header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_
#ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_
#include <functional>
#else
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/ref.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_
using std::function;
using std::bind;
using std::ref;
namespace placeholders = std::placeholders;
// There are some cases where a C++11 compiler balks at using std::ref
// but a C++03 compiler using boost function requires boost::ref. As such
// lib::ref is not useful in these cases. Instead this macro allows the use
// of boost::ref in the case of a boost compile or no reference wrapper at
// all in the case of a C++11 compile
#define _WEBSOCKETPP_REF(x) x
template <typename T>
void clear_function(T & x) {
x = nullptr;
}
#else
using boost::function;
using boost::bind;
using boost::ref;
namespace placeholders {
/// \todo this feels hacky, is there a better way?
using ::_1;
using ::_2;
using ::_3;
}
// See above definition for more details on what this is and why it exists
#define _WEBSOCKETPP_REF(x) boost::ref(x)
template <typename T>
void clear_function(T & x) {
x.clear();
}
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_FUNCTIONAL_HPP

View File

@@ -1,448 +1,448 @@
/*
md5.hpp is a reformulation of the md5.h and md5.c code from
http://www.opensource.apple.com/source/cups/cups-59/cups/md5.c to allow it to
function as a component of a header only library. This conversion was done by
Peter Thorson (webmaster@zaphoyd.com) in 2012 for the WebSocket++ project. The
changes are released under the same license as the original (listed below)
*/
/*
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Removed support for non-ANSI compilers; removed
references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
#ifndef WEBSOCKETPP_COMMON_MD5_HPP
#define WEBSOCKETPP_COMMON_MD5_HPP
/*
* This package supports both compile-time and run-time determination of CPU
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
* defined as non-zero, the code will be compiled to run only on big-endian
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
* run on either big- or little-endian CPUs, but will run slightly less
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
*/
#include <stddef.h>
#include <string>
#include <cstring>
namespace websocketpp {
/// Provides MD5 hashing functionality
namespace md5 {
typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef unsigned int md5_word_t; /* 32-bit word */
/* Define the state of the MD5 Algorithm. */
typedef struct md5_state_s {
md5_word_t count[2]; /* message length in bits, lsw first */
md5_word_t abcd[4]; /* digest buffer */
md5_byte_t buf[64]; /* accumulate block */
} md5_state_t;
/* Initialize the algorithm. */
inline void md5_init(md5_state_t *pms);
/* Append a string to the message. */
inline void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes);
/* Finish the message and return the digest. */
inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN
# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
#else
# define ZSW_MD5_BYTE_ORDER 0
#endif
#define ZSW_MD5_T_MASK ((md5_word_t)~0)
#define ZSW_MD5_T1 /* 0xd76aa478 */ (ZSW_MD5_T_MASK ^ 0x28955b87)
#define ZSW_MD5_T2 /* 0xe8c7b756 */ (ZSW_MD5_T_MASK ^ 0x173848a9)
#define ZSW_MD5_T3 0x242070db
#define ZSW_MD5_T4 /* 0xc1bdceee */ (ZSW_MD5_T_MASK ^ 0x3e423111)
#define ZSW_MD5_T5 /* 0xf57c0faf */ (ZSW_MD5_T_MASK ^ 0x0a83f050)
#define ZSW_MD5_T6 0x4787c62a
#define ZSW_MD5_T7 /* 0xa8304613 */ (ZSW_MD5_T_MASK ^ 0x57cfb9ec)
#define ZSW_MD5_T8 /* 0xfd469501 */ (ZSW_MD5_T_MASK ^ 0x02b96afe)
#define ZSW_MD5_T9 0x698098d8
#define ZSW_MD5_T10 /* 0x8b44f7af */ (ZSW_MD5_T_MASK ^ 0x74bb0850)
#define ZSW_MD5_T11 /* 0xffff5bb1 */ (ZSW_MD5_T_MASK ^ 0x0000a44e)
#define ZSW_MD5_T12 /* 0x895cd7be */ (ZSW_MD5_T_MASK ^ 0x76a32841)
#define ZSW_MD5_T13 0x6b901122
#define ZSW_MD5_T14 /* 0xfd987193 */ (ZSW_MD5_T_MASK ^ 0x02678e6c)
#define ZSW_MD5_T15 /* 0xa679438e */ (ZSW_MD5_T_MASK ^ 0x5986bc71)
#define ZSW_MD5_T16 0x49b40821
#define ZSW_MD5_T17 /* 0xf61e2562 */ (ZSW_MD5_T_MASK ^ 0x09e1da9d)
#define ZSW_MD5_T18 /* 0xc040b340 */ (ZSW_MD5_T_MASK ^ 0x3fbf4cbf)
#define ZSW_MD5_T19 0x265e5a51
#define ZSW_MD5_T20 /* 0xe9b6c7aa */ (ZSW_MD5_T_MASK ^ 0x16493855)
#define ZSW_MD5_T21 /* 0xd62f105d */ (ZSW_MD5_T_MASK ^ 0x29d0efa2)
#define ZSW_MD5_T22 0x02441453
#define ZSW_MD5_T23 /* 0xd8a1e681 */ (ZSW_MD5_T_MASK ^ 0x275e197e)
#define ZSW_MD5_T24 /* 0xe7d3fbc8 */ (ZSW_MD5_T_MASK ^ 0x182c0437)
#define ZSW_MD5_T25 0x21e1cde6
#define ZSW_MD5_T26 /* 0xc33707d6 */ (ZSW_MD5_T_MASK ^ 0x3cc8f829)
#define ZSW_MD5_T27 /* 0xf4d50d87 */ (ZSW_MD5_T_MASK ^ 0x0b2af278)
#define ZSW_MD5_T28 0x455a14ed
#define ZSW_MD5_T29 /* 0xa9e3e905 */ (ZSW_MD5_T_MASK ^ 0x561c16fa)
#define ZSW_MD5_T30 /* 0xfcefa3f8 */ (ZSW_MD5_T_MASK ^ 0x03105c07)
#define ZSW_MD5_T31 0x676f02d9
#define ZSW_MD5_T32 /* 0x8d2a4c8a */ (ZSW_MD5_T_MASK ^ 0x72d5b375)
#define ZSW_MD5_T33 /* 0xfffa3942 */ (ZSW_MD5_T_MASK ^ 0x0005c6bd)
#define ZSW_MD5_T34 /* 0x8771f681 */ (ZSW_MD5_T_MASK ^ 0x788e097e)
#define ZSW_MD5_T35 0x6d9d6122
#define ZSW_MD5_T36 /* 0xfde5380c */ (ZSW_MD5_T_MASK ^ 0x021ac7f3)
#define ZSW_MD5_T37 /* 0xa4beea44 */ (ZSW_MD5_T_MASK ^ 0x5b4115bb)
#define ZSW_MD5_T38 0x4bdecfa9
#define ZSW_MD5_T39 /* 0xf6bb4b60 */ (ZSW_MD5_T_MASK ^ 0x0944b49f)
#define ZSW_MD5_T40 /* 0xbebfbc70 */ (ZSW_MD5_T_MASK ^ 0x4140438f)
#define ZSW_MD5_T41 0x289b7ec6
#define ZSW_MD5_T42 /* 0xeaa127fa */ (ZSW_MD5_T_MASK ^ 0x155ed805)
#define ZSW_MD5_T43 /* 0xd4ef3085 */ (ZSW_MD5_T_MASK ^ 0x2b10cf7a)
#define ZSW_MD5_T44 0x04881d05
#define ZSW_MD5_T45 /* 0xd9d4d039 */ (ZSW_MD5_T_MASK ^ 0x262b2fc6)
#define ZSW_MD5_T46 /* 0xe6db99e5 */ (ZSW_MD5_T_MASK ^ 0x1924661a)
#define ZSW_MD5_T47 0x1fa27cf8
#define ZSW_MD5_T48 /* 0xc4ac5665 */ (ZSW_MD5_T_MASK ^ 0x3b53a99a)
#define ZSW_MD5_T49 /* 0xf4292244 */ (ZSW_MD5_T_MASK ^ 0x0bd6ddbb)
#define ZSW_MD5_T50 0x432aff97
#define ZSW_MD5_T51 /* 0xab9423a7 */ (ZSW_MD5_T_MASK ^ 0x546bdc58)
#define ZSW_MD5_T52 /* 0xfc93a039 */ (ZSW_MD5_T_MASK ^ 0x036c5fc6)
#define ZSW_MD5_T53 0x655b59c3
#define ZSW_MD5_T54 /* 0x8f0ccc92 */ (ZSW_MD5_T_MASK ^ 0x70f3336d)
#define ZSW_MD5_T55 /* 0xffeff47d */ (ZSW_MD5_T_MASK ^ 0x00100b82)
#define ZSW_MD5_T56 /* 0x85845dd1 */ (ZSW_MD5_T_MASK ^ 0x7a7ba22e)
#define ZSW_MD5_T57 0x6fa87e4f
#define ZSW_MD5_T58 /* 0xfe2ce6e0 */ (ZSW_MD5_T_MASK ^ 0x01d3191f)
#define ZSW_MD5_T59 /* 0xa3014314 */ (ZSW_MD5_T_MASK ^ 0x5cfebceb)
#define ZSW_MD5_T60 0x4e0811a1
#define ZSW_MD5_T61 /* 0xf7537e82 */ (ZSW_MD5_T_MASK ^ 0x08ac817d)
#define ZSW_MD5_T62 /* 0xbd3af235 */ (ZSW_MD5_T_MASK ^ 0x42c50dca)
#define ZSW_MD5_T63 0x2ad7d2bb
#define ZSW_MD5_T64 /* 0xeb86d391 */ (ZSW_MD5_T_MASK ^ 0x14792c6e)
static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
md5_word_t
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
md5_word_t t;
#if ZSW_MD5_BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
md5_word_t X[16];
#else
/* Define storage for little-endian or both types of CPUs. */
md5_word_t xbuf[16];
md5_word_t const * X;
#endif
{
#if ZSW_MD5_BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static int const w = 1;
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
#endif
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (md5_byte_t const *)0) & 3)) {
/* data are properly aligned */
X = (md5_word_t const *)data;
} else {
/* not aligned */
std::memcpy(xbuf, data, 64);
X = xbuf;
}
}
#endif
#if ZSW_MD5_BYTE_ORDER == 0
else /* dynamic big-endian */
#endif
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const md5_byte_t *xp = data;
int i;
# if ZSW_MD5_BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */
# else
# define xbuf X /* (static only) */
# endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
#define ZSW_MD5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_F(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, ZSW_MD5_T1);
SET(d, a, b, c, 1, 12, ZSW_MD5_T2);
SET(c, d, a, b, 2, 17, ZSW_MD5_T3);
SET(b, c, d, a, 3, 22, ZSW_MD5_T4);
SET(a, b, c, d, 4, 7, ZSW_MD5_T5);
SET(d, a, b, c, 5, 12, ZSW_MD5_T6);
SET(c, d, a, b, 6, 17, ZSW_MD5_T7);
SET(b, c, d, a, 7, 22, ZSW_MD5_T8);
SET(a, b, c, d, 8, 7, ZSW_MD5_T9);
SET(d, a, b, c, 9, 12, ZSW_MD5_T10);
SET(c, d, a, b, 10, 17, ZSW_MD5_T11);
SET(b, c, d, a, 11, 22, ZSW_MD5_T12);
SET(a, b, c, d, 12, 7, ZSW_MD5_T13);
SET(d, a, b, c, 13, 12, ZSW_MD5_T14);
SET(c, d, a, b, 14, 17, ZSW_MD5_T15);
SET(b, c, d, a, 15, 22, ZSW_MD5_T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_G(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, ZSW_MD5_T17);
SET(d, a, b, c, 6, 9, ZSW_MD5_T18);
SET(c, d, a, b, 11, 14, ZSW_MD5_T19);
SET(b, c, d, a, 0, 20, ZSW_MD5_T20);
SET(a, b, c, d, 5, 5, ZSW_MD5_T21);
SET(d, a, b, c, 10, 9, ZSW_MD5_T22);
SET(c, d, a, b, 15, 14, ZSW_MD5_T23);
SET(b, c, d, a, 4, 20, ZSW_MD5_T24);
SET(a, b, c, d, 9, 5, ZSW_MD5_T25);
SET(d, a, b, c, 14, 9, ZSW_MD5_T26);
SET(c, d, a, b, 3, 14, ZSW_MD5_T27);
SET(b, c, d, a, 8, 20, ZSW_MD5_T28);
SET(a, b, c, d, 13, 5, ZSW_MD5_T29);
SET(d, a, b, c, 2, 9, ZSW_MD5_T30);
SET(c, d, a, b, 7, 14, ZSW_MD5_T31);
SET(b, c, d, a, 12, 20, ZSW_MD5_T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_H(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, ZSW_MD5_T33);
SET(d, a, b, c, 8, 11, ZSW_MD5_T34);
SET(c, d, a, b, 11, 16, ZSW_MD5_T35);
SET(b, c, d, a, 14, 23, ZSW_MD5_T36);
SET(a, b, c, d, 1, 4, ZSW_MD5_T37);
SET(d, a, b, c, 4, 11, ZSW_MD5_T38);
SET(c, d, a, b, 7, 16, ZSW_MD5_T39);
SET(b, c, d, a, 10, 23, ZSW_MD5_T40);
SET(a, b, c, d, 13, 4, ZSW_MD5_T41);
SET(d, a, b, c, 0, 11, ZSW_MD5_T42);
SET(c, d, a, b, 3, 16, ZSW_MD5_T43);
SET(b, c, d, a, 6, 23, ZSW_MD5_T44);
SET(a, b, c, d, 9, 4, ZSW_MD5_T45);
SET(d, a, b, c, 12, 11, ZSW_MD5_T46);
SET(c, d, a, b, 15, 16, ZSW_MD5_T47);
SET(b, c, d, a, 2, 23, ZSW_MD5_T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_I(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, ZSW_MD5_T49);
SET(d, a, b, c, 7, 10, ZSW_MD5_T50);
SET(c, d, a, b, 14, 15, ZSW_MD5_T51);
SET(b, c, d, a, 5, 21, ZSW_MD5_T52);
SET(a, b, c, d, 12, 6, ZSW_MD5_T53);
SET(d, a, b, c, 3, 10, ZSW_MD5_T54);
SET(c, d, a, b, 10, 15, ZSW_MD5_T55);
SET(b, c, d, a, 1, 21, ZSW_MD5_T56);
SET(a, b, c, d, 8, 6, ZSW_MD5_T57);
SET(d, a, b, c, 15, 10, ZSW_MD5_T58);
SET(c, d, a, b, 6, 15, ZSW_MD5_T59);
SET(b, c, d, a, 13, 21, ZSW_MD5_T60);
SET(a, b, c, d, 4, 6, ZSW_MD5_T61);
SET(d, a, b, c, 11, 10, ZSW_MD5_T62);
SET(c, d, a, b, 2, 15, ZSW_MD5_T63);
SET(b, c, d, a, 9, 21, ZSW_MD5_T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
pms->abcd[0] += a;
pms->abcd[1] += b;
pms->abcd[2] += c;
pms->abcd[3] += d;
}
void md5_init(md5_state_t *pms) {
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ ZSW_MD5_T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ ZSW_MD5_T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476;
}
void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes) {
md5_byte_t const * p = data;
size_t left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes));
std::memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
md5_process(pms, p);
/* Process a final partial block. */
if (left)
std::memcpy(pms->buf, p, left);
}
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
static md5_byte_t const pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
md5_byte_t data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}
// some convenience c++ functions
inline std::string md5_hash_string(std::string const & s) {
char digest[16];
md5_state_t state;
md5_init(&state);
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
md5_finish(&state, (md5_byte_t *)digest);
std::string ret;
ret.resize(16);
std::copy(digest,digest+16,ret.begin());
return ret;
}
const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
inline std::string md5_hash_hex(std::string const & input) {
std::string hash = md5_hash_string(input);
std::string hex;
for (size_t i = 0; i < hash.size(); i++) {
hex.push_back(hexval[((hash[i] >> 4) & 0xF)]);
hex.push_back(hexval[(hash[i]) & 0x0F]);
}
return hex;
}
} // md5
} // websocketpp
#endif // WEBSOCKETPP_COMMON_MD5_HPP
/*
md5.hpp is a reformulation of the md5.h and md5.c code from
http://www.opensource.apple.com/source/cups/cups-59/cups/md5.c to allow it to
function as a component of a header only library. This conversion was done by
Peter Thorson (webmaster@zaphoyd.com) in 2012 for the WebSocket++ project. The
changes are released under the same license as the original (listed below)
*/
/*
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Removed support for non-ANSI compilers; removed
references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
#ifndef WEBSOCKETPP_COMMON_MD5_HPP
#define WEBSOCKETPP_COMMON_MD5_HPP
/*
* This package supports both compile-time and run-time determination of CPU
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
* defined as non-zero, the code will be compiled to run only on big-endian
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
* run on either big- or little-endian CPUs, but will run slightly less
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
*/
#include <stddef.h>
#include <string>
#include <cstring>
namespace websocketpp {
/// Provides MD5 hashing functionality
namespace md5 {
typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef unsigned int md5_word_t; /* 32-bit word */
/* Define the state of the MD5 Algorithm. */
typedef struct md5_state_s {
md5_word_t count[2]; /* message length in bits, lsw first */
md5_word_t abcd[4]; /* digest buffer */
md5_byte_t buf[64]; /* accumulate block */
} md5_state_t;
/* Initialize the algorithm. */
inline void md5_init(md5_state_t *pms);
/* Append a string to the message. */
inline void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes);
/* Finish the message and return the digest. */
inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN
# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
#else
# define ZSW_MD5_BYTE_ORDER 0
#endif
#define ZSW_MD5_T_MASK ((md5_word_t)~0)
#define ZSW_MD5_T1 /* 0xd76aa478 */ (ZSW_MD5_T_MASK ^ 0x28955b87)
#define ZSW_MD5_T2 /* 0xe8c7b756 */ (ZSW_MD5_T_MASK ^ 0x173848a9)
#define ZSW_MD5_T3 0x242070db
#define ZSW_MD5_T4 /* 0xc1bdceee */ (ZSW_MD5_T_MASK ^ 0x3e423111)
#define ZSW_MD5_T5 /* 0xf57c0faf */ (ZSW_MD5_T_MASK ^ 0x0a83f050)
#define ZSW_MD5_T6 0x4787c62a
#define ZSW_MD5_T7 /* 0xa8304613 */ (ZSW_MD5_T_MASK ^ 0x57cfb9ec)
#define ZSW_MD5_T8 /* 0xfd469501 */ (ZSW_MD5_T_MASK ^ 0x02b96afe)
#define ZSW_MD5_T9 0x698098d8
#define ZSW_MD5_T10 /* 0x8b44f7af */ (ZSW_MD5_T_MASK ^ 0x74bb0850)
#define ZSW_MD5_T11 /* 0xffff5bb1 */ (ZSW_MD5_T_MASK ^ 0x0000a44e)
#define ZSW_MD5_T12 /* 0x895cd7be */ (ZSW_MD5_T_MASK ^ 0x76a32841)
#define ZSW_MD5_T13 0x6b901122
#define ZSW_MD5_T14 /* 0xfd987193 */ (ZSW_MD5_T_MASK ^ 0x02678e6c)
#define ZSW_MD5_T15 /* 0xa679438e */ (ZSW_MD5_T_MASK ^ 0x5986bc71)
#define ZSW_MD5_T16 0x49b40821
#define ZSW_MD5_T17 /* 0xf61e2562 */ (ZSW_MD5_T_MASK ^ 0x09e1da9d)
#define ZSW_MD5_T18 /* 0xc040b340 */ (ZSW_MD5_T_MASK ^ 0x3fbf4cbf)
#define ZSW_MD5_T19 0x265e5a51
#define ZSW_MD5_T20 /* 0xe9b6c7aa */ (ZSW_MD5_T_MASK ^ 0x16493855)
#define ZSW_MD5_T21 /* 0xd62f105d */ (ZSW_MD5_T_MASK ^ 0x29d0efa2)
#define ZSW_MD5_T22 0x02441453
#define ZSW_MD5_T23 /* 0xd8a1e681 */ (ZSW_MD5_T_MASK ^ 0x275e197e)
#define ZSW_MD5_T24 /* 0xe7d3fbc8 */ (ZSW_MD5_T_MASK ^ 0x182c0437)
#define ZSW_MD5_T25 0x21e1cde6
#define ZSW_MD5_T26 /* 0xc33707d6 */ (ZSW_MD5_T_MASK ^ 0x3cc8f829)
#define ZSW_MD5_T27 /* 0xf4d50d87 */ (ZSW_MD5_T_MASK ^ 0x0b2af278)
#define ZSW_MD5_T28 0x455a14ed
#define ZSW_MD5_T29 /* 0xa9e3e905 */ (ZSW_MD5_T_MASK ^ 0x561c16fa)
#define ZSW_MD5_T30 /* 0xfcefa3f8 */ (ZSW_MD5_T_MASK ^ 0x03105c07)
#define ZSW_MD5_T31 0x676f02d9
#define ZSW_MD5_T32 /* 0x8d2a4c8a */ (ZSW_MD5_T_MASK ^ 0x72d5b375)
#define ZSW_MD5_T33 /* 0xfffa3942 */ (ZSW_MD5_T_MASK ^ 0x0005c6bd)
#define ZSW_MD5_T34 /* 0x8771f681 */ (ZSW_MD5_T_MASK ^ 0x788e097e)
#define ZSW_MD5_T35 0x6d9d6122
#define ZSW_MD5_T36 /* 0xfde5380c */ (ZSW_MD5_T_MASK ^ 0x021ac7f3)
#define ZSW_MD5_T37 /* 0xa4beea44 */ (ZSW_MD5_T_MASK ^ 0x5b4115bb)
#define ZSW_MD5_T38 0x4bdecfa9
#define ZSW_MD5_T39 /* 0xf6bb4b60 */ (ZSW_MD5_T_MASK ^ 0x0944b49f)
#define ZSW_MD5_T40 /* 0xbebfbc70 */ (ZSW_MD5_T_MASK ^ 0x4140438f)
#define ZSW_MD5_T41 0x289b7ec6
#define ZSW_MD5_T42 /* 0xeaa127fa */ (ZSW_MD5_T_MASK ^ 0x155ed805)
#define ZSW_MD5_T43 /* 0xd4ef3085 */ (ZSW_MD5_T_MASK ^ 0x2b10cf7a)
#define ZSW_MD5_T44 0x04881d05
#define ZSW_MD5_T45 /* 0xd9d4d039 */ (ZSW_MD5_T_MASK ^ 0x262b2fc6)
#define ZSW_MD5_T46 /* 0xe6db99e5 */ (ZSW_MD5_T_MASK ^ 0x1924661a)
#define ZSW_MD5_T47 0x1fa27cf8
#define ZSW_MD5_T48 /* 0xc4ac5665 */ (ZSW_MD5_T_MASK ^ 0x3b53a99a)
#define ZSW_MD5_T49 /* 0xf4292244 */ (ZSW_MD5_T_MASK ^ 0x0bd6ddbb)
#define ZSW_MD5_T50 0x432aff97
#define ZSW_MD5_T51 /* 0xab9423a7 */ (ZSW_MD5_T_MASK ^ 0x546bdc58)
#define ZSW_MD5_T52 /* 0xfc93a039 */ (ZSW_MD5_T_MASK ^ 0x036c5fc6)
#define ZSW_MD5_T53 0x655b59c3
#define ZSW_MD5_T54 /* 0x8f0ccc92 */ (ZSW_MD5_T_MASK ^ 0x70f3336d)
#define ZSW_MD5_T55 /* 0xffeff47d */ (ZSW_MD5_T_MASK ^ 0x00100b82)
#define ZSW_MD5_T56 /* 0x85845dd1 */ (ZSW_MD5_T_MASK ^ 0x7a7ba22e)
#define ZSW_MD5_T57 0x6fa87e4f
#define ZSW_MD5_T58 /* 0xfe2ce6e0 */ (ZSW_MD5_T_MASK ^ 0x01d3191f)
#define ZSW_MD5_T59 /* 0xa3014314 */ (ZSW_MD5_T_MASK ^ 0x5cfebceb)
#define ZSW_MD5_T60 0x4e0811a1
#define ZSW_MD5_T61 /* 0xf7537e82 */ (ZSW_MD5_T_MASK ^ 0x08ac817d)
#define ZSW_MD5_T62 /* 0xbd3af235 */ (ZSW_MD5_T_MASK ^ 0x42c50dca)
#define ZSW_MD5_T63 0x2ad7d2bb
#define ZSW_MD5_T64 /* 0xeb86d391 */ (ZSW_MD5_T_MASK ^ 0x14792c6e)
static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
md5_word_t
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
md5_word_t t;
#if ZSW_MD5_BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
md5_word_t X[16];
#else
/* Define storage for little-endian or both types of CPUs. */
md5_word_t xbuf[16];
md5_word_t const * X;
#endif
{
#if ZSW_MD5_BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static int const w = 1;
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
#endif
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (md5_byte_t const *)0) & 3)) {
/* data are properly aligned */
X = (md5_word_t const *)data;
} else {
/* not aligned */
std::memcpy(xbuf, data, 64);
X = xbuf;
}
}
#endif
#if ZSW_MD5_BYTE_ORDER == 0
else /* dynamic big-endian */
#endif
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const md5_byte_t *xp = data;
int i;
# if ZSW_MD5_BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */
# else
# define xbuf X /* (static only) */
# endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
#define ZSW_MD5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_F(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, ZSW_MD5_T1);
SET(d, a, b, c, 1, 12, ZSW_MD5_T2);
SET(c, d, a, b, 2, 17, ZSW_MD5_T3);
SET(b, c, d, a, 3, 22, ZSW_MD5_T4);
SET(a, b, c, d, 4, 7, ZSW_MD5_T5);
SET(d, a, b, c, 5, 12, ZSW_MD5_T6);
SET(c, d, a, b, 6, 17, ZSW_MD5_T7);
SET(b, c, d, a, 7, 22, ZSW_MD5_T8);
SET(a, b, c, d, 8, 7, ZSW_MD5_T9);
SET(d, a, b, c, 9, 12, ZSW_MD5_T10);
SET(c, d, a, b, 10, 17, ZSW_MD5_T11);
SET(b, c, d, a, 11, 22, ZSW_MD5_T12);
SET(a, b, c, d, 12, 7, ZSW_MD5_T13);
SET(d, a, b, c, 13, 12, ZSW_MD5_T14);
SET(c, d, a, b, 14, 17, ZSW_MD5_T15);
SET(b, c, d, a, 15, 22, ZSW_MD5_T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_G(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, ZSW_MD5_T17);
SET(d, a, b, c, 6, 9, ZSW_MD5_T18);
SET(c, d, a, b, 11, 14, ZSW_MD5_T19);
SET(b, c, d, a, 0, 20, ZSW_MD5_T20);
SET(a, b, c, d, 5, 5, ZSW_MD5_T21);
SET(d, a, b, c, 10, 9, ZSW_MD5_T22);
SET(c, d, a, b, 15, 14, ZSW_MD5_T23);
SET(b, c, d, a, 4, 20, ZSW_MD5_T24);
SET(a, b, c, d, 9, 5, ZSW_MD5_T25);
SET(d, a, b, c, 14, 9, ZSW_MD5_T26);
SET(c, d, a, b, 3, 14, ZSW_MD5_T27);
SET(b, c, d, a, 8, 20, ZSW_MD5_T28);
SET(a, b, c, d, 13, 5, ZSW_MD5_T29);
SET(d, a, b, c, 2, 9, ZSW_MD5_T30);
SET(c, d, a, b, 7, 14, ZSW_MD5_T31);
SET(b, c, d, a, 12, 20, ZSW_MD5_T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_H(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, ZSW_MD5_T33);
SET(d, a, b, c, 8, 11, ZSW_MD5_T34);
SET(c, d, a, b, 11, 16, ZSW_MD5_T35);
SET(b, c, d, a, 14, 23, ZSW_MD5_T36);
SET(a, b, c, d, 1, 4, ZSW_MD5_T37);
SET(d, a, b, c, 4, 11, ZSW_MD5_T38);
SET(c, d, a, b, 7, 16, ZSW_MD5_T39);
SET(b, c, d, a, 10, 23, ZSW_MD5_T40);
SET(a, b, c, d, 13, 4, ZSW_MD5_T41);
SET(d, a, b, c, 0, 11, ZSW_MD5_T42);
SET(c, d, a, b, 3, 16, ZSW_MD5_T43);
SET(b, c, d, a, 6, 23, ZSW_MD5_T44);
SET(a, b, c, d, 9, 4, ZSW_MD5_T45);
SET(d, a, b, c, 12, 11, ZSW_MD5_T46);
SET(c, d, a, b, 15, 16, ZSW_MD5_T47);
SET(b, c, d, a, 2, 23, ZSW_MD5_T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_I(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, ZSW_MD5_T49);
SET(d, a, b, c, 7, 10, ZSW_MD5_T50);
SET(c, d, a, b, 14, 15, ZSW_MD5_T51);
SET(b, c, d, a, 5, 21, ZSW_MD5_T52);
SET(a, b, c, d, 12, 6, ZSW_MD5_T53);
SET(d, a, b, c, 3, 10, ZSW_MD5_T54);
SET(c, d, a, b, 10, 15, ZSW_MD5_T55);
SET(b, c, d, a, 1, 21, ZSW_MD5_T56);
SET(a, b, c, d, 8, 6, ZSW_MD5_T57);
SET(d, a, b, c, 15, 10, ZSW_MD5_T58);
SET(c, d, a, b, 6, 15, ZSW_MD5_T59);
SET(b, c, d, a, 13, 21, ZSW_MD5_T60);
SET(a, b, c, d, 4, 6, ZSW_MD5_T61);
SET(d, a, b, c, 11, 10, ZSW_MD5_T62);
SET(c, d, a, b, 2, 15, ZSW_MD5_T63);
SET(b, c, d, a, 9, 21, ZSW_MD5_T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
pms->abcd[0] += a;
pms->abcd[1] += b;
pms->abcd[2] += c;
pms->abcd[3] += d;
}
void md5_init(md5_state_t *pms) {
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ ZSW_MD5_T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ ZSW_MD5_T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476;
}
void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes) {
md5_byte_t const * p = data;
size_t left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes));
std::memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
md5_process(pms, p);
/* Process a final partial block. */
if (left)
std::memcpy(pms->buf, p, left);
}
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
static md5_byte_t const pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
md5_byte_t data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}
// some convenience c++ functions
inline std::string md5_hash_string(std::string const & s) {
char digest[16];
md5_state_t state;
md5_init(&state);
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
md5_finish(&state, (md5_byte_t *)digest);
std::string ret;
ret.resize(16);
std::copy(digest,digest+16,ret.begin());
return ret;
}
const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
inline std::string md5_hash_hex(std::string const & input) {
std::string hash = md5_hash_string(input);
std::string hex;
for (size_t i = 0; i < hash.size(); i++) {
hex.push_back(hexval[((hash[i] >> 4) & 0xF)]);
hex.push_back(hexval[(hash[i]) & 0x0F]);
}
return hex;
}
} // md5
} // websocketpp
#endif // WEBSOCKETPP_COMMON_MD5_HPP

View File

@@ -1,88 +1,88 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_MEMORY_HPP
#define WEBSOCKETPP_COMMON_MEMORY_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 memory header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_
#ifndef _WEBSOCKETPP_CPP11_MEMORY_
#define _WEBSOCKETPP_CPP11_MEMORY_
#endif
#endif
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
// the use of C++11 functional header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_
#ifndef _WEBSOCKETPP_CPP11_MEMORY_
#define _WEBSOCKETPP_CPP11_MEMORY_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
#include <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>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
using std::shared_ptr;
using std::weak_ptr;
using std::enable_shared_from_this;
using std::static_pointer_cast;
using std::make_shared;
using std::unique_ptr;
typedef std::unique_ptr<unsigned char[]> unique_ptr_uchar_array;
#else
using boost::shared_ptr;
using boost::weak_ptr;
using std::auto_ptr;
using boost::enable_shared_from_this;
using boost::static_pointer_cast;
using boost::make_shared;
typedef boost::scoped_array<unsigned char> unique_ptr_uchar_array;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_MEMORY_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_MEMORY_HPP
#define WEBSOCKETPP_COMMON_MEMORY_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 memory header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_
#ifndef _WEBSOCKETPP_CPP11_MEMORY_
#define _WEBSOCKETPP_CPP11_MEMORY_
#endif
#endif
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
// the use of C++11 functional header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_
#ifndef _WEBSOCKETPP_CPP11_MEMORY_
#define _WEBSOCKETPP_CPP11_MEMORY_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
#include <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>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
using std::shared_ptr;
using std::weak_ptr;
using std::enable_shared_from_this;
using std::static_pointer_cast;
using std::make_shared;
using std::unique_ptr;
typedef std::unique_ptr<unsigned char[]> unique_ptr_uchar_array;
#else
using boost::shared_ptr;
using boost::weak_ptr;
using std::auto_ptr;
using boost::enable_shared_from_this;
using boost::static_pointer_cast;
using boost::make_shared;
typedef boost::scoped_array<unsigned char> unique_ptr_uchar_array;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_MEMORY_HPP

View File

@@ -1,106 +1,106 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_NETWORK_HPP
#define WEBSOCKETPP_COMMON_NETWORK_HPP
// For ntohs and htons
#if defined(_WIN32)
#include <winsock2.h>
#else
//#include <arpa/inet.h>
#include <netinet/in.h>
#endif
#include <websocketpp/common/stdint.hpp>
namespace websocketpp {
namespace lib {
namespace net {
inline bool is_little_endian() {
short int val = 0x1;
char *ptr = reinterpret_cast<char *>(&val);
return (ptr[0] == 1);
}
#define TYP_INIT 0
#define TYP_SMLE 1
#define TYP_BIGE 2
/// Convert 64 bit value to network byte order
/**
* This method is prefixed to avoid conflicts with operating system level
* macros for this functionality.
*
* TODO: figure out if it would be beneficial to use operating system level
* macros for this.
*
* @param src The integer in host byte order
* @return src converted to network byte order
*/
inline uint64_t _htonll(uint64_t src) {
static int typ = TYP_INIT;
unsigned char c;
union {
uint64_t ull;
unsigned char c[8];
} x;
if (typ == TYP_INIT) {
x.ull = 0x01;
typ = (x.c[7] == 0x01ULL) ? TYP_BIGE : TYP_SMLE;
}
if (typ == TYP_BIGE)
return src;
x.ull = src;
c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c;
c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c;
c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c;
c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c;
return x.ull;
}
/// Convert 64 bit value to host byte order
/**
* This method is prefixed to avoid conflicts with operating system level
* macros for this functionality.
*
* TODO: figure out if it would be beneficial to use operating system level
* macros for this.
*
* @param src The integer in network byte order
* @return src converted to host byte order
*/
inline uint64_t _ntohll(uint64_t src) {
return _htonll(src);
}
} // net
} // lib
} // websocketpp
#endif // WEBSOCKETPP_COMMON_NETWORK_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_NETWORK_HPP
#define WEBSOCKETPP_COMMON_NETWORK_HPP
// For ntohs and htons
#if defined(_WIN32)
#include <winsock2.h>
#else
//#include <arpa/inet.h>
#include <netinet/in.h>
#endif
#include <websocketpp/common/stdint.hpp>
namespace websocketpp {
namespace lib {
namespace net {
inline bool is_little_endian() {
short int val = 0x1;
char *ptr = reinterpret_cast<char *>(&val);
return (ptr[0] == 1);
}
#define TYP_INIT 0
#define TYP_SMLE 1
#define TYP_BIGE 2
/// Convert 64 bit value to network byte order
/**
* This method is prefixed to avoid conflicts with operating system level
* macros for this functionality.
*
* TODO: figure out if it would be beneficial to use operating system level
* macros for this.
*
* @param src The integer in host byte order
* @return src converted to network byte order
*/
inline uint64_t _htonll(uint64_t src) {
static int typ = TYP_INIT;
unsigned char c;
union {
uint64_t ull;
unsigned char c[8];
} x;
if (typ == TYP_INIT) {
x.ull = 0x01;
typ = (x.c[7] == 0x01ULL) ? TYP_BIGE : TYP_SMLE;
}
if (typ == TYP_BIGE)
return src;
x.ull = src;
c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c;
c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c;
c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c;
c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c;
return x.ull;
}
/// Convert 64 bit value to host byte order
/**
* This method is prefixed to avoid conflicts with operating system level
* macros for this functionality.
*
* TODO: figure out if it would be beneficial to use operating system level
* macros for this.
*
* @param src The integer in network byte order
* @return src converted to host byte order
*/
inline uint64_t _ntohll(uint64_t src) {
return _htonll(src);
}
} // net
} // lib
} // websocketpp
#endif // WEBSOCKETPP_COMMON_NETWORK_HPP

View File

@@ -1,46 +1,46 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_PLATFORMS_HPP
#define WEBSOCKETPP_COMMON_PLATFORMS_HPP
/**
* This header contains any platform specific preprocessor adjustments that
* don't fit somewhere else better.
*/
#if defined(_WIN32) && !defined(NOMINMAX)
// don't define min and max macros that conflict with std::min and std::max
#define NOMINMAX
#endif
// Bump up the variadic parameter max for Visual Studio 2012
#if defined(_MSC_VER) && _MSC_VER == 1700
#define _VARIADIC_MAX 8
#endif
#endif // WEBSOCKETPP_COMMON_PLATFORMS_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_PLATFORMS_HPP
#define WEBSOCKETPP_COMMON_PLATFORMS_HPP
/**
* This header contains any platform specific preprocessor adjustments that
* don't fit somewhere else better.
*/
#if defined(_WIN32) && !defined(NOMINMAX)
// don't define min and max macros that conflict with std::min and std::max
#define NOMINMAX
#endif
// Bump up the variadic parameter max for Visual Studio 2012
#if defined(_MSC_VER) && _MSC_VER == 1700
#define _VARIADIC_MAX 8
#endif
#endif // WEBSOCKETPP_COMMON_PLATFORMS_HPP

View File

@@ -1,82 +1,82 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP
#define WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 random header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_RANDOM_DEVICE_
#ifndef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
#define _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
#endif
#endif
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
// the use of C++11 random header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_
#ifndef _WEBSOCKETPP_CPP11_MEMORY_
#define _WEBSOCKETPP_CPP11_MEMORY_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
#include <random>
#else
#include <boost/version.hpp>
#if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 46
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/random_device.hpp>
#elif (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) >= 43
#include <boost/nondet_random.hpp>
#else
// TODO: static_assert(false, "Could not find a suitable random_device")
#endif
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
using std::random_device;
using std::uniform_int_distribution;
#else
using boost::random::random_device;
using boost::random::uniform_int_distribution;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP
#define WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 random header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_RANDOM_DEVICE_
#ifndef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
#define _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
#endif
#endif
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
// the use of C++11 random header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_
#ifndef _WEBSOCKETPP_CPP11_MEMORY_
#define _WEBSOCKETPP_CPP11_MEMORY_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
#include <random>
#else
#include <boost/version.hpp>
#if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 46
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/random_device.hpp>
#elif (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) >= 43
#include <boost/nondet_random.hpp>
#else
// TODO: static_assert(false, "Could not find a suitable random_device")
#endif
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
using std::random_device;
using std::uniform_int_distribution;
#else
using boost::random::random_device;
using boost::random::uniform_int_distribution;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP

View File

@@ -1,59 +1,59 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_REGEX_HPP
#define WEBSOCKETPP_COMMON_REGEX_HPP
#if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_REGEX_
#ifndef _WEBSOCKETPP_CPP11_REGEX_
#define _WEBSOCKETPP_CPP11_REGEX_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_REGEX_
#include <regex>
#else
#include <boost/regex.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_REGEX_
using std::cmatch;
using std::regex;
using std::regex_match;
#else
using boost::cmatch;
using boost::regex;
using boost::regex_match;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_REGEX_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_REGEX_HPP
#define WEBSOCKETPP_COMMON_REGEX_HPP
#if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_REGEX_
#ifndef _WEBSOCKETPP_CPP11_REGEX_
#define _WEBSOCKETPP_CPP11_REGEX_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_REGEX_
#include <regex>
#else
#include <boost/regex.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_REGEX_
using std::cmatch;
using std::regex;
using std::regex_match;
#else
using boost::cmatch;
using boost::regex;
using boost::regex_match;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_REGEX_HPP

View File

@@ -1,73 +1,73 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_STDINT_HPP
#define WEBSOCKETPP_COMMON_STDINT_HPP
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
#endif
#if defined (_WIN32) && defined (_MSC_VER) && (_MSC_VER < 1600)
#include <boost/cstdint.hpp>
using boost::int8_t;
using boost::int_least8_t;
using boost::int_fast8_t;
using boost::uint8_t;
using boost::uint_least8_t;
using boost::uint_fast8_t;
using boost::int16_t;
using boost::int_least16_t;
using boost::int_fast16_t;
using boost::uint16_t;
using boost::uint_least16_t;
using boost::uint_fast16_t;
using boost::int32_t;
using boost::int_least32_t;
using boost::int_fast32_t;
using boost::uint32_t;
using boost::uint_least32_t;
using boost::uint_fast32_t;
#ifndef BOOST_NO_INT64_T
using boost::int64_t;
using boost::int_least64_t;
using boost::int_fast64_t;
using boost::uint64_t;
using boost::uint_least64_t;
using boost::uint_fast64_t;
#endif
using boost::intmax_t;
using boost::uintmax_t;
#else
#include <stdint.h>
#endif
#endif // WEBSOCKETPP_COMMON_STDINT_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_STDINT_HPP
#define WEBSOCKETPP_COMMON_STDINT_HPP
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
#endif
#if defined (_WIN32) && defined (_MSC_VER) && (_MSC_VER < 1600)
#include <boost/cstdint.hpp>
using boost::int8_t;
using boost::int_least8_t;
using boost::int_fast8_t;
using boost::uint8_t;
using boost::uint_least8_t;
using boost::uint_fast8_t;
using boost::int16_t;
using boost::int_least16_t;
using boost::int_fast16_t;
using boost::uint16_t;
using boost::uint_least16_t;
using boost::uint_fast16_t;
using boost::int32_t;
using boost::int_least32_t;
using boost::int_fast32_t;
using boost::uint32_t;
using boost::uint_least32_t;
using boost::uint_fast32_t;
#ifndef BOOST_NO_INT64_T
using boost::int64_t;
using boost::int_least64_t;
using boost::int_fast64_t;
using boost::uint64_t;
using boost::uint_least64_t;
using boost::uint_fast64_t;
#endif
using boost::intmax_t;
using boost::uintmax_t;
#else
#include <stdint.h>
#endif
#endif // WEBSOCKETPP_COMMON_STDINT_HPP

View File

@@ -1,84 +1,84 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP
#define WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 system_error header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_SYSTEM_ERROR_
#ifndef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#endif
#endif
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
// the use of C++11 system_error header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_SYSTEM_ERROR_
#ifndef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#include <system_error>
#else
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
using std::errc;
using std::error_code;
using std::error_category;
using std::error_condition;
using std::system_error;
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ namespace std {
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ }
#else
namespace errc = boost::system::errc;
using boost::system::error_code;
using boost::system::error_category;
using boost::system::error_condition;
using boost::system::system_error;
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ namespace boost { namespace system {
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ }}
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP
#define WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 system_error header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_SYSTEM_ERROR_
#ifndef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#endif
#endif
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
// the use of C++11 system_error header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_SYSTEM_ERROR_
#ifndef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#include <system_error>
#else
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
using std::errc;
using std::error_code;
using std::error_category;
using std::error_condition;
using std::system_error;
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ namespace std {
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ }
#else
namespace errc = boost::system::errc;
using boost::system::error_code;
using boost::system::error_category;
using boost::system::error_condition;
using boost::system::system_error;
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ namespace boost { namespace system {
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ }}
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP

View File

@@ -1,88 +1,88 @@
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_THREAD_HPP
#define WEBSOCKETPP_COMMON_THREAD_HPP
#include <websocketpp/common/cpp11.hpp>
// If we autodetect C++11 and haven't been explicitly instructed to not use
// C++11 threads, then set the defines that instructs the rest of this header
// to use C++11 <thread> and <mutex>
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_THREAD_
// MinGW by default does not support C++11 thread/mutex so even if the
// internal check for C++11 passes, ignore it if we are on MinGW
#if (!defined(__MINGW32__) && !defined(__MINGW64__))
#ifndef _WEBSOCKETPP_CPP11_THREAD_
#define _WEBSOCKETPP_CPP11_THREAD_
#endif
#endif
#endif
// If we're on Visual Studio 2013 or higher and haven't explicitly disabled
// the use of C++11 thread header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1800 && !defined _WEBSOCKETPP_NO_CPP11_THREAD_
#ifndef _WEBSOCKETPP_CPP11_THREAD_
#define _WEBSOCKETPP_CPP11_THREAD_
#endif
#endif
#if defined(_WEBSOCKETPP_MINGW_THREAD_)
#include <mingw-threads/mingw.thread.h>
#include <mingw-threads/mingw.mutex.h>
#include <mingw-threads/mingw.condition_variable.h>
#elif defined(_WEBSOCKETPP_CPP11_THREAD_)
#include <thread>
#include <mutex>
#include <condition_variable>
#else
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#endif
namespace websocketpp {
namespace lib {
#if defined(_WEBSOCKETPP_CPP11_THREAD_) || defined(_WEBSOCKETPP_MINGW_THREAD_)
using std::mutex;
using std::lock_guard;
using std::thread;
using std::unique_lock;
using std::condition_variable;
#else
using boost::mutex;
using boost::lock_guard;
using boost::thread;
using boost::unique_lock;
using boost::condition_variable;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_THREAD_HPP
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_THREAD_HPP
#define WEBSOCKETPP_COMMON_THREAD_HPP
#include <websocketpp/common/cpp11.hpp>
// If we autodetect C++11 and haven't been explicitly instructed to not use
// C++11 threads, then set the defines that instructs the rest of this header
// to use C++11 <thread> and <mutex>
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_THREAD_
// MinGW by default does not support C++11 thread/mutex so even if the
// internal check for C++11 passes, ignore it if we are on MinGW
#if (!defined(__MINGW32__) && !defined(__MINGW64__))
#ifndef _WEBSOCKETPP_CPP11_THREAD_
#define _WEBSOCKETPP_CPP11_THREAD_
#endif
#endif
#endif
// If we're on Visual Studio 2013 or higher and haven't explicitly disabled
// the use of C++11 thread header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1800 && !defined _WEBSOCKETPP_NO_CPP11_THREAD_
#ifndef _WEBSOCKETPP_CPP11_THREAD_
#define _WEBSOCKETPP_CPP11_THREAD_
#endif
#endif
#if defined(_WEBSOCKETPP_MINGW_THREAD_)
#include <mingw-threads/mingw.thread.h>
#include <mingw-threads/mingw.mutex.h>
#include <mingw-threads/mingw.condition_variable.h>
#elif defined(_WEBSOCKETPP_CPP11_THREAD_)
#include <thread>
#include <mutex>
#include <condition_variable>
#else
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#endif
namespace websocketpp {
namespace lib {
#if defined(_WEBSOCKETPP_CPP11_THREAD_) || defined(_WEBSOCKETPP_MINGW_THREAD_)
using std::mutex;
using std::lock_guard;
using std::thread;
using std::unique_lock;
using std::condition_variable;
#else
using boost::mutex;
using boost::lock_guard;
using boost::thread;
using boost::unique_lock;
using boost::condition_variable;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_THREAD_HPP

View File

@@ -1,56 +1,56 @@
/*
* 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 <ctime>
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(__MINGW32__) || defined(__MINGW64__))
memcpy(&tm_snapshot, ::localtime(&time), sizeof(std::tm));
#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
localtime_s(&tm_snapshot, &time);
#else
localtime_r(&time, &tm_snapshot); // POSIX
#endif
return tm_snapshot;
}
} // lib
} // websocketpp
#endif // WEBSOCKETPP_COMMON_TIME_HPP
/*
* 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 <ctime>
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(__MINGW32__) || defined(__MINGW64__))
memcpy(&tm_snapshot, ::localtime(&time), sizeof(std::tm));
#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
localtime_s(&tm_snapshot, &time);
#else
localtime_r(&time, &tm_snapshot); // POSIX
#endif
return tm_snapshot;
}
} // lib
} // websocketpp
#endif // WEBSOCKETPP_COMMON_TIME_HPP

View File

@@ -1,65 +1,65 @@
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP
#define WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 functional header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_TYPE_TRAITS_
#ifndef _WEBSOCKETPP_CPP11_TYPE_TRAITS_
#define _WEBSOCKETPP_CPP11_TYPE_TRAITS_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_TYPE_TRAITS_
#include <type_traits>
#else
#include <boost/aligned_storage.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_TYPE_TRAITS_
using std::aligned_storage;
using std::is_same;
#else
using boost::aligned_storage;
using boost::is_same;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP
#define WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP
#include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't
// explicitly disabled the use of C++11 functional header, then prefer it to
// boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_TYPE_TRAITS_
#ifndef _WEBSOCKETPP_CPP11_TYPE_TRAITS_
#define _WEBSOCKETPP_CPP11_TYPE_TRAITS_
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_TYPE_TRAITS_
#include <type_traits>
#else
#include <boost/aligned_storage.hpp>
#endif
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_TYPE_TRAITS_
using std::aligned_storage;
using std::is_same;
#else
using boost::aligned_storage;
using boost::is_same;
#endif
} // namespace lib
} // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP

View File

@@ -1,46 +1,46 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONCURRENCY_BASIC_HPP
#define WEBSOCKETPP_CONCURRENCY_BASIC_HPP
#include <websocketpp/common/thread.hpp>
namespace websocketpp {
namespace concurrency {
/// Concurrency policy that uses std::mutex / boost::mutex
class basic {
public:
typedef lib::mutex mutex_type;
typedef lib::lock_guard<mutex_type> scoped_lock_type;
};
} // namespace concurrency
} // namespace websocketpp
#endif // WEBSOCKETPP_CONCURRENCY_BASIC_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONCURRENCY_BASIC_HPP
#define WEBSOCKETPP_CONCURRENCY_BASIC_HPP
#include <websocketpp/common/thread.hpp>
namespace websocketpp {
namespace concurrency {
/// Concurrency policy that uses std::mutex / boost::mutex
class basic {
public:
typedef lib::mutex mutex_type;
typedef lib::lock_guard<mutex_type> scoped_lock_type;
};
} // namespace concurrency
} // namespace websocketpp
#endif // WEBSOCKETPP_CONCURRENCY_BASIC_HPP

View File

@@ -1,80 +1,80 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONCURRENCY_NONE_HPP
#define WEBSOCKETPP_CONCURRENCY_NONE_HPP
namespace websocketpp {
/// Concurrency handling support
namespace concurrency {
/// Implementation for no-op locking primitives
namespace none_impl {
/// A fake mutex implementation that does nothing
class fake_mutex {
public:
fake_mutex() {}
~fake_mutex() {}
};
/// A fake lock guard implementation that does nothing
class fake_lock_guard {
public:
explicit fake_lock_guard(fake_mutex) {}
~fake_lock_guard() {}
};
} // namespace none_impl
/// Stub concurrency policy that implements the interface using no-ops.
/**
* This policy documents the concurrency policy interface using no-ops. It can
* be used as a reference or base for building a new concurrency policy. It can
* also be used as is to disable all locking for endpoints used in purely single
* threaded programs.
*/
class none {
public:
/// The type of a mutex primitive
/**
* std::mutex is an example.
*/
typedef none_impl::fake_mutex mutex_type;
/// The type of a scoped/RAII lock primitive.
/**
* The scoped lock constructor should take a mutex_type as a parameter,
* acquire that lock, and release it in its destructor. std::lock_guard is
* an example.
*/
typedef none_impl::fake_lock_guard scoped_lock_type;
};
} // namespace concurrency
} // namespace websocketpp
#endif // WEBSOCKETPP_CONCURRENCY_ASYNC_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONCURRENCY_NONE_HPP
#define WEBSOCKETPP_CONCURRENCY_NONE_HPP
namespace websocketpp {
/// Concurrency handling support
namespace concurrency {
/// Implementation for no-op locking primitives
namespace none_impl {
/// A fake mutex implementation that does nothing
class fake_mutex {
public:
fake_mutex() {}
~fake_mutex() {}
};
/// A fake lock guard implementation that does nothing
class fake_lock_guard {
public:
explicit fake_lock_guard(fake_mutex) {}
~fake_lock_guard() {}
};
} // namespace none_impl
/// Stub concurrency policy that implements the interface using no-ops.
/**
* This policy documents the concurrency policy interface using no-ops. It can
* be used as a reference or base for building a new concurrency policy. It can
* also be used as is to disable all locking for endpoints used in purely single
* threaded programs.
*/
class none {
public:
/// The type of a mutex primitive
/**
* std::mutex is an example.
*/
typedef none_impl::fake_mutex mutex_type;
/// The type of a scoped/RAII lock primitive.
/**
* The scoped lock constructor should take a mutex_type as a parameter,
* acquire that lock, and release it in its destructor. std::lock_guard is
* an example.
*/
typedef none_impl::fake_lock_guard scoped_lock_type;
};
} // namespace concurrency
} // namespace websocketpp
#endif // WEBSOCKETPP_CONCURRENCY_ASYNC_HPP

View File

@@ -1,77 +1,77 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_TLS_HPP
#define WEBSOCKETPP_CONFIG_ASIO_TLS_HPP
#include <websocketpp/config/core.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
#include <websocketpp/transport/asio/security/tls.hpp>
// Pull in non-tls config
#include <websocketpp/config/asio_no_tls.hpp>
// Define TLS config
namespace websocketpp {
namespace config {
/// Server config with asio transport and TLS enabled
struct asio_tls : public core {
typedef asio_tls type;
typedef core base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_TLS_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_TLS_HPP
#define WEBSOCKETPP_CONFIG_ASIO_TLS_HPP
#include <websocketpp/config/core.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
#include <websocketpp/transport/asio/security/tls.hpp>
// Pull in non-tls config
#include <websocketpp/config/asio_no_tls.hpp>
// Define TLS config
namespace websocketpp {
namespace config {
/// Server config with asio transport and TLS enabled
struct asio_tls : public core {
typedef asio_tls type;
typedef core base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_TLS_HPP

View File

@@ -1,77 +1,77 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP
#define WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP
#include <websocketpp/config/core_client.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
#include <websocketpp/transport/asio/security/tls.hpp>
// Pull in non-tls config
#include <websocketpp/config/asio_no_tls_client.hpp>
// Define TLS config
namespace websocketpp {
namespace config {
/// Client config with asio transport and TLS enabled
struct asio_tls_client : public core_client {
typedef asio_tls_client type;
typedef core_client base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP
#define WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP
#include <websocketpp/config/core_client.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
#include <websocketpp/transport/asio/security/tls.hpp>
// Pull in non-tls config
#include <websocketpp/config/asio_no_tls_client.hpp>
// Define TLS config
namespace websocketpp {
namespace config {
/// Client config with asio transport and TLS enabled
struct asio_tls_client : public core_client {
typedef asio_tls_client type;
typedef core_client base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP

View File

@@ -1,73 +1,73 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_HPP
#define WEBSOCKETPP_CONFIG_ASIO_HPP
#include <websocketpp/config/core.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
namespace websocketpp {
namespace config {
/// Server config with asio transport and TLS disabled
struct asio : public core {
typedef asio type;
typedef core base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::basic_socket::endpoint
socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_HPP
#define WEBSOCKETPP_CONFIG_ASIO_HPP
#include <websocketpp/config/core.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
namespace websocketpp {
namespace config {
/// Server config with asio transport and TLS disabled
struct asio : public core {
typedef asio type;
typedef core base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::basic_socket::endpoint
socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_HPP

View File

@@ -1,73 +1,73 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_CLIENT_HPP
#define WEBSOCKETPP_CONFIG_ASIO_CLIENT_HPP
#include <websocketpp/config/core_client.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
namespace websocketpp {
namespace config {
/// Client config with asio transport and TLS disabled
struct asio_client : public core_client {
typedef asio_client type;
typedef core_client base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::basic_socket::endpoint
socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_CLIENT_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_CLIENT_HPP
#define WEBSOCKETPP_CONFIG_ASIO_CLIENT_HPP
#include <websocketpp/config/core_client.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
namespace websocketpp {
namespace config {
/// Client config with asio transport and TLS disabled
struct asio_client : public core_client {
typedef asio_client type;
typedef core_client base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::basic_socket::endpoint
socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_CLIENT_HPP

View File

@@ -1,72 +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.
*
*/
// This header defines WebSocket++ macros for C++11 compatibility based on the
// Boost.Config library. This will correctly configure most target platforms
// simply by including this header before any other WebSocket++ header.
#ifndef WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
#define WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
#include <boost/config.hpp>
// _WEBSOCKETPP_CPP11_MEMORY_ and _WEBSOCKETPP_CPP11_FUNCTIONAL_ presently
// only work if either both or neither is defined.
#if !defined BOOST_NO_CXX11_SMART_PTR && !defined BOOST_NO_CXX11_HDR_FUNCTIONAL
#define _WEBSOCKETPP_CPP11_MEMORY_
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
#endif
#ifdef BOOST_ASIO_HAS_STD_CHRONO
#define _WEBSOCKETPP_CPP11_CHRONO_
#endif
#ifndef BOOST_NO_CXX11_HDR_RANDOM
#define _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
#endif
#ifndef BOOST_NO_CXX11_HDR_REGEX
#define _WEBSOCKETPP_CPP11_REGEX_
#endif
#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR
#define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#endif
#ifndef BOOST_NO_CXX11_HDR_THREAD
#define _WEBSOCKETPP_CPP11_THREAD_
#endif
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#define _WEBSOCKETPP_INITIALIZER_LISTS_
#endif
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ BOOST_NOEXCEPT
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ BOOST_CONSTEXPR
// TODO: nullptr support
#endif // WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// This header defines WebSocket++ macros for C++11 compatibility based on the
// Boost.Config library. This will correctly configure most target platforms
// simply by including this header before any other WebSocket++ header.
#ifndef WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
#define WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
#include <boost/config.hpp>
// _WEBSOCKETPP_CPP11_MEMORY_ and _WEBSOCKETPP_CPP11_FUNCTIONAL_ presently
// only work if either both or neither is defined.
#if !defined BOOST_NO_CXX11_SMART_PTR && !defined BOOST_NO_CXX11_HDR_FUNCTIONAL
#define _WEBSOCKETPP_CPP11_MEMORY_
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
#endif
#ifdef BOOST_ASIO_HAS_STD_CHRONO
#define _WEBSOCKETPP_CPP11_CHRONO_
#endif
#ifndef BOOST_NO_CXX11_HDR_RANDOM
#define _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
#endif
#ifndef BOOST_NO_CXX11_HDR_REGEX
#define _WEBSOCKETPP_CPP11_REGEX_
#endif
#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR
#define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#endif
#ifndef BOOST_NO_CXX11_HDR_THREAD
#define _WEBSOCKETPP_CPP11_THREAD_
#endif
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#define _WEBSOCKETPP_INITIALIZER_LISTS_
#endif
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ BOOST_NOEXCEPT
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ BOOST_CONSTEXPR
// TODO: nullptr support
#endif // WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP

View File

@@ -1,297 +1,297 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_CORE_HPP
#define WEBSOCKETPP_CONFIG_CORE_HPP
// Non-Policy common stuff
#include <websocketpp/common/platforms.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp>
// Concurrency
#include <websocketpp/concurrency/basic.hpp>
// Transport
#include <websocketpp/transport/iostream/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/basic.hpp>
#include <websocketpp/logger/levels.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 iostream transport
struct core {
typedef core type;
// Concurrency policy
typedef websocketpp::concurrency::basic concurrency_type;
// HTTP Parser Policies
typedef http::parser::request request_type;
typedef http::parser::response response_type;
// Message Policies
typedef message_buffer::message<message_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::basic<concurrency_type,
websocketpp::log::elevel> elog_type;
typedef websocketpp::log::basic<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::iostream::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::all ^ websocketpp::log::elevel::devel;
/// Default static access logging channels
/**
* Which access logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely
* code to test whether or not to print out log messages on a certain
* channel
*
* Default is all except for development/debug level access messages
*/
static const websocketpp::log::level alog_level =
websocketpp::log::alevel::all ^ websocketpp::log::alevel::devel;
/// Size of the per-connection read buffer
/**
* Each connection has an internal buffer of this size. A larger value will
* result in fewer trips through the library and less CPU overhead at the
* expense of increased memory usage per connection.
*
* If your application primarily deals in very large messages you may want
* to try setting this value higher.
*
* If your application has a lot of connections or primarily deals in small
* messages you may want to try setting this smaller.
*/
static const size_t connection_read_buffer_size = 16384;
/// Drop connections immediately on protocol error.
/**
* Drop connections on protocol error rather than sending a close frame.
* Off by default. This may result in legit messages near the error being
* dropped as well. It may free up resources otherwise spent dealing with
* misbehaving clients.
*/
static const bool drop_on_protocol_error = false;
/// Suppresses the return of detailed connection close information
/**
* Silence close suppresses the return of detailed connection close
* information during the closing handshake. This information is useful
* for debugging and presenting useful errors to end users but may be
* undesirable for security reasons in some production environments.
* Close reasons could be used by an attacker to confirm that the endpoint
* is out of resources or be used to identify the WebSocket implementation
* in use.
*
* Note: this will suppress *all* close codes, including those explicitly
* sent by local applications.
*/
static const bool silent_close = false;
/// Default maximum message size
/**
* Default value for the processor's maximum message size. Maximum message size
* determines the point at which the library will fail a connection with the
* message_too_big protocol error.
*
* The default is 32MB
*
* @since 0.3.0
*/
static const size_t max_message_size = 32000000;
/// Default maximum http body size
/**
* Default value for the http parser's maximum body size. Maximum body size
* determines the point at which the library will abort reading an HTTP
* connection with the 413/request entity too large error.
*
* The default is 32MB
*
* @since 0.5.0
*/
static const size_t max_http_body_size = 32000000;
/// Global flag for enabling/disabling extensions
static const bool enable_extensions = true;
/// Extension specific settings:
/// permessage_compress extension
struct permessage_deflate_config {
typedef core::request_type request_type;
/// If the remote endpoint requests that we reset the compression
/// context after each message should we honor the request?
static const bool allow_disabling_context_takeover = true;
/// If the remote endpoint requests that we reduce the size of the
/// LZ77 sliding window size this is the lowest value that will be
/// allowed. Values range from 8 to 15. A value of 8 means we will
/// allow any possible window size. A value of 15 means do not allow
/// negotiation of the window size (ie require the default).
static const uint8_t minimum_outgoing_window_bits = 8;
};
typedef 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_CORE_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_CORE_HPP
#define WEBSOCKETPP_CONFIG_CORE_HPP
// Non-Policy common stuff
#include <websocketpp/common/platforms.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp>
// Concurrency
#include <websocketpp/concurrency/basic.hpp>
// Transport
#include <websocketpp/transport/iostream/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/basic.hpp>
#include <websocketpp/logger/levels.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 iostream transport
struct core {
typedef core type;
// Concurrency policy
typedef websocketpp::concurrency::basic concurrency_type;
// HTTP Parser Policies
typedef http::parser::request request_type;
typedef http::parser::response response_type;
// Message Policies
typedef message_buffer::message<message_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::basic<concurrency_type,
websocketpp::log::elevel> elog_type;
typedef websocketpp::log::basic<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::iostream::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::all ^ websocketpp::log::elevel::devel;
/// Default static access logging channels
/**
* Which access logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely
* code to test whether or not to print out log messages on a certain
* channel
*
* Default is all except for development/debug level access messages
*/
static const websocketpp::log::level alog_level =
websocketpp::log::alevel::all ^ websocketpp::log::alevel::devel;
/// Size of the per-connection read buffer
/**
* Each connection has an internal buffer of this size. A larger value will
* result in fewer trips through the library and less CPU overhead at the
* expense of increased memory usage per connection.
*
* If your application primarily deals in very large messages you may want
* to try setting this value higher.
*
* If your application has a lot of connections or primarily deals in small
* messages you may want to try setting this smaller.
*/
static const size_t connection_read_buffer_size = 16384;
/// Drop connections immediately on protocol error.
/**
* Drop connections on protocol error rather than sending a close frame.
* Off by default. This may result in legit messages near the error being
* dropped as well. It may free up resources otherwise spent dealing with
* misbehaving clients.
*/
static const bool drop_on_protocol_error = false;
/// Suppresses the return of detailed connection close information
/**
* Silence close suppresses the return of detailed connection close
* information during the closing handshake. This information is useful
* for debugging and presenting useful errors to end users but may be
* undesirable for security reasons in some production environments.
* Close reasons could be used by an attacker to confirm that the endpoint
* is out of resources or be used to identify the WebSocket implementation
* in use.
*
* Note: this will suppress *all* close codes, including those explicitly
* sent by local applications.
*/
static const bool silent_close = false;
/// Default maximum message size
/**
* Default value for the processor's maximum message size. Maximum message size
* determines the point at which the library will fail a connection with the
* message_too_big protocol error.
*
* The default is 32MB
*
* @since 0.3.0
*/
static const size_t max_message_size = 32000000;
/// Default maximum http body size
/**
* Default value for the http parser's maximum body size. Maximum body size
* determines the point at which the library will abort reading an HTTP
* connection with the 413/request entity too large error.
*
* The default is 32MB
*
* @since 0.5.0
*/
static const size_t max_http_body_size = 32000000;
/// Global flag for enabling/disabling extensions
static const bool enable_extensions = true;
/// Extension specific settings:
/// permessage_compress extension
struct permessage_deflate_config {
typedef core::request_type request_type;
/// If the remote endpoint requests that we reset the compression
/// context after each message should we honor the request?
static const bool allow_disabling_context_takeover = true;
/// If the remote endpoint requests that we reduce the size of the
/// LZ77 sliding window size this is the lowest value that will be
/// allowed. Values range from 8 to 15. A value of 8 means we will
/// allow any possible window size. A value of 15 means do not allow
/// negotiation of the window size (ie require the default).
static const uint8_t minimum_outgoing_window_bits = 8;
};
typedef 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_CORE_HPP

View File

@@ -1,294 +1,294 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_CORE_CLIENT_HPP
#define WEBSOCKETPP_CONFIG_CORE_CLIENT_HPP
// Non-Policy common stuff
#include <websocketpp/common/platforms.hpp>
#include <websocketpp/common/cpp11.hpp>
#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>
// 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/basic.hpp>
// RNG
#include <websocketpp/random/random_device.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 {
/// Client config with iostream transport
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;
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::basic<concurrency_type,
websocketpp::log::elevel> elog_type;
typedef websocketpp::log::basic<concurrency_type,
websocketpp::log::alevel> alog_type;
/// RNG policies
typedef websocketpp::random::random_device::int_generator<uint32_t,
concurrency_type> 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::iostream::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::all ^ websocketpp::log::elevel::devel;
/// Default static access logging channels
/**
* Which access logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely
* code to test whether or not to print out log messages on a certain
* channel
*
* Default is all except for development/debug level access messages
*/
static const websocketpp::log::level alog_level =
websocketpp::log::alevel::all ^ websocketpp::log::alevel::devel;
///
static const size_t connection_read_buffer_size = 16384;
/// Drop connections immediately on protocol error.
/**
* Drop connections on protocol error rather than sending a close frame.
* Off by default. This may result in legit messages near the error being
* dropped as well. It may free up resources otherwise spent dealing with
* misbehaving clients.
*/
static const bool drop_on_protocol_error = false;
/// Suppresses the return of detailed connection close information
/**
* Silence close suppresses the return of detailed connection close
* information during the closing handshake. This information is useful
* for debugging and presenting useful errors to end users but may be
* undesirable for security reasons in some production environments.
* Close reasons could be used by an attacker to confirm that the endpoint
* is out of resources or be used to identify the WebSocket implementation
* in use.
*
* Note: this will suppress *all* close codes, including those explicitly
* sent by local applications.
*/
static const bool silent_close = false;
/// Default maximum message size
/**
* Default value for the processor's maximum message size. Maximum message size
* determines the point at which the library will fail a connection with the
* message_too_big protocol error.
*
* The default is 32MB
*
* @since 0.3.0
*/
static const size_t max_message_size = 32000000;
/// Default maximum http body size
/**
* Default value for the http parser's maximum body size. Maximum body size
* determines the point at which the library will abort reading an HTTP
* connection with the 413/request entity too large error.
*
* The default is 32MB
*
* @since 0.5.0
*/
static const size_t max_http_body_size = 32000000;
/// Global flag for enabling/disabling extensions
static const bool enable_extensions = true;
/// Extension specific settings:
/// permessage_deflate extension
struct permessage_deflate_config {
typedef core_client::request_type request_type;
/// If the remote endpoint requests that we reset the compression
/// context after each message should we honor the request?
static const bool allow_disabling_context_takeover = true;
/// If the remote endpoint requests that we reduce the size of the
/// LZ77 sliding window size this is the lowest value that will be
/// allowed. Values range from 8 to 15. A value of 8 means we will
/// allow any possible window size. A value of 15 means do not allow
/// negotiation of the window size (ie require the default).
static const uint8_t minimum_outgoing_window_bits = 8;
};
typedef websocketpp::extensions::permessage_deflate::disabled
<permessage_deflate_config> permessage_deflate_type;
/// Autonegotiate permessage-compress
/**
* Automatically enables the permessage-compress extension.
*
* For clients this results in a permessage-compress extension request being
* sent with every request rather than requiring it to be requested manually
*
* For servers this results in accepting the first set of extension settings
* requested by the client that we understand being used. The alternative is
* requiring the extension to be manually negotiated in `validate`. With
* auto-negotiate on, you may still override the auto-negotiate manually if
* needed.
*/
//static const bool autonegotiate_compression = false;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_CORE_CLIENT_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_CORE_CLIENT_HPP
#define WEBSOCKETPP_CONFIG_CORE_CLIENT_HPP
// Non-Policy common stuff
#include <websocketpp/common/platforms.hpp>
#include <websocketpp/common/cpp11.hpp>
#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>
// 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/basic.hpp>
// RNG
#include <websocketpp/random/random_device.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 {
/// Client config with iostream transport
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;
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::basic<concurrency_type,
websocketpp::log::elevel> elog_type;
typedef websocketpp::log::basic<concurrency_type,
websocketpp::log::alevel> alog_type;
/// RNG policies
typedef websocketpp::random::random_device::int_generator<uint32_t,
concurrency_type> 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::iostream::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::all ^ websocketpp::log::elevel::devel;
/// Default static access logging channels
/**
* Which access logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely
* code to test whether or not to print out log messages on a certain
* channel
*
* Default is all except for development/debug level access messages
*/
static const websocketpp::log::level alog_level =
websocketpp::log::alevel::all ^ websocketpp::log::alevel::devel;
///
static const size_t connection_read_buffer_size = 16384;
/// Drop connections immediately on protocol error.
/**
* Drop connections on protocol error rather than sending a close frame.
* Off by default. This may result in legit messages near the error being
* dropped as well. It may free up resources otherwise spent dealing with
* misbehaving clients.
*/
static const bool drop_on_protocol_error = false;
/// Suppresses the return of detailed connection close information
/**
* Silence close suppresses the return of detailed connection close
* information during the closing handshake. This information is useful
* for debugging and presenting useful errors to end users but may be
* undesirable for security reasons in some production environments.
* Close reasons could be used by an attacker to confirm that the endpoint
* is out of resources or be used to identify the WebSocket implementation
* in use.
*
* Note: this will suppress *all* close codes, including those explicitly
* sent by local applications.
*/
static const bool silent_close = false;
/// Default maximum message size
/**
* Default value for the processor's maximum message size. Maximum message size
* determines the point at which the library will fail a connection with the
* message_too_big protocol error.
*
* The default is 32MB
*
* @since 0.3.0
*/
static const size_t max_message_size = 32000000;
/// Default maximum http body size
/**
* Default value for the http parser's maximum body size. Maximum body size
* determines the point at which the library will abort reading an HTTP
* connection with the 413/request entity too large error.
*
* The default is 32MB
*
* @since 0.5.0
*/
static const size_t max_http_body_size = 32000000;
/// Global flag for enabling/disabling extensions
static const bool enable_extensions = true;
/// Extension specific settings:
/// permessage_deflate extension
struct permessage_deflate_config {
typedef core_client::request_type request_type;
/// If the remote endpoint requests that we reset the compression
/// context after each message should we honor the request?
static const bool allow_disabling_context_takeover = true;
/// If the remote endpoint requests that we reduce the size of the
/// LZ77 sliding window size this is the lowest value that will be
/// allowed. Values range from 8 to 15. A value of 8 means we will
/// allow any possible window size. A value of 15 means do not allow
/// negotiation of the window size (ie require the default).
static const uint8_t minimum_outgoing_window_bits = 8;
};
typedef websocketpp::extensions::permessage_deflate::disabled
<permessage_deflate_config> permessage_deflate_type;
/// Autonegotiate permessage-compress
/**
* Automatically enables the permessage-compress extension.
*
* For clients this results in a permessage-compress extension request being
* sent with every request rather than requiring it to be requested manually
*
* For servers this results in accepting the first set of extension settings
* requested by the client that we understand being used. The alternative is
* requiring the extension to be manually negotiated in `validate`. With
* auto-negotiate on, you may still override the auto-negotiate manually if
* needed.
*/
//static const bool autonegotiate_compression = false;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_CORE_CLIENT_HPP

View File

@@ -1,286 +1,286 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_DEBUG_HPP
#define WEBSOCKETPP_CONFIG_DEBUG_HPP
// Non-Policy common stuff
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp>
// Concurrency
#include <websocketpp/concurrency/basic.hpp>
// Transport
#include <websocketpp/transport/iostream/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/basic.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 {
/// Client/Server debug config with iostream transport
struct debug_core {
typedef debug_core type;
// Concurrency policy
typedef websocketpp::concurrency::basic concurrency_type;
// HTTP Parser Policies
typedef http::parser::request request_type;
typedef http::parser::response response_type;
// Message Policies
typedef message_buffer::message<message_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::basic<concurrency_type,
websocketpp::log::elevel> elog_type;
typedef websocketpp::log::basic<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::iostream::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::all;
/// Default static access logging channels
/**
* Which access logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely
* code to test whether or not to print out log messages on a certain
* channel
*
* Default is all except for development/debug level access messages
*/
static const websocketpp::log::level alog_level =
websocketpp::log::alevel::all;
///
static const size_t connection_read_buffer_size = 16384;
/// Drop connections immediately on protocol error.
/**
* Drop connections on protocol error rather than sending a close frame.
* Off by default. This may result in legit messages near the error being
* dropped as well. It may free up resources otherwise spent dealing with
* misbehaving clients.
*/
static const bool drop_on_protocol_error = false;
/// Suppresses the return of detailed connection close information
/**
* Silence close suppresses the return of detailed connection close
* information during the closing handshake. This information is useful
* for debugging and presenting useful errors to end users but may be
* undesirable for security reasons in some production environments.
* Close reasons could be used by an attacker to confirm that the endpoint
* is out of resources or be used to identify the WebSocket implementation
* in use.
*
* Note: this will suppress *all* close codes, including those explicitly
* sent by local applications.
*/
static const bool silent_close = false;
/// Default maximum message size
/**
* Default value for the processor's maximum message size. Maximum message size
* determines the point at which the library will fail a connection with the
* message_too_big protocol error.
*
* The default is 32MB
*
* @since 0.3.0
*/
static const size_t max_message_size = 32000000;
/// Default maximum http body size
/**
* Default value for the http parser's maximum body size. Maximum body size
* determines the point at which the library will abort reading an HTTP
* connection with the 413/request entity too large error.
*
* The default is 32MB
*
* @since 0.5.0
*/
static const size_t max_http_body_size = 32000000;
/// Global flag for enabling/disabling extensions
static const bool enable_extensions = true;
/// Extension specific settings:
/// permessage_compress extension
struct permessage_deflate_config {
typedef type::request_type request_type;
/// If the remote endpoint requests that we reset the compression
/// context after each message should we honor the request?
static const bool allow_disabling_context_takeover = true;
/// If the remote endpoint requests that we reduce the size of the
/// LZ77 sliding window size this is the lowest value that will be
/// allowed. Values range from 8 to 15. A value of 8 means we will
/// allow any possible window size. A value of 15 means do not allow
/// negotiation of the window size (ie require the default).
static const uint8_t minimum_outgoing_window_bits = 8;
};
typedef 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_CORE_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_DEBUG_HPP
#define WEBSOCKETPP_CONFIG_DEBUG_HPP
// Non-Policy common stuff
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp>
// Concurrency
#include <websocketpp/concurrency/basic.hpp>
// Transport
#include <websocketpp/transport/iostream/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/basic.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 {
/// Client/Server debug config with iostream transport
struct debug_core {
typedef debug_core type;
// Concurrency policy
typedef websocketpp::concurrency::basic concurrency_type;
// HTTP Parser Policies
typedef http::parser::request request_type;
typedef http::parser::response response_type;
// Message Policies
typedef message_buffer::message<message_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::basic<concurrency_type,
websocketpp::log::elevel> elog_type;
typedef websocketpp::log::basic<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::iostream::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::all;
/// Default static access logging channels
/**
* Which access logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely
* code to test whether or not to print out log messages on a certain
* channel
*
* Default is all except for development/debug level access messages
*/
static const websocketpp::log::level alog_level =
websocketpp::log::alevel::all;
///
static const size_t connection_read_buffer_size = 16384;
/// Drop connections immediately on protocol error.
/**
* Drop connections on protocol error rather than sending a close frame.
* Off by default. This may result in legit messages near the error being
* dropped as well. It may free up resources otherwise spent dealing with
* misbehaving clients.
*/
static const bool drop_on_protocol_error = false;
/// Suppresses the return of detailed connection close information
/**
* Silence close suppresses the return of detailed connection close
* information during the closing handshake. This information is useful
* for debugging and presenting useful errors to end users but may be
* undesirable for security reasons in some production environments.
* Close reasons could be used by an attacker to confirm that the endpoint
* is out of resources or be used to identify the WebSocket implementation
* in use.
*
* Note: this will suppress *all* close codes, including those explicitly
* sent by local applications.
*/
static const bool silent_close = false;
/// Default maximum message size
/**
* Default value for the processor's maximum message size. Maximum message size
* determines the point at which the library will fail a connection with the
* message_too_big protocol error.
*
* The default is 32MB
*
* @since 0.3.0
*/
static const size_t max_message_size = 32000000;
/// Default maximum http body size
/**
* Default value for the http parser's maximum body size. Maximum body size
* determines the point at which the library will abort reading an HTTP
* connection with the 413/request entity too large error.
*
* The default is 32MB
*
* @since 0.5.0
*/
static const size_t max_http_body_size = 32000000;
/// Global flag for enabling/disabling extensions
static const bool enable_extensions = true;
/// Extension specific settings:
/// permessage_compress extension
struct permessage_deflate_config {
typedef type::request_type request_type;
/// If the remote endpoint requests that we reset the compression
/// context after each message should we honor the request?
static const bool allow_disabling_context_takeover = true;
/// If the remote endpoint requests that we reduce the size of the
/// LZ77 sliding window size this is the lowest value that will be
/// allowed. Values range from 8 to 15. A value of 8 means we will
/// allow any possible window size. A value of 15 means do not allow
/// negotiation of the window size (ie require the default).
static const uint8_t minimum_outgoing_window_bits = 8;
};
typedef 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_CORE_HPP

View File

@@ -1,77 +1,77 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_TLS_DEBUG_HPP
#define WEBSOCKETPP_CONFIG_ASIO_TLS_DEBUG_HPP
#include <websocketpp/config/debug.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
#include <websocketpp/transport/asio/security/tls.hpp>
// Pull in non-tls config
#include <websocketpp/config/debug_asio_no_tls.hpp>
// Define TLS config
namespace websocketpp {
namespace config {
/// Client/Server debug config with asio transport and TLS enabled
struct debug_asio_tls : public debug_core {
typedef debug_asio_tls type;
typedef debug_core base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_TLS_DEBUG_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_TLS_DEBUG_HPP
#define WEBSOCKETPP_CONFIG_ASIO_TLS_DEBUG_HPP
#include <websocketpp/config/debug.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
#include <websocketpp/transport/asio/security/tls.hpp>
// Pull in non-tls config
#include <websocketpp/config/debug_asio_no_tls.hpp>
// Define TLS config
namespace websocketpp {
namespace config {
/// Client/Server debug config with asio transport and TLS enabled
struct debug_asio_tls : public debug_core {
typedef debug_asio_tls type;
typedef debug_core base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_TLS_DEBUG_HPP

View File

@@ -1,73 +1,73 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_DEBUG_HPP
#define WEBSOCKETPP_CONFIG_ASIO_DEBUG_HPP
#include <websocketpp/config/debug.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
namespace websocketpp {
namespace config {
/// Client/Server debug config with asio transport and TLS disabled
struct debug_asio : public debug_core {
typedef debug_asio type;
typedef debug_core base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::basic_socket::endpoint
socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_DEBUG_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONFIG_ASIO_DEBUG_HPP
#define WEBSOCKETPP_CONFIG_ASIO_DEBUG_HPP
#include <websocketpp/config/debug.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
namespace websocketpp {
namespace config {
/// Client/Server debug config with asio transport and TLS disabled
struct debug_asio : public debug_core {
typedef debug_asio type;
typedef debug_core base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::basic_socket::endpoint
socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};
} // namespace config
} // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_ASIO_DEBUG_HPP

View File

@@ -1,72 +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
/*
* 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

View File

@@ -1,312 +1,312 @@
/*
* 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 elog_type;
typedef websocketpp::log::stub 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;
/// Default maximum http body size
/**
* Default value for the http parser's maximum body size. Maximum body size
* determines the point at which the library will abort reading an HTTP
* connection with the 413/request entity too large error.
*
* The default is 32MB
*
* @since 0.5.0
*/
static const size_t max_http_body_size = 32000000;
/// Global flag for enabling/disabling extensions
static const bool enable_extensions = true;
/// Extension specific settings:
/// permessage_compress extension
struct permessage_deflate_config {
typedef core::request_type request_type;
/// If the remote endpoint requests that we reset the compression
/// context after each message should we honor the request?
static const bool allow_disabling_context_takeover = true;
/// If the remote endpoint requests that we reduce the size of the
/// LZ77 sliding window size this is the lowest value that will be
/// allowed. Values range from 8 to 15. A value of 8 means we will
/// allow any possible window size. A value of 15 means do not allow
/// negotiation of the window size (ie require the default).
static const uint8_t minimum_outgoing_window_bits = 8;
};
typedef 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
/*
* 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 elog_type;
typedef websocketpp::log::stub 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;
/// Default maximum http body size
/**
* Default value for the http parser's maximum body size. Maximum body size
* determines the point at which the library will abort reading an HTTP
* connection with the 413/request entity too large error.
*
* The default is 32MB
*
* @since 0.5.0
*/
static const size_t max_http_body_size = 32000000;
/// Global flag for enabling/disabling extensions
static const bool enable_extensions = true;
/// Extension specific settings:
/// permessage_compress extension
struct permessage_deflate_config {
typedef core::request_type request_type;
/// If the remote endpoint requests that we reset the compression
/// context after each message should we honor the request?
static const bool allow_disabling_context_takeover = true;
/// If the remote endpoint requests that we reduce the size of the
/// LZ77 sliding window size this is the lowest value that will be
/// allowed. Values range from 8 to 15. A value of 8 means we will
/// allow any possible window size. A value of 15 means do not allow
/// negotiation of the window size (ie require the default).
static const uint8_t minimum_outgoing_window_bits = 8;
};
typedef 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

File diff suppressed because it is too large Load Diff

View File

@@ -1,38 +1,38 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONNECTION_BASE_HPP
#define WEBSOCKETPP_CONNECTION_BASE_HPP
namespace websocketpp {
/// Stub for user supplied base class.
class connection_base {};
} // namespace websocketpp
#endif // WEBSOCKETPP_CONNECTION_BASE_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CONNECTION_BASE_HPP
#define WEBSOCKETPP_CONNECTION_BASE_HPP
namespace websocketpp {
/// Stub for user supplied base class.
class connection_base {};
} // namespace websocketpp
#endif // WEBSOCKETPP_CONNECTION_BASE_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -1,38 +1,38 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_ENDPOINT_BASE_HPP
#define WEBSOCKETPP_ENDPOINT_BASE_HPP
namespace websocketpp {
/// Stub for user supplied base class.
class endpoint_base {};
} // namespace websocketpp
#endif // WEBSOCKETPP_ENDPOINT_BASE_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_ENDPOINT_BASE_HPP
#define WEBSOCKETPP_ENDPOINT_BASE_HPP
namespace websocketpp {
/// Stub for user supplied base class.
class endpoint_base {};
} // namespace websocketpp
#endif // WEBSOCKETPP_ENDPOINT_BASE_HPP

View File

@@ -1,277 +1,277 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_ERROR_HPP
#define WEBSOCKETPP_ERROR_HPP
#include <exception>
#include <string>
#include <utility>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/system_error.hpp>
namespace websocketpp {
/// Combination error code / string type for returning two values
typedef std::pair<lib::error_code,std::string> err_str_pair;
/// Library level error codes
namespace error {
enum value {
/// Catch-all library error
general = 1,
/// send attempted when endpoint write queue was full
send_queue_full,
/// Attempted an operation using a payload that was improperly formatted
/// ex: invalid UTF8 encoding on a text message.
payload_violation,
/// Attempted to open a secure connection with an insecure endpoint
endpoint_not_secure,
/// Attempted an operation that required an endpoint that is no longer
/// available. This is usually because the endpoint went out of scope
/// before a connection that it created.
endpoint_unavailable,
/// An invalid uri was supplied
invalid_uri,
/// The endpoint is out of outgoing message buffers
no_outgoing_buffers,
/// The endpoint is out of incoming message buffers
no_incoming_buffers,
/// The connection was in the wrong state for this operation
invalid_state,
/// Unable to parse close code
bad_close_code,
/// Close code is in a reserved range
reserved_close_code,
/// Close code is invalid
invalid_close_code,
/// Invalid UTF-8
invalid_utf8,
/// Invalid subprotocol
invalid_subprotocol,
/// An operation was attempted on a connection that did not exist or was
/// already deleted.
bad_connection,
/// Unit testing utility error code
test,
/// Connection creation attempted failed
con_creation_failed,
/// Selected subprotocol was not requested by the client
unrequested_subprotocol,
/// Attempted to use a client specific feature on a server endpoint
client_only,
/// Attempted to use a server specific feature on a client endpoint
server_only,
/// HTTP connection ended
http_connection_ended,
/// WebSocket opening handshake timed out
open_handshake_timeout,
/// WebSocket close handshake timed out
close_handshake_timeout,
/// Invalid port in URI
invalid_port,
/// An async accept operation failed because the underlying transport has been
/// requested to not listen for new connections anymore.
async_accept_not_listening,
/// The requested operation was canceled
operation_canceled,
/// Connection rejected
rejected,
/// Upgrade Required. This happens if an HTTP request is made to a
/// WebSocket++ server that doesn't implement an http handler
upgrade_required,
/// Invalid WebSocket protocol version
invalid_version,
/// Unsupported WebSocket protocol version
unsupported_version,
/// HTTP parse error
http_parse_error,
/// Extension negotiation failed
extension_neg_failed
}; // enum value
class category : public lib::error_category {
public:
category() {}
char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
return "websocketpp";
}
std::string message(int value) const {
switch(value) {
case error::general:
return "Generic error";
case error::send_queue_full:
return "send queue full";
case error::payload_violation:
return "payload violation";
case error::endpoint_not_secure:
return "endpoint not secure";
case error::endpoint_unavailable:
return "endpoint not available";
case error::invalid_uri:
return "invalid uri";
case error::no_outgoing_buffers:
return "no outgoing message buffers";
case error::no_incoming_buffers:
return "no incoming message buffers";
case error::invalid_state:
return "invalid state";
case error::bad_close_code:
return "Unable to extract close code";
case error::invalid_close_code:
return "Extracted close code is in an invalid range";
case error::reserved_close_code:
return "Extracted close code is in a reserved range";
case error::invalid_utf8:
return "Invalid UTF-8";
case error::invalid_subprotocol:
return "Invalid subprotocol";
case error::bad_connection:
return "Bad Connection";
case error::test:
return "Test Error";
case error::con_creation_failed:
return "Connection creation attempt failed";
case error::unrequested_subprotocol:
return "Selected subprotocol was not requested by the client";
case error::client_only:
return "Feature not available on server endpoints";
case error::server_only:
return "Feature not available on client endpoints";
case error::http_connection_ended:
return "HTTP connection ended";
case error::open_handshake_timeout:
return "The opening handshake timed out";
case error::close_handshake_timeout:
return "The closing handshake timed out";
case error::invalid_port:
return "Invalid URI port";
case error::async_accept_not_listening:
return "Async Accept not listening";
case error::operation_canceled:
return "Operation canceled";
case error::rejected:
return "Connection rejected";
case error::upgrade_required:
return "Upgrade required";
case error::invalid_version:
return "Invalid version";
case error::unsupported_version:
return "Unsupported version";
case error::http_parse_error:
return "HTTP parse error";
case error::extension_neg_failed:
return "Extension negotiation failed";
default:
return "Unknown";
}
}
};
inline const lib::error_category& get_category() {
static category instance;
return instance;
}
inline lib::error_code make_error_code(error::value e) {
return lib::error_code(static_cast<int>(e), get_category());
}
} // namespace error
} // namespace websocketpp
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
template<> struct is_error_code_enum<websocketpp::error::value>
{
static bool const value = true;
};
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
namespace websocketpp {
class exception : public std::exception {
public:
exception(std::string const & msg, lib::error_code ec = make_error_code(error::general))
: m_msg(msg.empty() ? ec.message() : msg), m_code(ec)
{}
explicit exception(lib::error_code ec)
: m_msg(ec.message()), m_code(ec)
{}
~exception() throw() {}
virtual char const * what() const throw() {
return m_msg.c_str();
}
lib::error_code code() const throw() {
return m_code;
}
const std::string m_msg;
lib::error_code m_code;
};
} // namespace websocketpp
#endif // WEBSOCKETPP_ERROR_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_ERROR_HPP
#define WEBSOCKETPP_ERROR_HPP
#include <exception>
#include <string>
#include <utility>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/system_error.hpp>
namespace websocketpp {
/// Combination error code / string type for returning two values
typedef std::pair<lib::error_code,std::string> err_str_pair;
/// Library level error codes
namespace error {
enum value {
/// Catch-all library error
general = 1,
/// send attempted when endpoint write queue was full
send_queue_full,
/// Attempted an operation using a payload that was improperly formatted
/// ex: invalid UTF8 encoding on a text message.
payload_violation,
/// Attempted to open a secure connection with an insecure endpoint
endpoint_not_secure,
/// Attempted an operation that required an endpoint that is no longer
/// available. This is usually because the endpoint went out of scope
/// before a connection that it created.
endpoint_unavailable,
/// An invalid uri was supplied
invalid_uri,
/// The endpoint is out of outgoing message buffers
no_outgoing_buffers,
/// The endpoint is out of incoming message buffers
no_incoming_buffers,
/// The connection was in the wrong state for this operation
invalid_state,
/// Unable to parse close code
bad_close_code,
/// Close code is in a reserved range
reserved_close_code,
/// Close code is invalid
invalid_close_code,
/// Invalid UTF-8
invalid_utf8,
/// Invalid subprotocol
invalid_subprotocol,
/// An operation was attempted on a connection that did not exist or was
/// already deleted.
bad_connection,
/// Unit testing utility error code
test,
/// Connection creation attempted failed
con_creation_failed,
/// Selected subprotocol was not requested by the client
unrequested_subprotocol,
/// Attempted to use a client specific feature on a server endpoint
client_only,
/// Attempted to use a server specific feature on a client endpoint
server_only,
/// HTTP connection ended
http_connection_ended,
/// WebSocket opening handshake timed out
open_handshake_timeout,
/// WebSocket close handshake timed out
close_handshake_timeout,
/// Invalid port in URI
invalid_port,
/// An async accept operation failed because the underlying transport has been
/// requested to not listen for new connections anymore.
async_accept_not_listening,
/// The requested operation was canceled
operation_canceled,
/// Connection rejected
rejected,
/// Upgrade Required. This happens if an HTTP request is made to a
/// WebSocket++ server that doesn't implement an http handler
upgrade_required,
/// Invalid WebSocket protocol version
invalid_version,
/// Unsupported WebSocket protocol version
unsupported_version,
/// HTTP parse error
http_parse_error,
/// Extension negotiation failed
extension_neg_failed
}; // enum value
class category : public lib::error_category {
public:
category() {}
char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
return "websocketpp";
}
std::string message(int value) const {
switch(value) {
case error::general:
return "Generic error";
case error::send_queue_full:
return "send queue full";
case error::payload_violation:
return "payload violation";
case error::endpoint_not_secure:
return "endpoint not secure";
case error::endpoint_unavailable:
return "endpoint not available";
case error::invalid_uri:
return "invalid uri";
case error::no_outgoing_buffers:
return "no outgoing message buffers";
case error::no_incoming_buffers:
return "no incoming message buffers";
case error::invalid_state:
return "invalid state";
case error::bad_close_code:
return "Unable to extract close code";
case error::invalid_close_code:
return "Extracted close code is in an invalid range";
case error::reserved_close_code:
return "Extracted close code is in a reserved range";
case error::invalid_utf8:
return "Invalid UTF-8";
case error::invalid_subprotocol:
return "Invalid subprotocol";
case error::bad_connection:
return "Bad Connection";
case error::test:
return "Test Error";
case error::con_creation_failed:
return "Connection creation attempt failed";
case error::unrequested_subprotocol:
return "Selected subprotocol was not requested by the client";
case error::client_only:
return "Feature not available on server endpoints";
case error::server_only:
return "Feature not available on client endpoints";
case error::http_connection_ended:
return "HTTP connection ended";
case error::open_handshake_timeout:
return "The opening handshake timed out";
case error::close_handshake_timeout:
return "The closing handshake timed out";
case error::invalid_port:
return "Invalid URI port";
case error::async_accept_not_listening:
return "Async Accept not listening";
case error::operation_canceled:
return "Operation canceled";
case error::rejected:
return "Connection rejected";
case error::upgrade_required:
return "Upgrade required";
case error::invalid_version:
return "Invalid version";
case error::unsupported_version:
return "Unsupported version";
case error::http_parse_error:
return "HTTP parse error";
case error::extension_neg_failed:
return "Extension negotiation failed";
default:
return "Unknown";
}
}
};
inline const lib::error_category& get_category() {
static category instance;
return instance;
}
inline lib::error_code make_error_code(error::value e) {
return lib::error_code(static_cast<int>(e), get_category());
}
} // namespace error
} // namespace websocketpp
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
template<> struct is_error_code_enum<websocketpp::error::value>
{
static bool const value = true;
};
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
namespace websocketpp {
class exception : public std::exception {
public:
exception(std::string const & msg, lib::error_code ec = make_error_code(error::general))
: m_msg(msg.empty() ? ec.message() : msg), m_code(ec)
{}
explicit exception(lib::error_code ec)
: m_msg(ec.message()), m_code(ec)
{}
~exception() throw() {}
virtual char const * what() const throw() {
return m_msg.c_str();
}
lib::error_code code() const throw() {
return m_code;
}
const std::string m_msg;
lib::error_code m_code;
};
} // namespace websocketpp
#endif // WEBSOCKETPP_ERROR_HPP

View File

@@ -1,102 +1,102 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_EXTENSION_HPP
#define WEBSOCKETPP_EXTENSION_HPP
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/system_error.hpp>
#include <string>
#include <vector>
namespace websocketpp {
/**
* Some generic information about extensions
*
* Each extension object has an implemented flag. It can be retrieved by calling
* is_implemented(). This compile time flag indicates whether or not the object
* in question actually implements the extension or if it is a placeholder stub
*
* Each extension object also has an enabled flag. It can be retrieved by
* calling is_enabled(). This runtime flag indicates whether or not the
* extension has been negotiated for this connection.
*/
namespace extensions {
namespace error {
enum value {
/// Catch all
general = 1,
/// Extension disabled
disabled
};
class category : public lib::error_category {
public:
category() {}
const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
return "websocketpp.extension";
}
std::string message(int value) const {
switch(value) {
case general:
return "Generic extension error";
case disabled:
return "Use of methods from disabled extension";
default:
return "Unknown permessage-compress error";
}
}
};
inline lib::error_category const & get_category() {
static category instance;
return instance;
}
inline lib::error_code make_error_code(error::value e) {
return lib::error_code(static_cast<int>(e), get_category());
}
} // namespace error
} // namespace extensions
} // namespace websocketpp
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
template<> struct is_error_code_enum
<websocketpp::extensions::error::value>
{
static const bool value = true;
};
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
#endif // WEBSOCKETPP_EXTENSION_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_EXTENSION_HPP
#define WEBSOCKETPP_EXTENSION_HPP
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/system_error.hpp>
#include <string>
#include <vector>
namespace websocketpp {
/**
* Some generic information about extensions
*
* Each extension object has an implemented flag. It can be retrieved by calling
* is_implemented(). This compile time flag indicates whether or not the object
* in question actually implements the extension or if it is a placeholder stub
*
* Each extension object also has an enabled flag. It can be retrieved by
* calling is_enabled(). This runtime flag indicates whether or not the
* extension has been negotiated for this connection.
*/
namespace extensions {
namespace error {
enum value {
/// Catch all
general = 1,
/// Extension disabled
disabled
};
class category : public lib::error_category {
public:
category() {}
const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
return "websocketpp.extension";
}
std::string message(int value) const {
switch(value) {
case general:
return "Generic extension error";
case disabled:
return "Use of methods from disabled extension";
default:
return "Unknown permessage-compress error";
}
}
};
inline lib::error_category const & get_category() {
static category instance;
return instance;
}
inline lib::error_code make_error_code(error::value e) {
return lib::error_code(static_cast<int>(e), get_category());
}
} // namespace error
} // namespace extensions
} // namespace websocketpp
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
template<> struct is_error_code_enum
<websocketpp::extensions::error::value>
{
static const bool value = true;
};
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
#endif // WEBSOCKETPP_EXTENSION_HPP

View File

@@ -1,129 +1,129 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP
#define WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp>
#include <websocketpp/common/system_error.hpp>
#include <websocketpp/http/constants.hpp>
#include <websocketpp/extensions/extension.hpp>
#include <map>
#include <string>
#include <utility>
namespace websocketpp {
namespace extensions {
namespace permessage_deflate {
/// Stub class for use when disabling permessage_deflate extension
/**
* This class is a stub that implements the permessage_deflate interface
* with minimal dependencies. It is used to disable permessage_deflate
* functionality at compile time without loading any unnecessary code.
*/
template <typename config>
class disabled {
typedef std::pair<lib::error_code,std::string> err_str_pair;
public:
/// Negotiate extension
/**
* The disabled extension always fails the negotiation with a disabled
* error.
*
* @param offer Attribute from client's offer
* @return Status code and value to return to remote endpoint
*/
err_str_pair negotiate(http::attribute_list const &) {
return make_pair(make_error_code(error::disabled),std::string());
}
/// Initialize state
/**
* For the disabled extension state initialization is a no-op.
*
* @param is_server True to initialize as a server, false for a client.
* @return A code representing the error that occurred, if any
*/
lib::error_code init(bool) {
return lib::error_code();
}
/// Returns true if the extension is capable of providing
/// permessage_deflate functionality
bool is_implemented() const {
return false;
}
/// Returns true if permessage_deflate functionality is active for this
/// connection
bool is_enabled() const {
return false;
}
/// Generate extension offer
/**
* Creates an offer string to include in the Sec-WebSocket-Extensions
* header of outgoing client requests.
*
* @return A WebSocket extension offer string for this extension
*/
std::string generate_offer() const {
return "";
}
/// Compress bytes
/**
* @param [in] in String to compress
* @param [out] out String to append compressed bytes to
* @return Error or status code
*/
lib::error_code compress(std::string const &, std::string &) {
return make_error_code(error::disabled);
}
/// Decompress bytes
/**
* @param buf Byte buffer to decompress
* @param len Length of buf
* @param out String to append decompressed bytes to
* @return Error or status code
*/
lib::error_code decompress(uint8_t const *, size_t, std::string &) {
return make_error_code(error::disabled);
}
};
} // namespace permessage_deflate
} // namespace extensions
} // namespace websocketpp
#endif // WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP
#define WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp>
#include <websocketpp/common/system_error.hpp>
#include <websocketpp/http/constants.hpp>
#include <websocketpp/extensions/extension.hpp>
#include <map>
#include <string>
#include <utility>
namespace websocketpp {
namespace extensions {
namespace permessage_deflate {
/// Stub class for use when disabling permessage_deflate extension
/**
* This class is a stub that implements the permessage_deflate interface
* with minimal dependencies. It is used to disable permessage_deflate
* functionality at compile time without loading any unnecessary code.
*/
template <typename config>
class disabled {
typedef std::pair<lib::error_code,std::string> err_str_pair;
public:
/// Negotiate extension
/**
* The disabled extension always fails the negotiation with a disabled
* error.
*
* @param offer Attribute from client's offer
* @return Status code and value to return to remote endpoint
*/
err_str_pair negotiate(http::attribute_list const &) {
return make_pair(make_error_code(error::disabled),std::string());
}
/// Initialize state
/**
* For the disabled extension state initialization is a no-op.
*
* @param is_server True to initialize as a server, false for a client.
* @return A code representing the error that occurred, if any
*/
lib::error_code init(bool) {
return lib::error_code();
}
/// Returns true if the extension is capable of providing
/// permessage_deflate functionality
bool is_implemented() const {
return false;
}
/// Returns true if permessage_deflate functionality is active for this
/// connection
bool is_enabled() const {
return false;
}
/// Generate extension offer
/**
* Creates an offer string to include in the Sec-WebSocket-Extensions
* header of outgoing client requests.
*
* @return A WebSocket extension offer string for this extension
*/
std::string generate_offer() const {
return "";
}
/// Compress bytes
/**
* @param [in] in String to compress
* @param [out] out String to append compressed bytes to
* @return Error or status code
*/
lib::error_code compress(std::string const &, std::string &) {
return make_error_code(error::disabled);
}
/// Decompress bytes
/**
* @param buf Byte buffer to decompress
* @param len Length of buf
* @param out String to append decompressed bytes to
* @return Error or status code
*/
lib::error_code decompress(uint8_t const *, size_t, std::string &) {
return make_error_code(error::disabled);
}
};
} // namespace permessage_deflate
} // namespace extensions
} // namespace websocketpp
#endif // WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -1,308 +1,308 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_CONSTANTS_HPP
#define HTTP_CONSTANTS_HPP
#include <exception>
#include <map>
#include <string>
#include <vector>
#include <utility>
namespace websocketpp {
/// HTTP handling support
namespace http {
/// The type of an HTTP attribute list
/**
* The attribute list is an unordered key/value map. Encoded attribute
* values are delimited by semicolons.
*/
typedef std::map<std::string,std::string> attribute_list;
/// The type of an HTTP parameter list
/**
* The parameter list is an ordered pairing of a parameter and its
* associated attribute list. Encoded parameter values are delimited by
* commas.
*/
typedef std::vector< std::pair<std::string,attribute_list> > parameter_list;
/// Literal value of the HTTP header delimiter
static char const header_delimiter[] = "\r\n";
/// Literal value of the HTTP header separator
static char const header_separator[] = ":";
/// Literal value of an empty header
static std::string const empty_header;
/// Maximum size in bytes before rejecting an HTTP header as too big.
size_t const max_header_size = 16000;
/// Default Maximum size in bytes for HTTP message bodies.
size_t const max_body_size = 32000000;
/// Number of bytes to use for temporary istream read buffers
size_t const istream_buffer = 512;
/// invalid HTTP token characters
/**
* 0x00 - 0x32, 0x7f-0xff
* ( ) < > @ , ; : \ " / [ ] ? = { }
*/
static char const header_token[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..0f
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10..1f
0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0, // 20..2f
1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 30..3f
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 40..4f
1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1, // 50..5f
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 60..6f
1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0, // 70..7f
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 80..8f
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 90..9f
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a0..af
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b0..bf
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c0..cf
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d0..df
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e0..ef
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff
};
/// Is the character a token
inline bool is_token_char(unsigned char c) {
return (header_token[c] == 1);
}
/// Is the character a non-token
inline bool is_not_token_char(unsigned char c) {
return !header_token[c];
}
/// Is the character whitespace
/**
* whitespace is space (32) or horizontal tab (9)
*/
inline bool is_whitespace_char(unsigned char c) {
return (c == 9 || c == 32);
}
/// Is the character non-whitespace
inline bool is_not_whitespace_char(unsigned char c) {
return (c != 9 && c != 32);
}
/// HTTP Status codes
namespace status_code {
enum value {
uninitialized = 0,
continue_code = 100,
switching_protocols = 101,
ok = 200,
created = 201,
accepted = 202,
non_authoritative_information = 203,
no_content = 204,
reset_content = 205,
partial_content = 206,
multiple_choices = 300,
moved_permanently = 301,
found = 302,
see_other = 303,
not_modified = 304,
use_proxy = 305,
temporary_redirect = 307,
bad_request = 400,
unauthorized = 401,
payment_required = 402,
forbidden = 403,
not_found = 404,
method_not_allowed = 405,
not_acceptable = 406,
proxy_authentication_required = 407,
request_timeout = 408,
conflict = 409,
gone = 410,
length_required = 411,
precondition_failed = 412,
request_entity_too_large = 413,
request_uri_too_long = 414,
unsupported_media_type = 415,
request_range_not_satisfiable = 416,
expectation_failed = 417,
im_a_teapot = 418,
upgrade_required = 426,
precondition_required = 428,
too_many_requests = 429,
request_header_fields_too_large = 431,
internal_server_error = 500,
not_implemented = 501,
bad_gateway = 502,
service_unavailable = 503,
gateway_timeout = 504,
http_version_not_supported = 505,
not_extended = 510,
network_authentication_required = 511
};
// TODO: should this be inline?
inline std::string get_string(value c) {
switch (c) {
case uninitialized:
return "Uninitialized";
case continue_code:
return "Continue";
case switching_protocols:
return "Switching Protocols";
case ok:
return "OK";
case created:
return "Created";
case accepted:
return "Accepted";
case non_authoritative_information:
return "Non Authoritative Information";
case no_content:
return "No Content";
case reset_content:
return "Reset Content";
case partial_content:
return "Partial Content";
case multiple_choices:
return "Multiple Choices";
case moved_permanently:
return "Moved Permanently";
case found:
return "Found";
case see_other:
return "See Other";
case not_modified:
return "Not Modified";
case use_proxy:
return "Use Proxy";
case temporary_redirect:
return "Temporary Redirect";
case bad_request:
return "Bad Request";
case unauthorized:
return "Unauthorized";
case payment_required:
return "Payment Required";
case forbidden:
return "Forbidden";
case not_found:
return "Not Found";
case method_not_allowed:
return "Method Not Allowed";
case not_acceptable:
return "Not Acceptable";
case proxy_authentication_required:
return "Proxy Authentication Required";
case request_timeout:
return "Request Timeout";
case conflict:
return "Conflict";
case gone:
return "Gone";
case length_required:
return "Length Required";
case precondition_failed:
return "Precondition Failed";
case request_entity_too_large:
return "Request Entity Too Large";
case request_uri_too_long:
return "Request-URI Too Long";
case unsupported_media_type:
return "Unsupported Media Type";
case request_range_not_satisfiable:
return "Requested Range Not Satisfiable";
case expectation_failed:
return "Expectation Failed";
case im_a_teapot:
return "I'm a teapot";
case upgrade_required:
return "Upgrade Required";
case precondition_required:
return "Precondition Required";
case too_many_requests:
return "Too Many Requests";
case request_header_fields_too_large:
return "Request Header Fields Too Large";
case internal_server_error:
return "Internal Server Error";
case not_implemented:
return "Not Implemented";
case bad_gateway:
return "Bad Gateway";
case service_unavailable:
return "Service Unavailable";
case gateway_timeout:
return "Gateway Timeout";
case http_version_not_supported:
return "HTTP Version Not Supported";
case not_extended:
return "Not Extended";
case network_authentication_required:
return "Network Authentication Required";
default:
return "Unknown";
}
}
}
class exception : public std::exception {
public:
exception(const std::string& log_msg,
status_code::value error_code,
const std::string& error_msg = std::string(),
const std::string& body = std::string())
: m_msg(log_msg)
, m_error_msg(error_msg)
, m_body(body)
, m_error_code(error_code) {}
~exception() throw() {}
virtual const char* what() const throw() {
return m_msg.c_str();
}
std::string m_msg;
std::string m_error_msg;
std::string m_body;
status_code::value m_error_code;
};
}
}
#endif // HTTP_CONSTANTS_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_CONSTANTS_HPP
#define HTTP_CONSTANTS_HPP
#include <exception>
#include <map>
#include <string>
#include <vector>
#include <utility>
namespace websocketpp {
/// HTTP handling support
namespace http {
/// The type of an HTTP attribute list
/**
* The attribute list is an unordered key/value map. Encoded attribute
* values are delimited by semicolons.
*/
typedef std::map<std::string,std::string> attribute_list;
/// The type of an HTTP parameter list
/**
* The parameter list is an ordered pairing of a parameter and its
* associated attribute list. Encoded parameter values are delimited by
* commas.
*/
typedef std::vector< std::pair<std::string,attribute_list> > parameter_list;
/// Literal value of the HTTP header delimiter
static char const header_delimiter[] = "\r\n";
/// Literal value of the HTTP header separator
static char const header_separator[] = ":";
/// Literal value of an empty header
static std::string const empty_header;
/// Maximum size in bytes before rejecting an HTTP header as too big.
size_t const max_header_size = 16000;
/// Default Maximum size in bytes for HTTP message bodies.
size_t const max_body_size = 32000000;
/// Number of bytes to use for temporary istream read buffers
size_t const istream_buffer = 512;
/// invalid HTTP token characters
/**
* 0x00 - 0x32, 0x7f-0xff
* ( ) < > @ , ; : \ " / [ ] ? = { }
*/
static char const header_token[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..0f
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10..1f
0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0, // 20..2f
1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 30..3f
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 40..4f
1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1, // 50..5f
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 60..6f
1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0, // 70..7f
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 80..8f
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 90..9f
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a0..af
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b0..bf
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c0..cf
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d0..df
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e0..ef
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff
};
/// Is the character a token
inline bool is_token_char(unsigned char c) {
return (header_token[c] == 1);
}
/// Is the character a non-token
inline bool is_not_token_char(unsigned char c) {
return !header_token[c];
}
/// Is the character whitespace
/**
* whitespace is space (32) or horizontal tab (9)
*/
inline bool is_whitespace_char(unsigned char c) {
return (c == 9 || c == 32);
}
/// Is the character non-whitespace
inline bool is_not_whitespace_char(unsigned char c) {
return (c != 9 && c != 32);
}
/// HTTP Status codes
namespace status_code {
enum value {
uninitialized = 0,
continue_code = 100,
switching_protocols = 101,
ok = 200,
created = 201,
accepted = 202,
non_authoritative_information = 203,
no_content = 204,
reset_content = 205,
partial_content = 206,
multiple_choices = 300,
moved_permanently = 301,
found = 302,
see_other = 303,
not_modified = 304,
use_proxy = 305,
temporary_redirect = 307,
bad_request = 400,
unauthorized = 401,
payment_required = 402,
forbidden = 403,
not_found = 404,
method_not_allowed = 405,
not_acceptable = 406,
proxy_authentication_required = 407,
request_timeout = 408,
conflict = 409,
gone = 410,
length_required = 411,
precondition_failed = 412,
request_entity_too_large = 413,
request_uri_too_long = 414,
unsupported_media_type = 415,
request_range_not_satisfiable = 416,
expectation_failed = 417,
im_a_teapot = 418,
upgrade_required = 426,
precondition_required = 428,
too_many_requests = 429,
request_header_fields_too_large = 431,
internal_server_error = 500,
not_implemented = 501,
bad_gateway = 502,
service_unavailable = 503,
gateway_timeout = 504,
http_version_not_supported = 505,
not_extended = 510,
network_authentication_required = 511
};
// TODO: should this be inline?
inline std::string get_string(value c) {
switch (c) {
case uninitialized:
return "Uninitialized";
case continue_code:
return "Continue";
case switching_protocols:
return "Switching Protocols";
case ok:
return "OK";
case created:
return "Created";
case accepted:
return "Accepted";
case non_authoritative_information:
return "Non Authoritative Information";
case no_content:
return "No Content";
case reset_content:
return "Reset Content";
case partial_content:
return "Partial Content";
case multiple_choices:
return "Multiple Choices";
case moved_permanently:
return "Moved Permanently";
case found:
return "Found";
case see_other:
return "See Other";
case not_modified:
return "Not Modified";
case use_proxy:
return "Use Proxy";
case temporary_redirect:
return "Temporary Redirect";
case bad_request:
return "Bad Request";
case unauthorized:
return "Unauthorized";
case payment_required:
return "Payment Required";
case forbidden:
return "Forbidden";
case not_found:
return "Not Found";
case method_not_allowed:
return "Method Not Allowed";
case not_acceptable:
return "Not Acceptable";
case proxy_authentication_required:
return "Proxy Authentication Required";
case request_timeout:
return "Request Timeout";
case conflict:
return "Conflict";
case gone:
return "Gone";
case length_required:
return "Length Required";
case precondition_failed:
return "Precondition Failed";
case request_entity_too_large:
return "Request Entity Too Large";
case request_uri_too_long:
return "Request-URI Too Long";
case unsupported_media_type:
return "Unsupported Media Type";
case request_range_not_satisfiable:
return "Requested Range Not Satisfiable";
case expectation_failed:
return "Expectation Failed";
case im_a_teapot:
return "I'm a teapot";
case upgrade_required:
return "Upgrade Required";
case precondition_required:
return "Precondition Required";
case too_many_requests:
return "Too Many Requests";
case request_header_fields_too_large:
return "Request Header Fields Too Large";
case internal_server_error:
return "Internal Server Error";
case not_implemented:
return "Not Implemented";
case bad_gateway:
return "Bad Gateway";
case service_unavailable:
return "Service Unavailable";
case gateway_timeout:
return "Gateway Timeout";
case http_version_not_supported:
return "HTTP Version Not Supported";
case not_extended:
return "Not Extended";
case network_authentication_required:
return "Network Authentication Required";
default:
return "Unknown";
}
}
}
class exception : public std::exception {
public:
exception(const std::string& log_msg,
status_code::value error_code,
const std::string& error_msg = std::string(),
const std::string& body = std::string())
: m_msg(log_msg)
, m_error_msg(error_msg)
, m_body(body)
, m_error_code(error_code) {}
~exception() throw() {}
virtual const char* what() const throw() {
return m_msg.c_str();
}
std::string m_msg;
std::string m_error_msg;
std::string m_body;
status_code::value m_error_code;
};
}
}
#endif // HTTP_CONSTANTS_HPP

View File

@@ -1,200 +1,200 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_PARSER_IMPL_HPP
#define HTTP_PARSER_IMPL_HPP
#include <algorithm>
#include <cstdlib>
#include <istream>
#include <sstream>
#include <string>
namespace websocketpp {
namespace http {
namespace parser {
inline void parser::set_version(std::string const & version) {
m_version = version;
}
inline std::string const & parser::get_header(std::string const & key) const {
header_list::const_iterator h = m_headers.find(key);
if (h == m_headers.end()) {
return empty_header;
} else {
return h->second;
}
}
inline bool parser::get_header_as_plist(std::string const & key,
parameter_list & out) const
{
header_list::const_iterator it = m_headers.find(key);
if (it == m_headers.end() || it->second.size() == 0) {
return false;
}
return this->parse_parameter_list(it->second,out);
}
inline void parser::append_header(std::string const & key, std::string const &
val)
{
if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) {
throw exception("Invalid header name",status_code::bad_request);
}
if (this->get_header(key).empty()) {
m_headers[key] = val;
} else {
m_headers[key] += ", " + val;
}
}
inline void parser::replace_header(std::string const & key, std::string const &
val)
{
m_headers[key] = val;
}
inline void parser::remove_header(std::string const & key) {
m_headers.erase(key);
}
inline void parser::set_body(std::string const & value) {
if (value.size() == 0) {
remove_header("Content-Length");
m_body.clear();
return;
}
// TODO: should this method respect the max size? If so how should errors
// be indicated?
std::stringstream len;
len << value.size();
replace_header("Content-Length", len.str());
m_body = value;
}
inline bool parser::parse_parameter_list(std::string const & in,
parameter_list & out) const
{
if (in.size() == 0) {
return false;
}
std::string::const_iterator it;
it = extract_parameters(in.begin(),in.end(),out);
return (it == in.begin());
}
inline bool parser::prepare_body() {
if (!get_header("Content-Length").empty()) {
std::string const & cl_header = get_header("Content-Length");
char * end;
// TODO: not 100% sure what the compatibility of this method is. Also,
// I believe this will only work up to 32bit sizes. Is there a need for
// > 4GiB HTTP payloads?
m_body_bytes_needed = std::strtoul(cl_header.c_str(),&end,10);
if (m_body_bytes_needed > m_body_bytes_max) {
throw exception("HTTP message body too large",
status_code::request_entity_too_large);
}
m_body_encoding = body_encoding::plain;
return true;
} else if (get_header("Transfer-Encoding") == "chunked") {
// TODO
//m_body_encoding = body_encoding::chunked;
return false;
} else {
return false;
}
}
inline size_t parser::process_body(char const * buf, size_t len) {
if (m_body_encoding == body_encoding::plain) {
size_t processed = (std::min)(m_body_bytes_needed,len);
m_body.append(buf,processed);
m_body_bytes_needed -= processed;
return processed;
} else if (m_body_encoding == body_encoding::chunked) {
// TODO:
throw exception("Unexpected body encoding",
status_code::internal_server_error);
} else {
throw exception("Unexpected body encoding",
status_code::internal_server_error);
}
}
inline void parser::process_header(std::string::iterator begin,
std::string::iterator end)
{
std::string::iterator cursor = std::search(
begin,
end,
header_separator,
header_separator + sizeof(header_separator) - 1
);
if (cursor == end) {
throw exception("Invalid header line",status_code::bad_request);
}
append_header(strip_lws(std::string(begin,cursor)),
strip_lws(std::string(cursor+sizeof(header_separator)-1,end)));
}
inline header_list const & parser::get_headers() const {
return m_headers;
}
inline std::string parser::raw_headers() const {
std::stringstream raw;
header_list::const_iterator it;
for (it = m_headers.begin(); it != m_headers.end(); it++) {
raw << it->first << ": " << it->second << "\r\n";
}
return raw.str();
}
} // namespace parser
} // namespace http
} // namespace websocketpp
#endif // HTTP_PARSER_IMPL_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_PARSER_IMPL_HPP
#define HTTP_PARSER_IMPL_HPP
#include <algorithm>
#include <cstdlib>
#include <istream>
#include <sstream>
#include <string>
namespace websocketpp {
namespace http {
namespace parser {
inline void parser::set_version(std::string const & version) {
m_version = version;
}
inline std::string const & parser::get_header(std::string const & key) const {
header_list::const_iterator h = m_headers.find(key);
if (h == m_headers.end()) {
return empty_header;
} else {
return h->second;
}
}
inline bool parser::get_header_as_plist(std::string const & key,
parameter_list & out) const
{
header_list::const_iterator it = m_headers.find(key);
if (it == m_headers.end() || it->second.size() == 0) {
return false;
}
return this->parse_parameter_list(it->second,out);
}
inline void parser::append_header(std::string const & key, std::string const &
val)
{
if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) {
throw exception("Invalid header name",status_code::bad_request);
}
if (this->get_header(key).empty()) {
m_headers[key] = val;
} else {
m_headers[key] += ", " + val;
}
}
inline void parser::replace_header(std::string const & key, std::string const &
val)
{
m_headers[key] = val;
}
inline void parser::remove_header(std::string const & key) {
m_headers.erase(key);
}
inline void parser::set_body(std::string const & value) {
if (value.size() == 0) {
remove_header("Content-Length");
m_body.clear();
return;
}
// TODO: should this method respect the max size? If so how should errors
// be indicated?
std::stringstream len;
len << value.size();
replace_header("Content-Length", len.str());
m_body = value;
}
inline bool parser::parse_parameter_list(std::string const & in,
parameter_list & out) const
{
if (in.size() == 0) {
return false;
}
std::string::const_iterator it;
it = extract_parameters(in.begin(),in.end(),out);
return (it == in.begin());
}
inline bool parser::prepare_body() {
if (!get_header("Content-Length").empty()) {
std::string const & cl_header = get_header("Content-Length");
char * end;
// TODO: not 100% sure what the compatibility of this method is. Also,
// I believe this will only work up to 32bit sizes. Is there a need for
// > 4GiB HTTP payloads?
m_body_bytes_needed = std::strtoul(cl_header.c_str(),&end,10);
if (m_body_bytes_needed > m_body_bytes_max) {
throw exception("HTTP message body too large",
status_code::request_entity_too_large);
}
m_body_encoding = body_encoding::plain;
return true;
} else if (get_header("Transfer-Encoding") == "chunked") {
// TODO
//m_body_encoding = body_encoding::chunked;
return false;
} else {
return false;
}
}
inline size_t parser::process_body(char const * buf, size_t len) {
if (m_body_encoding == body_encoding::plain) {
size_t processed = (std::min)(m_body_bytes_needed,len);
m_body.append(buf,processed);
m_body_bytes_needed -= processed;
return processed;
} else if (m_body_encoding == body_encoding::chunked) {
// TODO:
throw exception("Unexpected body encoding",
status_code::internal_server_error);
} else {
throw exception("Unexpected body encoding",
status_code::internal_server_error);
}
}
inline void parser::process_header(std::string::iterator begin,
std::string::iterator end)
{
std::string::iterator cursor = std::search(
begin,
end,
header_separator,
header_separator + sizeof(header_separator) - 1
);
if (cursor == end) {
throw exception("Invalid header line",status_code::bad_request);
}
append_header(strip_lws(std::string(begin,cursor)),
strip_lws(std::string(cursor+sizeof(header_separator)-1,end)));
}
inline header_list const & parser::get_headers() const {
return m_headers;
}
inline std::string parser::raw_headers() const {
std::stringstream raw;
header_list::const_iterator it;
for (it = m_headers.begin(); it != m_headers.end(); it++) {
raw << it->first << ": " << it->second << "\r\n";
}
return raw.str();
}
} // namespace parser
} // namespace http
} // namespace websocketpp
#endif // HTTP_PARSER_IMPL_HPP

View File

@@ -1,191 +1,191 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_PARSER_REQUEST_IMPL_HPP
#define HTTP_PARSER_REQUEST_IMPL_HPP
#include <algorithm>
#include <sstream>
#include <string>
#include <websocketpp/http/parser.hpp>
namespace websocketpp {
namespace http {
namespace parser {
inline size_t request::consume(char const * buf, size_t len) {
size_t bytes_processed;
if (m_ready) {return 0;}
if (m_body_bytes_needed > 0) {
bytes_processed = process_body(buf,len);
if (body_ready()) {
m_ready = true;
}
return bytes_processed;
}
// copy new header bytes into buffer
m_buf->append(buf,len);
// Search for delimiter in buf. If found read until then. If not read all
std::string::iterator begin = m_buf->begin();
std::string::iterator end;
for (;;) {
// search for line delimiter
end = std::search(
begin,
m_buf->end(),
header_delimiter,
header_delimiter+sizeof(header_delimiter)-1
);
m_header_bytes += (end-begin+sizeof(header_delimiter));
if (m_header_bytes > max_header_size) {
// exceeded max header size
throw exception("Maximum header size exceeded.",
status_code::request_header_fields_too_large);
}
if (end == m_buf->end()) {
// we are out of bytes. Discard the processed bytes and copy the
// remaining unprecessed bytes to the beginning of the buffer
std::copy(begin,end,m_buf->begin());
m_buf->resize(static_cast<std::string::size_type>(end-begin));
m_header_bytes -= m_buf->size();
return len;
}
//the range [begin,end) now represents a line to be processed.
if (end-begin == 0) {
// we got a blank line
if (m_method.empty() || get_header("Host").empty()) {
throw exception("Incomplete Request",status_code::bad_request);
}
bytes_processed = (
len - static_cast<std::string::size_type>(m_buf->end()-end)
+ sizeof(header_delimiter) - 1
);
// frees memory used temporarily during request parsing
m_buf.reset();
// if this was not an upgrade request and has a content length
// continue capturing content-length bytes and expose them as a
// request body.
if (prepare_body()) {
bytes_processed += process_body(buf+bytes_processed,len-bytes_processed);
if (body_ready()) {
m_ready = true;
}
return bytes_processed;
} else {
m_ready = true;
// return number of bytes processed (starting bytes - bytes left)
return bytes_processed;
}
} else {
if (m_method.empty()) {
this->process(begin,end);
} else {
this->process_header(begin,end);
}
}
begin = end+(sizeof(header_delimiter)-1);
}
}
inline std::string request::raw() const {
// TODO: validation. Make sure all required fields have been set?
std::stringstream ret;
ret << m_method << " " << m_uri << " " << get_version() << "\r\n";
ret << raw_headers() << "\r\n" << m_body;
return ret.str();
}
inline std::string request::raw_head() const {
// TODO: validation. Make sure all required fields have been set?
std::stringstream ret;
ret << m_method << " " << m_uri << " " << get_version() << "\r\n";
ret << raw_headers() << "\r\n";
return ret.str();
}
inline void request::set_method(std::string const & method) {
if (std::find_if(method.begin(),method.end(),is_not_token_char) != method.end()) {
throw exception("Invalid method token.",status_code::bad_request);
}
m_method = method;
}
inline void request::set_uri(std::string const & uri) {
// TODO: validation?
m_uri = uri;
}
inline void request::process(std::string::iterator begin, std::string::iterator
end)
{
std::string::iterator cursor_start = begin;
std::string::iterator cursor_end = std::find(begin,end,' ');
if (cursor_end == end) {
throw exception("Invalid request line1",status_code::bad_request);
}
set_method(std::string(cursor_start,cursor_end));
cursor_start = cursor_end+1;
cursor_end = std::find(cursor_start,end,' ');
if (cursor_end == end) {
throw exception("Invalid request line2",status_code::bad_request);
}
set_uri(std::string(cursor_start,cursor_end));
set_version(std::string(cursor_end+1,end));
}
} // namespace parser
} // namespace http
} // namespace websocketpp
#endif // HTTP_PARSER_REQUEST_IMPL_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_PARSER_REQUEST_IMPL_HPP
#define HTTP_PARSER_REQUEST_IMPL_HPP
#include <algorithm>
#include <sstream>
#include <string>
#include <websocketpp/http/parser.hpp>
namespace websocketpp {
namespace http {
namespace parser {
inline size_t request::consume(char const * buf, size_t len) {
size_t bytes_processed;
if (m_ready) {return 0;}
if (m_body_bytes_needed > 0) {
bytes_processed = process_body(buf,len);
if (body_ready()) {
m_ready = true;
}
return bytes_processed;
}
// copy new header bytes into buffer
m_buf->append(buf,len);
// Search for delimiter in buf. If found read until then. If not read all
std::string::iterator begin = m_buf->begin();
std::string::iterator end;
for (;;) {
// search for line delimiter
end = std::search(
begin,
m_buf->end(),
header_delimiter,
header_delimiter+sizeof(header_delimiter)-1
);
m_header_bytes += (end-begin+sizeof(header_delimiter));
if (m_header_bytes > max_header_size) {
// exceeded max header size
throw exception("Maximum header size exceeded.",
status_code::request_header_fields_too_large);
}
if (end == m_buf->end()) {
// we are out of bytes. Discard the processed bytes and copy the
// remaining unprecessed bytes to the beginning of the buffer
std::copy(begin,end,m_buf->begin());
m_buf->resize(static_cast<std::string::size_type>(end-begin));
m_header_bytes -= m_buf->size();
return len;
}
//the range [begin,end) now represents a line to be processed.
if (end-begin == 0) {
// we got a blank line
if (m_method.empty() || get_header("Host").empty()) {
throw exception("Incomplete Request",status_code::bad_request);
}
bytes_processed = (
len - static_cast<std::string::size_type>(m_buf->end()-end)
+ sizeof(header_delimiter) - 1
);
// frees memory used temporarily during request parsing
m_buf.reset();
// if this was not an upgrade request and has a content length
// continue capturing content-length bytes and expose them as a
// request body.
if (prepare_body()) {
bytes_processed += process_body(buf+bytes_processed,len-bytes_processed);
if (body_ready()) {
m_ready = true;
}
return bytes_processed;
} else {
m_ready = true;
// return number of bytes processed (starting bytes - bytes left)
return bytes_processed;
}
} else {
if (m_method.empty()) {
this->process(begin,end);
} else {
this->process_header(begin,end);
}
}
begin = end+(sizeof(header_delimiter)-1);
}
}
inline std::string request::raw() const {
// TODO: validation. Make sure all required fields have been set?
std::stringstream ret;
ret << m_method << " " << m_uri << " " << get_version() << "\r\n";
ret << raw_headers() << "\r\n" << m_body;
return ret.str();
}
inline std::string request::raw_head() const {
// TODO: validation. Make sure all required fields have been set?
std::stringstream ret;
ret << m_method << " " << m_uri << " " << get_version() << "\r\n";
ret << raw_headers() << "\r\n";
return ret.str();
}
inline void request::set_method(std::string const & method) {
if (std::find_if(method.begin(),method.end(),is_not_token_char) != method.end()) {
throw exception("Invalid method token.",status_code::bad_request);
}
m_method = method;
}
inline void request::set_uri(std::string const & uri) {
// TODO: validation?
m_uri = uri;
}
inline void request::process(std::string::iterator begin, std::string::iterator
end)
{
std::string::iterator cursor_start = begin;
std::string::iterator cursor_end = std::find(begin,end,' ');
if (cursor_end == end) {
throw exception("Invalid request line1",status_code::bad_request);
}
set_method(std::string(cursor_start,cursor_end));
cursor_start = cursor_end+1;
cursor_end = std::find(cursor_start,end,' ');
if (cursor_end == end) {
throw exception("Invalid request line2",status_code::bad_request);
}
set_uri(std::string(cursor_start,cursor_end));
set_version(std::string(cursor_end+1,end));
}
} // namespace parser
} // namespace http
} // namespace websocketpp
#endif // HTTP_PARSER_REQUEST_IMPL_HPP

View File

@@ -1,266 +1,266 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_PARSER_RESPONSE_IMPL_HPP
#define HTTP_PARSER_RESPONSE_IMPL_HPP
#include <algorithm>
#include <istream>
#include <sstream>
#include <string>
#include <websocketpp/http/parser.hpp>
namespace websocketpp {
namespace http {
namespace parser {
inline size_t response::consume(char const * buf, size_t len) {
if (m_state == DONE) {return 0;}
if (m_state == BODY) {
return this->process_body(buf,len);
}
// copy new header bytes into buffer
m_buf->append(buf,len);
// Search for delimiter in buf. If found read until then. If not read all
std::string::iterator begin = m_buf->begin();
std::string::iterator end = begin;
for (;;) {
// search for delimiter
end = std::search(
begin,
m_buf->end(),
header_delimiter,
header_delimiter + sizeof(header_delimiter) - 1
);
m_header_bytes += (end-begin+sizeof(header_delimiter));
if (m_header_bytes > max_header_size) {
// exceeded max header size
throw exception("Maximum header size exceeded.",
status_code::request_header_fields_too_large);
}
if (end == m_buf->end()) {
// we are out of bytes. Discard the processed bytes and copy the
// remaining unprecessed bytes to the beginning of the buffer
std::copy(begin,end,m_buf->begin());
m_buf->resize(static_cast<std::string::size_type>(end-begin));
m_read += len;
m_header_bytes -= m_buf->size();
return len;
}
//the range [begin,end) now represents a line to be processed.
if (end-begin == 0) {
// we got a blank line
if (m_state == RESPONSE_LINE) {
throw exception("Incomplete Request",status_code::bad_request);
}
// TODO: grab content-length
std::string length = get_header("Content-Length");
if (length.empty()) {
// no content length found, read indefinitely
m_read = 0;
} else {
std::istringstream ss(length);
if ((ss >> m_read).fail()) {
throw exception("Unable to parse Content-Length header",
status_code::bad_request);
}
}
m_state = BODY;
// calc header bytes processed (starting bytes - bytes left)
size_t read = (
len - static_cast<std::string::size_type>(m_buf->end() - end)
+ sizeof(header_delimiter) - 1
);
// if there were bytes left process them as body bytes
if (read < len) {
read += this->process_body(buf+read,(len-read));
}
// frees memory used temporarily during header parsing
m_buf.reset();
return read;
} else {
if (m_state == RESPONSE_LINE) {
this->process(begin,end);
m_state = HEADERS;
} else {
this->process_header(begin,end);
}
}
begin = end+(sizeof(header_delimiter) - 1);
}
}
inline size_t response::consume(std::istream & s) {
char buf[istream_buffer];
size_t bytes_read;
size_t bytes_processed;
size_t total = 0;
while (s.good()) {
s.getline(buf,istream_buffer);
bytes_read = static_cast<size_t>(s.gcount());
if (s.fail() || s.eof()) {
bytes_processed = this->consume(buf,bytes_read);
total += bytes_processed;
if (bytes_processed != bytes_read) {
// problem
break;
}
} else if (s.bad()) {
// problem
break;
} else {
// the delimiting newline was found. Replace the trailing null with
// the newline that was discarded, since our raw consume function
// expects the newline to be be there.
buf[bytes_read-1] = '\n';
bytes_processed = this->consume(buf,bytes_read);
total += bytes_processed;
if (bytes_processed != bytes_read) {
// problem
break;
}
}
}
return total;
}
inline std::string response::raw() const {
// TODO: validation. Make sure all required fields have been set?
std::stringstream ret;
ret << get_version() << " " << m_status_code << " " << m_status_msg;
ret << "\r\n" << raw_headers() << "\r\n";
ret << m_body;
return ret.str();
}
inline void response::set_status(status_code::value code) {
// TODO: validation?
m_status_code = code;
m_status_msg = get_string(code);
}
inline void response::set_status(status_code::value code, std::string const &
msg)
{
// TODO: validation?
m_status_code = code;
m_status_msg = msg;
}
inline void response::process(std::string::iterator begin,
std::string::iterator end)
{
std::string::iterator cursor_start = begin;
std::string::iterator cursor_end = std::find(begin,end,' ');
if (cursor_end == end) {
throw exception("Invalid response line",status_code::bad_request);
}
set_version(std::string(cursor_start,cursor_end));
cursor_start = cursor_end+1;
cursor_end = std::find(cursor_start,end,' ');
if (cursor_end == end) {
throw exception("Invalid request line",status_code::bad_request);
}
int code;
std::istringstream ss(std::string(cursor_start,cursor_end));
if ((ss >> code).fail()) {
throw exception("Unable to parse response code",status_code::bad_request);
}
set_status(status_code::value(code),std::string(cursor_end+1,end));
}
inline size_t response::process_body(char const * buf, size_t len) {
// If no content length was set then we read forever and never set m_ready
if (m_read == 0) {
//m_body.append(buf,len);
//return len;
m_state = DONE;
return 0;
}
// Otherwise m_read is the number of bytes left.
size_t to_read;
if (len >= m_read) {
// if we have more bytes than we need read, read only the amount needed
// then set done state
to_read = m_read;
m_state = DONE;
} else {
// we need more bytes than are available, read them all
to_read = len;
}
m_body.append(buf,to_read);
m_read -= to_read;
return to_read;
}
} // namespace parser
} // namespace http
} // namespace websocketpp
#endif // HTTP_PARSER_RESPONSE_IMPL_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_PARSER_RESPONSE_IMPL_HPP
#define HTTP_PARSER_RESPONSE_IMPL_HPP
#include <algorithm>
#include <istream>
#include <sstream>
#include <string>
#include <websocketpp/http/parser.hpp>
namespace websocketpp {
namespace http {
namespace parser {
inline size_t response::consume(char const * buf, size_t len) {
if (m_state == DONE) {return 0;}
if (m_state == BODY) {
return this->process_body(buf,len);
}
// copy new header bytes into buffer
m_buf->append(buf,len);
// Search for delimiter in buf. If found read until then. If not read all
std::string::iterator begin = m_buf->begin();
std::string::iterator end = begin;
for (;;) {
// search for delimiter
end = std::search(
begin,
m_buf->end(),
header_delimiter,
header_delimiter + sizeof(header_delimiter) - 1
);
m_header_bytes += (end-begin+sizeof(header_delimiter));
if (m_header_bytes > max_header_size) {
// exceeded max header size
throw exception("Maximum header size exceeded.",
status_code::request_header_fields_too_large);
}
if (end == m_buf->end()) {
// we are out of bytes. Discard the processed bytes and copy the
// remaining unprecessed bytes to the beginning of the buffer
std::copy(begin,end,m_buf->begin());
m_buf->resize(static_cast<std::string::size_type>(end-begin));
m_read += len;
m_header_bytes -= m_buf->size();
return len;
}
//the range [begin,end) now represents a line to be processed.
if (end-begin == 0) {
// we got a blank line
if (m_state == RESPONSE_LINE) {
throw exception("Incomplete Request",status_code::bad_request);
}
// TODO: grab content-length
std::string length = get_header("Content-Length");
if (length.empty()) {
// no content length found, read indefinitely
m_read = 0;
} else {
std::istringstream ss(length);
if ((ss >> m_read).fail()) {
throw exception("Unable to parse Content-Length header",
status_code::bad_request);
}
}
m_state = BODY;
// calc header bytes processed (starting bytes - bytes left)
size_t read = (
len - static_cast<std::string::size_type>(m_buf->end() - end)
+ sizeof(header_delimiter) - 1
);
// if there were bytes left process them as body bytes
if (read < len) {
read += this->process_body(buf+read,(len-read));
}
// frees memory used temporarily during header parsing
m_buf.reset();
return read;
} else {
if (m_state == RESPONSE_LINE) {
this->process(begin,end);
m_state = HEADERS;
} else {
this->process_header(begin,end);
}
}
begin = end+(sizeof(header_delimiter) - 1);
}
}
inline size_t response::consume(std::istream & s) {
char buf[istream_buffer];
size_t bytes_read;
size_t bytes_processed;
size_t total = 0;
while (s.good()) {
s.getline(buf,istream_buffer);
bytes_read = static_cast<size_t>(s.gcount());
if (s.fail() || s.eof()) {
bytes_processed = this->consume(buf,bytes_read);
total += bytes_processed;
if (bytes_processed != bytes_read) {
// problem
break;
}
} else if (s.bad()) {
// problem
break;
} else {
// the delimiting newline was found. Replace the trailing null with
// the newline that was discarded, since our raw consume function
// expects the newline to be be there.
buf[bytes_read-1] = '\n';
bytes_processed = this->consume(buf,bytes_read);
total += bytes_processed;
if (bytes_processed != bytes_read) {
// problem
break;
}
}
}
return total;
}
inline std::string response::raw() const {
// TODO: validation. Make sure all required fields have been set?
std::stringstream ret;
ret << get_version() << " " << m_status_code << " " << m_status_msg;
ret << "\r\n" << raw_headers() << "\r\n";
ret << m_body;
return ret.str();
}
inline void response::set_status(status_code::value code) {
// TODO: validation?
m_status_code = code;
m_status_msg = get_string(code);
}
inline void response::set_status(status_code::value code, std::string const &
msg)
{
// TODO: validation?
m_status_code = code;
m_status_msg = msg;
}
inline void response::process(std::string::iterator begin,
std::string::iterator end)
{
std::string::iterator cursor_start = begin;
std::string::iterator cursor_end = std::find(begin,end,' ');
if (cursor_end == end) {
throw exception("Invalid response line",status_code::bad_request);
}
set_version(std::string(cursor_start,cursor_end));
cursor_start = cursor_end+1;
cursor_end = std::find(cursor_start,end,' ');
if (cursor_end == end) {
throw exception("Invalid request line",status_code::bad_request);
}
int code;
std::istringstream ss(std::string(cursor_start,cursor_end));
if ((ss >> code).fail()) {
throw exception("Unable to parse response code",status_code::bad_request);
}
set_status(status_code::value(code),std::string(cursor_end+1,end));
}
inline size_t response::process_body(char const * buf, size_t len) {
// If no content length was set then we read forever and never set m_ready
if (m_read == 0) {
//m_body.append(buf,len);
//return len;
m_state = DONE;
return 0;
}
// Otherwise m_read is the number of bytes left.
size_t to_read;
if (len >= m_read) {
// if we have more bytes than we need read, read only the amount needed
// then set done state
to_read = m_read;
m_state = DONE;
} else {
// we need more bytes than are available, read them all
to_read = len;
}
m_body.append(buf,to_read);
m_read -= to_read;
return to_read;
}
} // namespace parser
} // namespace http
} // namespace websocketpp
#endif // HTTP_PARSER_RESPONSE_IMPL_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -1,124 +1,124 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_PARSER_REQUEST_HPP
#define HTTP_PARSER_REQUEST_HPP
#include <string>
#include <websocketpp/common/memory.hpp>
#include <websocketpp/http/parser.hpp>
namespace websocketpp {
namespace http {
namespace parser {
/// Stores, parses, and manipulates HTTP requests
/**
* http::request provides the following functionality for working with HTTP
* requests.
*
* - Initialize request via manually setting each element
* - Initialize request via reading raw bytes and parsing
* - Once initialized, access individual parsed elements
* - Once initialized, read entire request as raw bytes
*/
class request : public parser {
public:
typedef request type;
typedef lib::shared_ptr<type> ptr;
request()
: m_buf(lib::make_shared<std::string>())
, m_ready(false) {}
/// Process bytes in the input buffer
/**
* Process up to len bytes from input buffer buf. Returns the number of
* bytes processed. Bytes left unprocessed means bytes left over after the
* final header delimiters.
*
* Consume is a streaming processor. It may be called multiple times on one
* request and the full headers need not be available before processing can
* begin. If the end of the request was reached during this call to consume
* the ready flag will be set. Further calls to consume once ready will be
* ignored.
*
* Consume will throw an http::exception in the case of an error. Typical
* error reasons include malformed requests, incomplete requests, and max
* header size being reached.
*
* @param buf Pointer to byte buffer
* @param len Size of byte buffer
* @return Number of bytes processed.
*/
size_t consume(char const * buf, size_t len);
/// Returns whether or not the request is ready for reading.
bool ready() const {
return m_ready;
}
/// Returns the full raw request (including the body)
std::string raw() const;
/// Returns the raw request headers only (similar to an HTTP HEAD request)
std::string raw_head() const;
/// Set the HTTP method. Must be a valid HTTP token
void set_method(std::string const & method);
/// Return the request method
std::string const & get_method() const {
return m_method;
}
/// Set the HTTP uri. Must be a valid HTTP uri
void set_uri(std::string const & uri);
/// Return the requested URI
std::string const & get_uri() const {
return m_uri;
}
private:
/// Helper function for message::consume. Process request line
void process(std::string::iterator begin, std::string::iterator end);
lib::shared_ptr<std::string> m_buf;
std::string m_method;
std::string m_uri;
bool m_ready;
};
} // namespace parser
} // namespace http
} // namespace websocketpp
#include <websocketpp/http/impl/request.hpp>
#endif // HTTP_PARSER_REQUEST_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_PARSER_REQUEST_HPP
#define HTTP_PARSER_REQUEST_HPP
#include <string>
#include <websocketpp/common/memory.hpp>
#include <websocketpp/http/parser.hpp>
namespace websocketpp {
namespace http {
namespace parser {
/// Stores, parses, and manipulates HTTP requests
/**
* http::request provides the following functionality for working with HTTP
* requests.
*
* - Initialize request via manually setting each element
* - Initialize request via reading raw bytes and parsing
* - Once initialized, access individual parsed elements
* - Once initialized, read entire request as raw bytes
*/
class request : public parser {
public:
typedef request type;
typedef lib::shared_ptr<type> ptr;
request()
: m_buf(lib::make_shared<std::string>())
, m_ready(false) {}
/// Process bytes in the input buffer
/**
* Process up to len bytes from input buffer buf. Returns the number of
* bytes processed. Bytes left unprocessed means bytes left over after the
* final header delimiters.
*
* Consume is a streaming processor. It may be called multiple times on one
* request and the full headers need not be available before processing can
* begin. If the end of the request was reached during this call to consume
* the ready flag will be set. Further calls to consume once ready will be
* ignored.
*
* Consume will throw an http::exception in the case of an error. Typical
* error reasons include malformed requests, incomplete requests, and max
* header size being reached.
*
* @param buf Pointer to byte buffer
* @param len Size of byte buffer
* @return Number of bytes processed.
*/
size_t consume(char const * buf, size_t len);
/// Returns whether or not the request is ready for reading.
bool ready() const {
return m_ready;
}
/// Returns the full raw request (including the body)
std::string raw() const;
/// Returns the raw request headers only (similar to an HTTP HEAD request)
std::string raw_head() const;
/// Set the HTTP method. Must be a valid HTTP token
void set_method(std::string const & method);
/// Return the request method
std::string const & get_method() const {
return m_method;
}
/// Set the HTTP uri. Must be a valid HTTP uri
void set_uri(std::string const & uri);
/// Return the requested URI
std::string const & get_uri() const {
return m_uri;
}
private:
/// Helper function for message::consume. Process request line
void process(std::string::iterator begin, std::string::iterator end);
lib::shared_ptr<std::string> m_buf;
std::string m_method;
std::string m_uri;
bool m_ready;
};
} // namespace parser
} // namespace http
} // namespace websocketpp
#include <websocketpp/http/impl/request.hpp>
#endif // HTTP_PARSER_REQUEST_HPP

View File

@@ -1,188 +1,188 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_PARSER_RESPONSE_HPP
#define HTTP_PARSER_RESPONSE_HPP
#include <iostream>
#include <string>
#include <websocketpp/http/parser.hpp>
namespace websocketpp {
namespace http {
namespace parser {
/// Stores, parses, and manipulates HTTP responses
/**
* http::response provides the following functionality for working with HTTP
* responses.
*
* - Initialize response via manually setting each element
* - Initialize response via reading raw bytes and parsing
* - Once initialized, access individual parsed elements
* - Once initialized, read entire response as raw bytes
*
* http::response checks for header completeness separately from the full
* response. Once the header is complete, the Content-Length header is read to
* determine when to stop reading body bytes. If no Content-Length is present
* ready() will never return true. It is the responsibility of the caller to
* consume to determine when the response is complete (ie when the connection
* terminates, or some other metric).
*/
class response : public parser {
public:
typedef response type;
typedef lib::shared_ptr<type> ptr;
response()
: m_read(0)
, m_buf(lib::make_shared<std::string>())
, m_status_code(status_code::uninitialized)
, m_state(RESPONSE_LINE) {}
/// Process bytes in the input buffer
/**
* Process up to len bytes from input buffer buf. Returns the number of
* bytes processed. Bytes left unprocessed means bytes left over after the
* final header delimiters.
*
* Consume is a streaming processor. It may be called multiple times on one
* response and the full headers need not be available before processing can
* begin. If the end of the response was reached during this call to consume
* the ready flag will be set. Further calls to consume once ready will be
* ignored.
*
* Consume will throw an http::exception in the case of an error. Typical
* error reasons include malformed responses, incomplete responses, and max
* header size being reached.
*
* @param buf Pointer to byte buffer
* @param len Size of byte buffer
* @return Number of bytes processed.
*/
size_t consume(char const * buf, size_t len);
/// Process bytes in the input buffer (istream version)
/**
* Process bytes from istream s. Returns the number of bytes processed.
* Bytes left unprocessed means bytes left over after the final header
* delimiters.
*
* Consume is a streaming processor. It may be called multiple times on one
* response and the full headers need not be available before processing can
* begin. If the end of the response was reached during this call to consume
* the ready flag will be set. Further calls to consume once ready will be
* ignored.
*
* Consume will throw an http::exception in the case of an error. Typical
* error reasons include malformed responses, incomplete responses, and max
* header size being reached.
*
* @param buf Pointer to byte buffer
* @param len Size of byte buffer
* @return Number of bytes processed.
*/
size_t consume(std::istream & s);
/// Returns true if the response is ready.
/**
* @note will never return true if the content length header is not present
*/
bool ready() const {
return m_state == DONE;
}
/// Returns true if the response headers are fully parsed.
bool headers_ready() const {
return (m_state == BODY || m_state == DONE);
}
/// Returns the full raw response
std::string raw() const;
/// Set response status code and message
/**
* Sets the response status code to `code` and looks up the corresponding
* message for standard codes. Non-standard codes will be entered as Unknown
* use set_status(status_code::value,std::string) overload to set both
* values explicitly.
*
* @param code Code to set
* @param msg Message to set
*/
void set_status(status_code::value code);
/// Set response status code and message
/**
* Sets the response status code and message to independent custom values.
* use set_status(status_code::value) to set the code and have the standard
* message be automatically set.
*
* @param code Code to set
* @param msg Message to set
*/
void set_status(status_code::value code, std::string const & msg);
/// Return the response status code
status_code::value get_status_code() const {
return m_status_code;
}
/// Return the response status message
const std::string& get_status_msg() const {
return m_status_msg;
}
private:
/// Helper function for consume. Process response line
void process(std::string::iterator begin, std::string::iterator end);
/// Helper function for processing body bytes
size_t process_body(char const * buf, size_t len);
enum state {
RESPONSE_LINE = 0,
HEADERS = 1,
BODY = 2,
DONE = 3
};
std::string m_status_msg;
size_t m_read;
lib::shared_ptr<std::string> m_buf;
status_code::value m_status_code;
state m_state;
};
} // namespace parser
} // namespace http
} // namespace websocketpp
#include <websocketpp/http/impl/response.hpp>
#endif // HTTP_PARSER_RESPONSE_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HTTP_PARSER_RESPONSE_HPP
#define HTTP_PARSER_RESPONSE_HPP
#include <iostream>
#include <string>
#include <websocketpp/http/parser.hpp>
namespace websocketpp {
namespace http {
namespace parser {
/// Stores, parses, and manipulates HTTP responses
/**
* http::response provides the following functionality for working with HTTP
* responses.
*
* - Initialize response via manually setting each element
* - Initialize response via reading raw bytes and parsing
* - Once initialized, access individual parsed elements
* - Once initialized, read entire response as raw bytes
*
* http::response checks for header completeness separately from the full
* response. Once the header is complete, the Content-Length header is read to
* determine when to stop reading body bytes. If no Content-Length is present
* ready() will never return true. It is the responsibility of the caller to
* consume to determine when the response is complete (ie when the connection
* terminates, or some other metric).
*/
class response : public parser {
public:
typedef response type;
typedef lib::shared_ptr<type> ptr;
response()
: m_read(0)
, m_buf(lib::make_shared<std::string>())
, m_status_code(status_code::uninitialized)
, m_state(RESPONSE_LINE) {}
/// Process bytes in the input buffer
/**
* Process up to len bytes from input buffer buf. Returns the number of
* bytes processed. Bytes left unprocessed means bytes left over after the
* final header delimiters.
*
* Consume is a streaming processor. It may be called multiple times on one
* response and the full headers need not be available before processing can
* begin. If the end of the response was reached during this call to consume
* the ready flag will be set. Further calls to consume once ready will be
* ignored.
*
* Consume will throw an http::exception in the case of an error. Typical
* error reasons include malformed responses, incomplete responses, and max
* header size being reached.
*
* @param buf Pointer to byte buffer
* @param len Size of byte buffer
* @return Number of bytes processed.
*/
size_t consume(char const * buf, size_t len);
/// Process bytes in the input buffer (istream version)
/**
* Process bytes from istream s. Returns the number of bytes processed.
* Bytes left unprocessed means bytes left over after the final header
* delimiters.
*
* Consume is a streaming processor. It may be called multiple times on one
* response and the full headers need not be available before processing can
* begin. If the end of the response was reached during this call to consume
* the ready flag will be set. Further calls to consume once ready will be
* ignored.
*
* Consume will throw an http::exception in the case of an error. Typical
* error reasons include malformed responses, incomplete responses, and max
* header size being reached.
*
* @param buf Pointer to byte buffer
* @param len Size of byte buffer
* @return Number of bytes processed.
*/
size_t consume(std::istream & s);
/// Returns true if the response is ready.
/**
* @note will never return true if the content length header is not present
*/
bool ready() const {
return m_state == DONE;
}
/// Returns true if the response headers are fully parsed.
bool headers_ready() const {
return (m_state == BODY || m_state == DONE);
}
/// Returns the full raw response
std::string raw() const;
/// Set response status code and message
/**
* Sets the response status code to `code` and looks up the corresponding
* message for standard codes. Non-standard codes will be entered as Unknown
* use set_status(status_code::value,std::string) overload to set both
* values explicitly.
*
* @param code Code to set
* @param msg Message to set
*/
void set_status(status_code::value code);
/// Set response status code and message
/**
* Sets the response status code and message to independent custom values.
* use set_status(status_code::value) to set the code and have the standard
* message be automatically set.
*
* @param code Code to set
* @param msg Message to set
*/
void set_status(status_code::value code, std::string const & msg);
/// Return the response status code
status_code::value get_status_code() const {
return m_status_code;
}
/// Return the response status message
const std::string& get_status_msg() const {
return m_status_msg;
}
private:
/// Helper function for consume. Process response line
void process(std::string::iterator begin, std::string::iterator end);
/// Helper function for processing body bytes
size_t process_body(char const * buf, size_t len);
enum state {
RESPONSE_LINE = 0,
HEADERS = 1,
BODY = 2,
DONE = 3
};
std::string m_status_msg;
size_t m_read;
lib::shared_ptr<std::string> m_buf;
status_code::value m_status_code;
state m_state;
};
} // namespace parser
} // namespace http
} // namespace websocketpp
#include <websocketpp/http/impl/response.hpp>
#endif // HTTP_PARSER_RESPONSE_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -1,269 +1,269 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_ENDPOINT_IMPL_HPP
#define WEBSOCKETPP_ENDPOINT_IMPL_HPP
#include <string>
namespace websocketpp {
template <typename connection, typename config>
typename endpoint<connection,config>::connection_ptr
endpoint<connection,config>::create_connection() {
m_alog->write(log::alevel::devel,"create_connection");
//scoped_lock_type lock(m_state_lock);
/*if (m_state == STOPPING || m_state == STOPPED) {
return connection_ptr();
}*/
//scoped_lock_type guard(m_mutex);
// Create a connection on the heap and manage it using a shared pointer
connection_ptr con = lib::make_shared<connection_type>(m_is_server,
m_user_agent, m_alog, m_elog, lib::ref(m_rng));
connection_weak_ptr w(con);
// Create a weak pointer on the heap using that shared_ptr.
// Cast that weak pointer to void* and manage it using another shared_ptr
// connection_hdl hdl(reinterpret_cast<void*>(new connection_weak_ptr(con)));
con->set_handle(w);
// Copy default handlers from the endpoint
con->set_open_handler(m_open_handler);
con->set_close_handler(m_close_handler);
con->set_fail_handler(m_fail_handler);
con->set_ping_handler(m_ping_handler);
con->set_pong_handler(m_pong_handler);
con->set_pong_timeout_handler(m_pong_timeout_handler);
con->set_interrupt_handler(m_interrupt_handler);
con->set_http_handler(m_http_handler);
con->set_validate_handler(m_validate_handler);
con->set_message_handler(m_message_handler);
if (m_open_handshake_timeout_dur != config::timeout_open_handshake) {
con->set_open_handshake_timeout(m_open_handshake_timeout_dur);
}
if (m_close_handshake_timeout_dur != config::timeout_close_handshake) {
con->set_close_handshake_timeout(m_close_handshake_timeout_dur);
}
if (m_pong_timeout_dur != config::timeout_pong) {
con->set_pong_timeout(m_pong_timeout_dur);
}
if (m_max_message_size != config::max_message_size) {
con->set_max_message_size(m_max_message_size);
}
con->set_max_http_body_size(m_max_http_body_size);
lib::error_code ec;
ec = transport_type::init(con);
if (ec) {
m_elog->write(log::elevel::fatal,ec.message());
return connection_ptr();
}
return con;
}
template <typename connection, typename config>
void endpoint<connection,config>::interrupt(connection_hdl hdl, lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
m_alog->write(log::alevel::devel,"Interrupting connection");
ec = con->interrupt();
}
template <typename connection, typename config>
void endpoint<connection,config>::interrupt(connection_hdl hdl) {
lib::error_code ec;
interrupt(hdl,ec);
if (ec) { throw exception(ec); }
}
template <typename connection, typename config>
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_http_response(connection_hdl hdl,
lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
con->send_http_response(ec);
}
template <typename connection, typename config>
void endpoint<connection,config>::send_http_response(connection_hdl hdl) {
lib::error_code ec;
send_http_response(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;}
ec = con->send(payload,op);
}
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;
send(hdl,payload,op,ec);
if (ec) { throw exception(ec); }
}
template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
size_t len, frame::opcode::value op, lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
ec = con->send(payload,len,op);
}
template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
size_t len, frame::opcode::value op)
{
lib::error_code ec;
send(hdl,payload,len,op,ec);
if (ec) { throw exception(ec); }
}
template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg,
lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
ec = con->send(msg);
}
template <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 exception(ec); }
}
template <typename connection, typename config>
void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
const code, std::string const & reason,
lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
con->close(code,reason,ec);
}
template <typename connection, typename config>
void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
const code, std::string const & reason)
{
lib::error_code ec;
close(hdl,code,reason,ec);
if (ec) { throw exception(ec); }
}
template <typename connection, typename config>
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
payload, lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
con->ping(payload,ec);
}
template <typename connection, typename config>
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload)
{
lib::error_code ec;
ping(hdl,payload,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)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
con->pong(payload,ec);
}
template <typename connection, typename config>
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload)
{
lib::error_code ec;
pong(hdl,payload,ec);
if (ec) { throw exception(ec); }
}
} // namespace websocketpp
#endif // WEBSOCKETPP_ENDPOINT_IMPL_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_ENDPOINT_IMPL_HPP
#define WEBSOCKETPP_ENDPOINT_IMPL_HPP
#include <string>
namespace websocketpp {
template <typename connection, typename config>
typename endpoint<connection,config>::connection_ptr
endpoint<connection,config>::create_connection() {
m_alog->write(log::alevel::devel,"create_connection");
//scoped_lock_type lock(m_state_lock);
/*if (m_state == STOPPING || m_state == STOPPED) {
return connection_ptr();
}*/
//scoped_lock_type guard(m_mutex);
// Create a connection on the heap and manage it using a shared pointer
connection_ptr con = lib::make_shared<connection_type>(m_is_server,
m_user_agent, m_alog, m_elog, lib::ref(m_rng));
connection_weak_ptr w(con);
// Create a weak pointer on the heap using that shared_ptr.
// Cast that weak pointer to void* and manage it using another shared_ptr
// connection_hdl hdl(reinterpret_cast<void*>(new connection_weak_ptr(con)));
con->set_handle(w);
// Copy default handlers from the endpoint
con->set_open_handler(m_open_handler);
con->set_close_handler(m_close_handler);
con->set_fail_handler(m_fail_handler);
con->set_ping_handler(m_ping_handler);
con->set_pong_handler(m_pong_handler);
con->set_pong_timeout_handler(m_pong_timeout_handler);
con->set_interrupt_handler(m_interrupt_handler);
con->set_http_handler(m_http_handler);
con->set_validate_handler(m_validate_handler);
con->set_message_handler(m_message_handler);
if (m_open_handshake_timeout_dur != config::timeout_open_handshake) {
con->set_open_handshake_timeout(m_open_handshake_timeout_dur);
}
if (m_close_handshake_timeout_dur != config::timeout_close_handshake) {
con->set_close_handshake_timeout(m_close_handshake_timeout_dur);
}
if (m_pong_timeout_dur != config::timeout_pong) {
con->set_pong_timeout(m_pong_timeout_dur);
}
if (m_max_message_size != config::max_message_size) {
con->set_max_message_size(m_max_message_size);
}
con->set_max_http_body_size(m_max_http_body_size);
lib::error_code ec;
ec = transport_type::init(con);
if (ec) {
m_elog->write(log::elevel::fatal,ec.message());
return connection_ptr();
}
return con;
}
template <typename connection, typename config>
void endpoint<connection,config>::interrupt(connection_hdl hdl, lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
m_alog->write(log::alevel::devel,"Interrupting connection");
ec = con->interrupt();
}
template <typename connection, typename config>
void endpoint<connection,config>::interrupt(connection_hdl hdl) {
lib::error_code ec;
interrupt(hdl,ec);
if (ec) { throw exception(ec); }
}
template <typename connection, typename config>
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_http_response(connection_hdl hdl,
lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
con->send_http_response(ec);
}
template <typename connection, typename config>
void endpoint<connection,config>::send_http_response(connection_hdl hdl) {
lib::error_code ec;
send_http_response(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;}
ec = con->send(payload,op);
}
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;
send(hdl,payload,op,ec);
if (ec) { throw exception(ec); }
}
template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
size_t len, frame::opcode::value op, lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
ec = con->send(payload,len,op);
}
template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
size_t len, frame::opcode::value op)
{
lib::error_code ec;
send(hdl,payload,len,op,ec);
if (ec) { throw exception(ec); }
}
template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg,
lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
ec = con->send(msg);
}
template <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 exception(ec); }
}
template <typename connection, typename config>
void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
const code, std::string const & reason,
lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
con->close(code,reason,ec);
}
template <typename connection, typename config>
void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
const code, std::string const & reason)
{
lib::error_code ec;
close(hdl,code,reason,ec);
if (ec) { throw exception(ec); }
}
template <typename connection, typename config>
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
payload, lib::error_code & ec)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
con->ping(payload,ec);
}
template <typename connection, typename config>
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload)
{
lib::error_code ec;
ping(hdl,payload,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)
{
connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;}
con->pong(payload,ec);
}
template <typename connection, typename config>
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload)
{
lib::error_code ec;
pong(hdl,payload,ec);
if (ec) { throw exception(ec); }
}
} // namespace websocketpp
#endif // WEBSOCKETPP_ENDPOINT_IMPL_HPP

View File

@@ -1,87 +1,87 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_UTILITIES_IMPL_HPP
#define WEBSOCKETPP_UTILITIES_IMPL_HPP
#include <algorithm>
#include <string>
namespace websocketpp {
namespace utility {
inline std::string to_lower(std::string const & in) {
std::string out = in;
std::transform(out.begin(),out.end(),out.begin(),::tolower);
return out;
}
inline std::string to_hex(std::string const & input) {
std::string output;
std::string hex = "0123456789ABCDEF";
for (size_t i = 0; i < input.size(); i++) {
output += hex[(input[i] & 0xF0) >> 4];
output += hex[input[i] & 0x0F];
output += " ";
}
return output;
}
inline std::string to_hex(uint8_t const * input, size_t length) {
std::string output;
std::string hex = "0123456789ABCDEF";
for (size_t i = 0; i < length; i++) {
output += hex[(input[i] & 0xF0) >> 4];
output += hex[input[i] & 0x0F];
output += " ";
}
return output;
}
inline std::string to_hex(const char* input,size_t length) {
return to_hex(reinterpret_cast<const uint8_t*>(input),length);
}
inline std::string string_replace_all(std::string subject, std::string const &
search, std::string const & replace)
{
size_t pos = 0;
while((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
return subject;
}
} // namespace utility
} // namespace websocketpp
#endif // WEBSOCKETPP_UTILITIES_IMPL_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_UTILITIES_IMPL_HPP
#define WEBSOCKETPP_UTILITIES_IMPL_HPP
#include <algorithm>
#include <string>
namespace websocketpp {
namespace utility {
inline std::string to_lower(std::string const & in) {
std::string out = in;
std::transform(out.begin(),out.end(),out.begin(),::tolower);
return out;
}
inline std::string to_hex(std::string const & input) {
std::string output;
std::string hex = "0123456789ABCDEF";
for (size_t i = 0; i < input.size(); i++) {
output += hex[(input[i] & 0xF0) >> 4];
output += hex[input[i] & 0x0F];
output += " ";
}
return output;
}
inline std::string to_hex(uint8_t const * input, size_t length) {
std::string output;
std::string hex = "0123456789ABCDEF";
for (size_t i = 0; i < length; i++) {
output += hex[(input[i] & 0xF0) >> 4];
output += hex[input[i] & 0x0F];
output += " ";
}
return output;
}
inline std::string to_hex(const char* input,size_t length) {
return to_hex(reinterpret_cast<const uint8_t*>(input),length);
}
inline std::string string_replace_all(std::string subject, std::string const &
search, std::string const & replace)
{
size_t pos = 0;
while((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
return subject;
}
} // namespace utility
} // namespace websocketpp
#endif // WEBSOCKETPP_UTILITIES_IMPL_HPP

View File

@@ -1,199 +1,199 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_LOGGER_BASIC_HPP
#define WEBSOCKETPP_LOGGER_BASIC_HPP
/* Need a way to print a message to the log
*
* - timestamps
* - channels
* - thread safe
* - output to stdout or file
* - selective output channels, both compile time and runtime
* - named channels
* - ability to test whether a log message will be printed at compile time
*
*/
#include <websocketpp/logger/levels.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp>
#include <websocketpp/common/time.hpp>
#include <ctime>
#include <iostream>
#include <iomanip>
#include <string>
namespace websocketpp {
namespace log {
/// Basic logger that outputs to an ostream
template <typename concurrency, typename names>
class basic {
public:
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, 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) {}
/// Destructor
~basic<concurrency,names>() {}
/// Copy constructor
basic<concurrency,names>(basic<concurrency,names> const & other)
: m_static_channels(other.m_static_channels)
, m_dynamic_channels(other.m_dynamic_channels)
, m_out(other.m_out)
{}
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
// no copy assignment operator because of const member variables
basic<concurrency,names> & operator=(basic<concurrency,names> const &) = delete;
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
/// Move constructor
basic<concurrency,names>(basic<concurrency,names> && other)
: m_static_channels(other.m_static_channels)
, m_dynamic_channels(other.m_dynamic_channels)
, m_out(other.m_out)
{}
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
// no move assignment operator because of const member variables
basic<concurrency,names> & operator=(basic<concurrency,names> &&) = delete;
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
void set_ostream(std::ostream * out = &std::cout) {
m_out = out;
}
void set_channels(level channels) {
if (channels == names::none) {
clear_channels(names::all);
return;
}
scoped_lock_type lock(m_lock);
m_dynamic_channels |= (channels & m_static_channels);
}
void clear_channels(level channels) {
scoped_lock_type lock(m_lock);
m_dynamic_channels &= ~channels;
}
/// Write a string message to the given channel
/**
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level channel, std::string const & msg) {
scoped_lock_type lock(m_lock);
if (!this->dynamic_test(channel)) { return; }
*m_out << "[" << timestamp << "] "
<< "[" << names::channel_name(channel) << "] "
<< msg << "\n";
m_out->flush();
}
/// Write a cstring message to the given channel
/**
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level channel, char const * msg) {
scoped_lock_type lock(m_lock);
if (!this->dynamic_test(channel)) { return; }
*m_out << "[" << timestamp << "] "
<< "[" << names::channel_name(channel) << "] "
<< msg << "\n";
m_out->flush();
}
_WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level channel) const {
return ((channel & m_static_channels) != 0);
}
bool dynamic_test(level channel) {
return ((channel & m_dynamic_channels) != 0);
}
protected:
typedef typename concurrency::scoped_lock_type scoped_lock_type;
typedef typename concurrency::mutex_type mutex_type;
mutex_type m_lock;
private:
// The timestamp does not include the time zone, because on Windows with the
// default registry settings, the time zone would be written out in full,
// which would be obnoxiously verbose.
//
// TODO: find a workaround for this or make this format user settable
static std::ostream & timestamp(std::ostream & os) {
std::time_t t = std::time(NULL);
std::tm lt = lib::localtime(t);
#ifdef _WEBSOCKETPP_PUTTIME_
return os << std::put_time(&lt,"%Y-%m-%d %H:%M:%S");
#else // Falls back to strftime, which requires a temporary copy of the string.
char buffer[20];
size_t result = std::strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",&lt);
return os << (result == 0 ? "Unknown" : buffer);
#endif
}
level const m_static_channels;
level m_dynamic_channels;
std::ostream * m_out;
};
} // log
} // websocketpp
#endif // WEBSOCKETPP_LOGGER_BASIC_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_LOGGER_BASIC_HPP
#define WEBSOCKETPP_LOGGER_BASIC_HPP
/* Need a way to print a message to the log
*
* - timestamps
* - channels
* - thread safe
* - output to stdout or file
* - selective output channels, both compile time and runtime
* - named channels
* - ability to test whether a log message will be printed at compile time
*
*/
#include <websocketpp/logger/levels.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp>
#include <websocketpp/common/time.hpp>
#include <ctime>
#include <iostream>
#include <iomanip>
#include <string>
namespace websocketpp {
namespace log {
/// Basic logger that outputs to an ostream
template <typename concurrency, typename names>
class basic {
public:
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, 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) {}
/// Destructor
~basic<concurrency,names>() {}
/// Copy constructor
basic<concurrency,names>(basic<concurrency,names> const & other)
: m_static_channels(other.m_static_channels)
, m_dynamic_channels(other.m_dynamic_channels)
, m_out(other.m_out)
{}
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
// no copy assignment operator because of const member variables
basic<concurrency,names> & operator=(basic<concurrency,names> const &) = delete;
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
/// Move constructor
basic<concurrency,names>(basic<concurrency,names> && other)
: m_static_channels(other.m_static_channels)
, m_dynamic_channels(other.m_dynamic_channels)
, m_out(other.m_out)
{}
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
// no move assignment operator because of const member variables
basic<concurrency,names> & operator=(basic<concurrency,names> &&) = delete;
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
void set_ostream(std::ostream * out = &std::cout) {
m_out = out;
}
void set_channels(level channels) {
if (channels == names::none) {
clear_channels(names::all);
return;
}
scoped_lock_type lock(m_lock);
m_dynamic_channels |= (channels & m_static_channels);
}
void clear_channels(level channels) {
scoped_lock_type lock(m_lock);
m_dynamic_channels &= ~channels;
}
/// Write a string message to the given channel
/**
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level channel, std::string const & msg) {
scoped_lock_type lock(m_lock);
if (!this->dynamic_test(channel)) { return; }
*m_out << "[" << timestamp << "] "
<< "[" << names::channel_name(channel) << "] "
<< msg << "\n";
m_out->flush();
}
/// Write a cstring message to the given channel
/**
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level channel, char const * msg) {
scoped_lock_type lock(m_lock);
if (!this->dynamic_test(channel)) { return; }
*m_out << "[" << timestamp << "] "
<< "[" << names::channel_name(channel) << "] "
<< msg << "\n";
m_out->flush();
}
_WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level channel) const {
return ((channel & m_static_channels) != 0);
}
bool dynamic_test(level channel) {
return ((channel & m_dynamic_channels) != 0);
}
protected:
typedef typename concurrency::scoped_lock_type scoped_lock_type;
typedef typename concurrency::mutex_type mutex_type;
mutex_type m_lock;
private:
// The timestamp does not include the time zone, because on Windows with the
// default registry settings, the time zone would be written out in full,
// which would be obnoxiously verbose.
//
// TODO: find a workaround for this or make this format user settable
static std::ostream & timestamp(std::ostream & os) {
std::time_t t = std::time(NULL);
std::tm lt = lib::localtime(t);
#ifdef _WEBSOCKETPP_PUTTIME_
return os << std::put_time(&lt,"%Y-%m-%d %H:%M:%S");
#else // Falls back to strftime, which requires a temporary copy of the string.
char buffer[20];
size_t result = std::strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",&lt);
return os << (result == 0 ? "Unknown" : buffer);
#endif
}
level const m_static_channels;
level m_dynamic_channels;
std::ostream * m_out;
};
} // log
} // websocketpp
#endif // WEBSOCKETPP_LOGGER_BASIC_HPP

View File

@@ -1,203 +1,203 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_LOGGER_LEVELS_HPP
#define WEBSOCKETPP_LOGGER_LEVELS_HPP
#include <websocketpp/common/stdint.hpp>
namespace websocketpp {
namespace log {
/// Type of a channel package
typedef uint32_t level;
/// Package of values for hinting at the nature of a given logger.
/**
* Used by the library to signal to the logging class a hint that it can use to
* set itself up. For example, the `access` hint indicates that it is an access
* log that might be suitable for being printed to an access log file or to cout
* whereas `error` might be suitable for an error log file or cerr.
*/
struct channel_type_hint {
/// Type of a channel type hint value
typedef uint32_t value;
/// No information
static value const none = 0;
/// Access log
static value const access = 1;
/// Error log
static value const error = 2;
};
/// Package of log levels for logging errors
struct elevel {
/// Special aggregate value representing "no levels"
static level const none = 0x0;
/// Low level debugging information (warning: very chatty)
static level const devel = 0x1;
/// Information about unusual system states or other minor internal library
/// problems, less chatty than devel.
static level const library = 0x2;
/// Information about minor configuration problems or additional information
/// about other warnings.
static level const info = 0x4;
/// Information about important problems not severe enough to terminate
/// connections.
static level const warn = 0x8;
/// Recoverable error. Recovery may mean cleanly closing the connection with
/// an appropriate error code to the remote endpoint.
static level const rerror = 0x10;
/// Unrecoverable error. This error will trigger immediate unclean
/// termination of the connection or endpoint.
static level const fatal = 0x20;
/// Special aggregate value representing "all levels"
static level const all = 0xffffffff;
/// Get the textual name of a channel given a channel id
/**
* The id must be that of a single channel. Passing an aggregate channel
* package results in undefined behavior.
*
* @param channel The channel id to look up.
*
* @return The name of the specified channel.
*/
static char const * channel_name(level channel) {
switch(channel) {
case devel:
return "devel";
case library:
return "library";
case info:
return "info";
case warn:
return "warning";
case rerror:
return "error";
case fatal:
return "fatal";
default:
return "unknown";
}
}
};
/// Package of log levels for logging access events
struct alevel {
/// Special aggregate value representing "no levels"
static level const none = 0x0;
/// Information about new connections
/**
* One line for each new connection that includes a host of information
* including: the remote address, websocket version, requested resource,
* http code, remote user agent
*/
static level const connect = 0x1;
/// One line for each closed connection. Includes closing codes and reasons.
static level const disconnect = 0x2;
/// One line per control frame
static level const control = 0x4;
/// One line per frame, includes the full frame header
static level const frame_header = 0x8;
/// One line per frame, includes the full message payload (warning: chatty)
static level const frame_payload = 0x10;
/// Reserved
static level const message_header = 0x20;
/// Reserved
static level const message_payload = 0x40;
/// Reserved
static level const endpoint = 0x80;
/// Extra information about opening handshakes
static level const debug_handshake = 0x100;
/// Extra information about closing handshakes
static level const debug_close = 0x200;
/// Development messages (warning: very chatty)
static level const devel = 0x400;
/// Special channel for application specific logs. Not used by the library.
static level const app = 0x800;
/// Access related to HTTP requests
static level const http = 0x1000;
/// One line for each failed WebSocket connection with details
static level const fail = 0x2000;
/// Aggregate package representing the commonly used core access channels
/// Connect, Disconnect, Fail, and HTTP
static level const access_core = 0x00003003;
/// Special aggregate value representing "all levels"
static level const all = 0xffffffff;
/// Get the textual name of a channel given a channel id
/**
* Get the textual name of a channel given a channel id. The id must be that
* of a single channel. Passing an aggregate channel package results in
* undefined behavior.
*
* @param channel The channelid to look up.
*
* @return The name of the specified channel.
*/
static char const * channel_name(level channel) {
switch(channel) {
case connect:
return "connect";
case disconnect:
return "disconnect";
case control:
return "control";
case frame_header:
return "frame_header";
case frame_payload:
return "frame_payload";
case message_header:
return "message_header";
case message_payload:
return "message_payload";
case endpoint:
return "endpoint";
case debug_handshake:
return "debug_handshake";
case debug_close:
return "debug_close";
case devel:
return "devel";
case app:
return "application";
case http:
return "http";
case fail:
return "fail";
default:
return "unknown";
}
}
};
} // logger
} // websocketpp
#endif //WEBSOCKETPP_LOGGER_LEVELS_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_LOGGER_LEVELS_HPP
#define WEBSOCKETPP_LOGGER_LEVELS_HPP
#include <websocketpp/common/stdint.hpp>
namespace websocketpp {
namespace log {
/// Type of a channel package
typedef uint32_t level;
/// Package of values for hinting at the nature of a given logger.
/**
* Used by the library to signal to the logging class a hint that it can use to
* set itself up. For example, the `access` hint indicates that it is an access
* log that might be suitable for being printed to an access log file or to cout
* whereas `error` might be suitable for an error log file or cerr.
*/
struct channel_type_hint {
/// Type of a channel type hint value
typedef uint32_t value;
/// No information
static value const none = 0;
/// Access log
static value const access = 1;
/// Error log
static value const error = 2;
};
/// Package of log levels for logging errors
struct elevel {
/// Special aggregate value representing "no levels"
static level const none = 0x0;
/// Low level debugging information (warning: very chatty)
static level const devel = 0x1;
/// Information about unusual system states or other minor internal library
/// problems, less chatty than devel.
static level const library = 0x2;
/// Information about minor configuration problems or additional information
/// about other warnings.
static level const info = 0x4;
/// Information about important problems not severe enough to terminate
/// connections.
static level const warn = 0x8;
/// Recoverable error. Recovery may mean cleanly closing the connection with
/// an appropriate error code to the remote endpoint.
static level const rerror = 0x10;
/// Unrecoverable error. This error will trigger immediate unclean
/// termination of the connection or endpoint.
static level const fatal = 0x20;
/// Special aggregate value representing "all levels"
static level const all = 0xffffffff;
/// Get the textual name of a channel given a channel id
/**
* The id must be that of a single channel. Passing an aggregate channel
* package results in undefined behavior.
*
* @param channel The channel id to look up.
*
* @return The name of the specified channel.
*/
static char const * channel_name(level channel) {
switch(channel) {
case devel:
return "devel";
case library:
return "library";
case info:
return "info";
case warn:
return "warning";
case rerror:
return "error";
case fatal:
return "fatal";
default:
return "unknown";
}
}
};
/// Package of log levels for logging access events
struct alevel {
/// Special aggregate value representing "no levels"
static level const none = 0x0;
/// Information about new connections
/**
* One line for each new connection that includes a host of information
* including: the remote address, websocket version, requested resource,
* http code, remote user agent
*/
static level const connect = 0x1;
/// One line for each closed connection. Includes closing codes and reasons.
static level const disconnect = 0x2;
/// One line per control frame
static level const control = 0x4;
/// One line per frame, includes the full frame header
static level const frame_header = 0x8;
/// One line per frame, includes the full message payload (warning: chatty)
static level const frame_payload = 0x10;
/// Reserved
static level const message_header = 0x20;
/// Reserved
static level const message_payload = 0x40;
/// Reserved
static level const endpoint = 0x80;
/// Extra information about opening handshakes
static level const debug_handshake = 0x100;
/// Extra information about closing handshakes
static level const debug_close = 0x200;
/// Development messages (warning: very chatty)
static level const devel = 0x400;
/// Special channel for application specific logs. Not used by the library.
static level const app = 0x800;
/// Access related to HTTP requests
static level const http = 0x1000;
/// One line for each failed WebSocket connection with details
static level const fail = 0x2000;
/// Aggregate package representing the commonly used core access channels
/// Connect, Disconnect, Fail, and HTTP
static level const access_core = 0x00003003;
/// Special aggregate value representing "all levels"
static level const all = 0xffffffff;
/// Get the textual name of a channel given a channel id
/**
* Get the textual name of a channel given a channel id. The id must be that
* of a single channel. Passing an aggregate channel package results in
* undefined behavior.
*
* @param channel The channelid to look up.
*
* @return The name of the specified channel.
*/
static char const * channel_name(level channel) {
switch(channel) {
case connect:
return "connect";
case disconnect:
return "disconnect";
case control:
return "control";
case frame_header:
return "frame_header";
case frame_payload:
return "frame_payload";
case message_header:
return "message_header";
case message_payload:
return "message_payload";
case endpoint:
return "endpoint";
case debug_handshake:
return "debug_handshake";
case debug_close:
return "debug_close";
case devel:
return "devel";
case app:
return "application";
case http:
return "http";
case fail:
return "fail";
default:
return "unknown";
}
}
};
} // logger
} // websocketpp
#endif //WEBSOCKETPP_LOGGER_LEVELS_HPP

View File

@@ -1,119 +1,119 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_LOGGER_STUB_HPP
#define WEBSOCKETPP_LOGGER_STUB_HPP
#include <websocketpp/logger/levels.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <string>
namespace websocketpp {
namespace log {
/// Stub logger that ignores all input
class stub {
public:
/// Construct the logger
/**
* @param hint A channel type specific hint for how to construct the logger
*/
explicit stub(channel_type_hint::value) {}
/// Construct the logger
/**
* @param default_channels A set of channels to statically enable
* @param hint A channel type specific hint for how to construct the logger
*/
stub(level, channel_type_hint::value) {}
_WEBSOCKETPP_CONSTEXPR_TOKEN_ stub() {}
/// Dynamically enable the given list of channels
/**
* All operations on the stub logger are no-ops and all arguments are
* ignored
*
* @param channels The package of channels to enable
*/
void set_channels(level) {}
/// Dynamically disable the given list of channels
/**
* All operations on the stub logger are no-ops and all arguments are
* ignored
*
* @param channels The package of channels to disable
*/
void clear_channels(level) {}
/// Write a string message to the given channel
/**
* Writing on the stub logger is a no-op and all arguments are ignored
*
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level, std::string const &) {}
/// Write a cstring message to the given channel
/**
* Writing on the stub logger is a no-op and all arguments are ignored
*
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level, char const *) {}
/// Test whether a channel is statically enabled
/**
* The stub logger has no channels so all arguments are ignored and
* `static_test` always returns false.
*
* @param channel The package of channels to test
*/
_WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level) const {
return false;
}
/// Test whether a channel is dynamically enabled
/**
* The stub logger has no channels so all arguments are ignored and
* `dynamic_test` always returns false.
*
* @param channel The package of channels to test
*/
bool dynamic_test(level) {
return false;
}
};
} // log
} // websocketpp
#endif // WEBSOCKETPP_LOGGER_STUB_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_LOGGER_STUB_HPP
#define WEBSOCKETPP_LOGGER_STUB_HPP
#include <websocketpp/logger/levels.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <string>
namespace websocketpp {
namespace log {
/// Stub logger that ignores all input
class stub {
public:
/// Construct the logger
/**
* @param hint A channel type specific hint for how to construct the logger
*/
explicit stub(channel_type_hint::value) {}
/// Construct the logger
/**
* @param default_channels A set of channels to statically enable
* @param hint A channel type specific hint for how to construct the logger
*/
stub(level, channel_type_hint::value) {}
_WEBSOCKETPP_CONSTEXPR_TOKEN_ stub() {}
/// Dynamically enable the given list of channels
/**
* All operations on the stub logger are no-ops and all arguments are
* ignored
*
* @param channels The package of channels to enable
*/
void set_channels(level) {}
/// Dynamically disable the given list of channels
/**
* All operations on the stub logger are no-ops and all arguments are
* ignored
*
* @param channels The package of channels to disable
*/
void clear_channels(level) {}
/// Write a string message to the given channel
/**
* Writing on the stub logger is a no-op and all arguments are ignored
*
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level, std::string const &) {}
/// Write a cstring message to the given channel
/**
* Writing on the stub logger is a no-op and all arguments are ignored
*
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level, char const *) {}
/// Test whether a channel is statically enabled
/**
* The stub logger has no channels so all arguments are ignored and
* `static_test` always returns false.
*
* @param channel The package of channels to test
*/
_WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level) const {
return false;
}
/// Test whether a channel is dynamically enabled
/**
* The stub logger has no channels so all arguments are ignored and
* `dynamic_test` always returns false.
*
* @param channel The package of channels to test
*/
bool dynamic_test(level) {
return false;
}
};
} // log
} // websocketpp
#endif // WEBSOCKETPP_LOGGER_STUB_HPP

View File

@@ -1,146 +1,146 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* The initial version of this logging policy was contributed to the WebSocket++
* project by Tom Hughes.
*/
#ifndef WEBSOCKETPP_LOGGER_SYSLOG_HPP
#define WEBSOCKETPP_LOGGER_SYSLOG_HPP
#include <syslog.h>
#include <websocketpp/logger/basic.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/logger/levels.hpp>
namespace websocketpp {
namespace log {
/// Basic logger that outputs to syslog
template <typename concurrency, typename names>
class syslog : public basic<concurrency, names> {
public:
typedef basic<concurrency, names> base;
/// Construct the logger
/**
* @param hint A channel type specific hint for how to construct the logger
*/
syslog<concurrency,names>(channel_type_hint::value hint =
channel_type_hint::access)
: basic<concurrency,names>(hint), m_channel_type_hint(hint) {}
/// Construct the logger
/**
* @param channels A set of channels to statically enable
* @param hint A channel type specific hint for how to construct the logger
*/
syslog<concurrency,names>(level channels, channel_type_hint::value hint =
channel_type_hint::access)
: basic<concurrency,names>(channels, hint), m_channel_type_hint(hint) {}
/// Write a string message to the given channel
/**
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level channel, std::string const & msg) {
write(channel, msg.c_str());
}
/// Write a cstring message to the given channel
/**
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level channel, char const * msg) {
scoped_lock_type lock(base::m_lock);
if (!this->dynamic_test(channel)) { return; }
::syslog(syslog_priority(channel), "[%s] %s",
names::channel_name(channel), msg);
}
private:
typedef typename base::scoped_lock_type scoped_lock_type;
/// The default level is used for all access logs and any error logs that
/// don't trivially map to one of the standard syslog levels.
static int const default_level = LOG_INFO;
/// retrieve the syslog priority code given a WebSocket++ channel
/**
* @param channel The level to look up
* @return The syslog level associated with `channel`
*/
int syslog_priority(level channel) const {
if (m_channel_type_hint == channel_type_hint::access) {
return syslog_priority_access(channel);
} else {
return syslog_priority_error(channel);
}
}
/// retrieve the syslog priority code given a WebSocket++ error channel
/**
* @param channel The level to look up
* @return The syslog level associated with `channel`
*/
int syslog_priority_error(level channel) const {
switch (channel) {
case elevel::devel:
return LOG_DEBUG;
case elevel::library:
return LOG_DEBUG;
case elevel::info:
return LOG_INFO;
case elevel::warn:
return LOG_WARNING;
case elevel::rerror:
return LOG_ERR;
case elevel::fatal:
return LOG_CRIT;
default:
return default_level;
}
}
/// retrieve the syslog priority code given a WebSocket++ access channel
/**
* @param channel The level to look up
* @return The syslog level associated with `channel`
*/
_WEBSOCKETPP_CONSTEXPR_TOKEN_ int syslog_priority_access(level) const {
return default_level;
}
channel_type_hint::value m_channel_type_hint;
};
} // log
} // websocketpp
#endif // WEBSOCKETPP_LOGGER_SYSLOG_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* The initial version of this logging policy was contributed to the WebSocket++
* project by Tom Hughes.
*/
#ifndef WEBSOCKETPP_LOGGER_SYSLOG_HPP
#define WEBSOCKETPP_LOGGER_SYSLOG_HPP
#include <syslog.h>
#include <websocketpp/logger/basic.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/logger/levels.hpp>
namespace websocketpp {
namespace log {
/// Basic logger that outputs to syslog
template <typename concurrency, typename names>
class syslog : public basic<concurrency, names> {
public:
typedef basic<concurrency, names> base;
/// Construct the logger
/**
* @param hint A channel type specific hint for how to construct the logger
*/
syslog<concurrency,names>(channel_type_hint::value hint =
channel_type_hint::access)
: basic<concurrency,names>(hint), m_channel_type_hint(hint) {}
/// Construct the logger
/**
* @param channels A set of channels to statically enable
* @param hint A channel type specific hint for how to construct the logger
*/
syslog<concurrency,names>(level channels, channel_type_hint::value hint =
channel_type_hint::access)
: basic<concurrency,names>(channels, hint), m_channel_type_hint(hint) {}
/// Write a string message to the given channel
/**
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level channel, std::string const & msg) {
write(channel, msg.c_str());
}
/// Write a cstring message to the given channel
/**
* @param channel The channel to write to
* @param msg The message to write
*/
void write(level channel, char const * msg) {
scoped_lock_type lock(base::m_lock);
if (!this->dynamic_test(channel)) { return; }
::syslog(syslog_priority(channel), "[%s] %s",
names::channel_name(channel), msg);
}
private:
typedef typename base::scoped_lock_type scoped_lock_type;
/// The default level is used for all access logs and any error logs that
/// don't trivially map to one of the standard syslog levels.
static int const default_level = LOG_INFO;
/// retrieve the syslog priority code given a WebSocket++ channel
/**
* @param channel The level to look up
* @return The syslog level associated with `channel`
*/
int syslog_priority(level channel) const {
if (m_channel_type_hint == channel_type_hint::access) {
return syslog_priority_access(channel);
} else {
return syslog_priority_error(channel);
}
}
/// retrieve the syslog priority code given a WebSocket++ error channel
/**
* @param channel The level to look up
* @return The syslog level associated with `channel`
*/
int syslog_priority_error(level channel) const {
switch (channel) {
case elevel::devel:
return LOG_DEBUG;
case elevel::library:
return LOG_DEBUG;
case elevel::info:
return LOG_INFO;
case elevel::warn:
return LOG_WARNING;
case elevel::rerror:
return LOG_ERR;
case elevel::fatal:
return LOG_CRIT;
default:
return default_level;
}
}
/// retrieve the syslog priority code given a WebSocket++ access channel
/**
* @param channel The level to look up
* @return The syslog level associated with `channel`
*/
_WEBSOCKETPP_CONSTEXPR_TOKEN_ int syslog_priority_access(level) const {
return default_level;
}
channel_type_hint::value m_channel_type_hint;
};
} // log
} // websocketpp
#endif // WEBSOCKETPP_LOGGER_SYSLOG_HPP

View File

@@ -1,105 +1,105 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP
#define WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP
#include <websocketpp/common/memory.hpp>
#include <websocketpp/frame.hpp>
namespace websocketpp {
namespace message_buffer {
namespace alloc {
/// A connection message manager that allocates a new message for each
/// request.
template <typename message>
class con_msg_manager
: public lib::enable_shared_from_this<con_msg_manager<message> >
{
public:
typedef con_msg_manager<message> type;
typedef lib::shared_ptr<con_msg_manager> ptr;
typedef lib::weak_ptr<con_msg_manager> weak_ptr;
typedef typename message::ptr message_ptr;
/// Get an empty message buffer
/**
* @return A shared pointer to an empty new message
*/
message_ptr get_message() {
return message_ptr(lib::make_shared<message>(type::shared_from_this()));
}
/// Get a message buffer with specified size and opcode
/**
* @param op The opcode to use
* @param size Minimum size in bytes to request for the message payload.
*
* @return A shared pointer to a new message with specified size.
*/
message_ptr get_message(frame::opcode::value op,size_t size) {
return message_ptr(lib::make_shared<message>(type::shared_from_this(),op,size));
}
/// Recycle a message
/**
* This method shouldn't be called. If it is, return false to indicate an
* error. The rest of the method recycle chain should notice this and free
* the memory.
*
* @param msg The message to be recycled.
*
* @return true if the message was successfully recycled, false otherwse.
*/
bool recycle(message *) {
return false;
}
};
/// An endpoint message manager that allocates a new manager for each
/// connection.
template <typename con_msg_manager>
class endpoint_msg_manager {
public:
typedef typename con_msg_manager::ptr con_msg_man_ptr;
/// Get a pointer to a connection message manager
/**
* @return A pointer to the requested connection message manager.
*/
con_msg_man_ptr get_manager() const {
return con_msg_man_ptr(lib::make_shared<con_msg_manager>());
}
};
} // namespace alloc
} // namespace message_buffer
} // namespace websocketpp
#endif // WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP
#define WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP
#include <websocketpp/common/memory.hpp>
#include <websocketpp/frame.hpp>
namespace websocketpp {
namespace message_buffer {
namespace alloc {
/// A connection message manager that allocates a new message for each
/// request.
template <typename message>
class con_msg_manager
: public lib::enable_shared_from_this<con_msg_manager<message> >
{
public:
typedef con_msg_manager<message> type;
typedef lib::shared_ptr<con_msg_manager> ptr;
typedef lib::weak_ptr<con_msg_manager> weak_ptr;
typedef typename message::ptr message_ptr;
/// Get an empty message buffer
/**
* @return A shared pointer to an empty new message
*/
message_ptr get_message() {
return message_ptr(lib::make_shared<message>(type::shared_from_this()));
}
/// Get a message buffer with specified size and opcode
/**
* @param op The opcode to use
* @param size Minimum size in bytes to request for the message payload.
*
* @return A shared pointer to a new message with specified size.
*/
message_ptr get_message(frame::opcode::value op,size_t size) {
return message_ptr(lib::make_shared<message>(type::shared_from_this(),op,size));
}
/// Recycle a message
/**
* This method shouldn't be called. If it is, return false to indicate an
* error. The rest of the method recycle chain should notice this and free
* the memory.
*
* @param msg The message to be recycled.
*
* @return true if the message was successfully recycled, false otherwse.
*/
bool recycle(message *) {
return false;
}
};
/// An endpoint message manager that allocates a new manager for each
/// connection.
template <typename con_msg_manager>
class endpoint_msg_manager {
public:
typedef typename con_msg_manager::ptr con_msg_man_ptr;
/// Get a pointer to a connection message manager
/**
* @return A pointer to the requested connection message manager.
*/
con_msg_man_ptr get_manager() const {
return con_msg_man_ptr(lib::make_shared<con_msg_manager>());
}
};
} // namespace alloc
} // namespace message_buffer
} // namespace websocketpp
#endif // WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP

View File

@@ -1,340 +1,340 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_MESSAGE_BUFFER_MESSAGE_HPP
#define WEBSOCKETPP_MESSAGE_BUFFER_MESSAGE_HPP
#include <websocketpp/common/memory.hpp>
#include <websocketpp/frame.hpp>
#include <string>
namespace websocketpp {
namespace message_buffer {
/* # message:
* object that stores a message while it is being sent or received. Contains
* the message payload itself, the message header, the extension data, and the
* opcode.
*
* # connection_message_manager:
* An object that manages all of the message_buffers associated with a given
* connection. Implements the get_message_buffer(size) method that returns
* a message buffer at least size bytes long.
*
* Message buffers are reference counted with shared ownership semantics. Once
* requested from the manager the requester and it's associated downstream code
* may keep a pointer to the message indefinitely at a cost of extra resource
* usage. Once the reference count drops to the point where the manager is the
* only reference the messages is recycled using whatever method is implemented
* in the manager.
*
* # endpoint_message_manager:
* An object that manages connection_message_managers. Implements the
* get_message_manager() method. This is used once by each connection to
* request the message manager that they are supposed to use to manage message
* buffers for their own use.
*
* TYPES OF CONNECTION_MESSAGE_MANAGERS
* - allocate a message with the exact size every time one is requested
* - maintain a pool of pre-allocated messages and return one when needed.
* Recycle previously used messages back into the pool
*
* TYPES OF ENDPOINT_MESSAGE_MANAGERS
* - allocate a new connection manager for each connection. Message pools
* become connection specific. This increases memory usage but improves
* concurrency.
* - allocate a single connection manager and share a pointer to it with all
* connections created by this endpoint. The message pool will be shared
* among all connections, improving memory usage and performance at the cost
* of reduced concurrency
*/
/// Represents a buffer for a single WebSocket message.
/**
*
*
*/
template <template<class> class con_msg_manager>
class message {
public:
typedef lib::shared_ptr<message> ptr;
typedef con_msg_manager<message> con_msg_man_type;
typedef typename con_msg_man_type::ptr con_msg_man_ptr;
typedef typename con_msg_man_type::weak_ptr con_msg_man_weak_ptr;
/// Construct an empty message
/**
* Construct an empty message
*/
message(const con_msg_man_ptr manager)
: m_manager(manager)
, m_prepared(false)
, m_fin(true)
, m_terminal(false)
, m_compressed(false) {}
/// Construct a message and fill in some values
/**
*
*/
message(const con_msg_man_ptr manager, frame::opcode::value op, size_t size = 128)
: m_manager(manager)
, m_opcode(op)
, m_prepared(false)
, m_fin(true)
, m_terminal(false)
, m_compressed(false)
{
m_payload.reserve(size);
}
/// Return whether or not the message has been prepared for sending
/**
* The prepared flag indicates that the message has been prepared by a
* websocket protocol processor and is ready to be written to the wire.
*
* @return whether or not the message has been prepared for sending
*/
bool get_prepared() const {
return m_prepared;
}
/// Set or clear the flag that indicates that the message has been prepared
/**
* This flag should not be set by end user code without a very good reason.
*
* @param value The value to set the prepared flag to
*/
void set_prepared(bool value) {
m_prepared = value;
}
/// Return whether or not the message is flagged as compressed
/**
* @return whether or not the message is/should be compressed
*/
bool get_compressed() const {
return m_compressed;
}
/// Set or clear the compression flag
/**
* Setting the compression flag indicates that the data in this message
* would benefit from compression. If both endpoints negotiate a compression
* extension WebSocket++ will attempt to compress messages with this flag.
* Setting this flag does not guarantee that the message will be compressed.
*
* @param value The value to set the compressed flag to
*/
void set_compressed(bool value) {
m_compressed = value;
}
/// Get whether or not the message is terminal
/**
* Messages can be flagged as terminal, which results in the connection
* being close after they are written rather than the implementation going
* on to the next message in the queue. This is typically used internally
* for close messages only.
*
* @return Whether or not this message is marked terminal
*/
bool get_terminal() const {
return m_terminal;
}
/// Set the terminal flag
/**
* This flag should not be set by end user code without a very good reason.
*
* @see get_terminal()
*
* @param value The value to set the terminal flag to.
*/
void set_terminal(bool value) {
m_terminal = value;
}
/// Read the fin bit
/**
* A message with the fin bit set will be sent as the last message of its
* sequence. A message with the fin bit cleared will require subsequent
* frames of opcode continuation until one of them has the fin bit set.
*
* The remote end likely will not deliver any bytes until the frame with the fin
* bit set has been received.
*
* @return Whether or not the fin bit is set
*/
bool get_fin() const {
return m_fin;
}
/// Set the fin bit
/**
* @see get_fin for a more detailed explaination of the fin bit
*
* @param value The value to set the fin bit to.
*/
void set_fin(bool value) {
m_fin = value;
}
/// Return the message opcode
frame::opcode::value get_opcode() const {
return m_opcode;
}
/// Set the opcode
void set_opcode(frame::opcode::value op) {
m_opcode = op;
}
/// Return the prepared frame header
/**
* This value is typically set by a websocket protocol processor
* and shouldn't be tampered with.
*/
std::string const & get_header() const {
return m_header;
}
/// Set prepared frame header
/**
* Under normal circumstances this should not be called by end users
*
* @param header A string to set the header to.
*/
void set_header(std::string const & header) {
m_header = header;
}
std::string const & get_extension_data() const {
return m_extension_data;
}
/// Get a reference to the payload string
/**
* @return A const reference to the message's payload string
*/
std::string const & get_payload() const {
return m_payload;
}
/// Get a non-const reference to the payload string
/**
* @return A reference to the message's payload string
*/
std::string & get_raw_payload() {
return m_payload;
}
/// Set payload data
/**
* Set the message buffer's payload to the given value.
*
* @param payload A string to set the payload to.
*/
void set_payload(std::string const & payload) {
m_payload = payload;
}
/// Set payload data
/**
* Set the message buffer's payload to the given value.
*
* @param payload A pointer to a data array to set to.
* @param len The length of new payload in bytes.
*/
void set_payload(void const * payload, size_t len) {
m_payload.reserve(len);
char const * pl = static_cast<char const *>(payload);
m_payload.assign(pl, pl + len);
}
/// Append payload data
/**
* Append data to the message buffer's payload.
*
* @param payload A string containing the data array to append.
*/
void append_payload(std::string const & payload) {
m_payload.append(payload);
}
/// Append payload data
/**
* Append data to the message buffer's payload.
*
* @param payload A pointer to a data array to append
* @param len The length of payload in bytes
*/
void append_payload(void const * payload, size_t len) {
m_payload.reserve(m_payload.size()+len);
m_payload.append(static_cast<char const *>(payload),len);
}
/// Recycle the message
/**
* A request to recycle this message was received. Forward that request to
* the connection message manager for processing. Errors and exceptions
* from the manager's recycle member function should be passed back up the
* call chain. The caller to message::recycle will deal with them.
*
* Recycle must *only* be called by the message shared_ptr's destructor.
* Once recycled successfully, ownership of the memory has been passed to
* another system and must not be accessed again.
*
* @return true if the message was successfully recycled, false otherwise.
*/
bool recycle() {
con_msg_man_ptr shared = m_manager.lock();
if (shared) {
return shared->recycle(this);
} else {
return false;
}
}
private:
con_msg_man_weak_ptr m_manager;
std::string m_header;
std::string m_extension_data;
std::string m_payload;
frame::opcode::value m_opcode;
bool m_prepared;
bool m_fin;
bool m_terminal;
bool m_compressed;
};
} // namespace message_buffer
} // namespace websocketpp
#endif // WEBSOCKETPP_MESSAGE_BUFFER_MESSAGE_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_MESSAGE_BUFFER_MESSAGE_HPP
#define WEBSOCKETPP_MESSAGE_BUFFER_MESSAGE_HPP
#include <websocketpp/common/memory.hpp>
#include <websocketpp/frame.hpp>
#include <string>
namespace websocketpp {
namespace message_buffer {
/* # message:
* object that stores a message while it is being sent or received. Contains
* the message payload itself, the message header, the extension data, and the
* opcode.
*
* # connection_message_manager:
* An object that manages all of the message_buffers associated with a given
* connection. Implements the get_message_buffer(size) method that returns
* a message buffer at least size bytes long.
*
* Message buffers are reference counted with shared ownership semantics. Once
* requested from the manager the requester and it's associated downstream code
* may keep a pointer to the message indefinitely at a cost of extra resource
* usage. Once the reference count drops to the point where the manager is the
* only reference the messages is recycled using whatever method is implemented
* in the manager.
*
* # endpoint_message_manager:
* An object that manages connection_message_managers. Implements the
* get_message_manager() method. This is used once by each connection to
* request the message manager that they are supposed to use to manage message
* buffers for their own use.
*
* TYPES OF CONNECTION_MESSAGE_MANAGERS
* - allocate a message with the exact size every time one is requested
* - maintain a pool of pre-allocated messages and return one when needed.
* Recycle previously used messages back into the pool
*
* TYPES OF ENDPOINT_MESSAGE_MANAGERS
* - allocate a new connection manager for each connection. Message pools
* become connection specific. This increases memory usage but improves
* concurrency.
* - allocate a single connection manager and share a pointer to it with all
* connections created by this endpoint. The message pool will be shared
* among all connections, improving memory usage and performance at the cost
* of reduced concurrency
*/
/// Represents a buffer for a single WebSocket message.
/**
*
*
*/
template <template<class> class con_msg_manager>
class message {
public:
typedef lib::shared_ptr<message> ptr;
typedef con_msg_manager<message> con_msg_man_type;
typedef typename con_msg_man_type::ptr con_msg_man_ptr;
typedef typename con_msg_man_type::weak_ptr con_msg_man_weak_ptr;
/// Construct an empty message
/**
* Construct an empty message
*/
message(const con_msg_man_ptr manager)
: m_manager(manager)
, m_prepared(false)
, m_fin(true)
, m_terminal(false)
, m_compressed(false) {}
/// Construct a message and fill in some values
/**
*
*/
message(const con_msg_man_ptr manager, frame::opcode::value op, size_t size = 128)
: m_manager(manager)
, m_opcode(op)
, m_prepared(false)
, m_fin(true)
, m_terminal(false)
, m_compressed(false)
{
m_payload.reserve(size);
}
/// Return whether or not the message has been prepared for sending
/**
* The prepared flag indicates that the message has been prepared by a
* websocket protocol processor and is ready to be written to the wire.
*
* @return whether or not the message has been prepared for sending
*/
bool get_prepared() const {
return m_prepared;
}
/// Set or clear the flag that indicates that the message has been prepared
/**
* This flag should not be set by end user code without a very good reason.
*
* @param value The value to set the prepared flag to
*/
void set_prepared(bool value) {
m_prepared = value;
}
/// Return whether or not the message is flagged as compressed
/**
* @return whether or not the message is/should be compressed
*/
bool get_compressed() const {
return m_compressed;
}
/// Set or clear the compression flag
/**
* Setting the compression flag indicates that the data in this message
* would benefit from compression. If both endpoints negotiate a compression
* extension WebSocket++ will attempt to compress messages with this flag.
* Setting this flag does not guarantee that the message will be compressed.
*
* @param value The value to set the compressed flag to
*/
void set_compressed(bool value) {
m_compressed = value;
}
/// Get whether or not the message is terminal
/**
* Messages can be flagged as terminal, which results in the connection
* being close after they are written rather than the implementation going
* on to the next message in the queue. This is typically used internally
* for close messages only.
*
* @return Whether or not this message is marked terminal
*/
bool get_terminal() const {
return m_terminal;
}
/// Set the terminal flag
/**
* This flag should not be set by end user code without a very good reason.
*
* @see get_terminal()
*
* @param value The value to set the terminal flag to.
*/
void set_terminal(bool value) {
m_terminal = value;
}
/// Read the fin bit
/**
* A message with the fin bit set will be sent as the last message of its
* sequence. A message with the fin bit cleared will require subsequent
* frames of opcode continuation until one of them has the fin bit set.
*
* The remote end likely will not deliver any bytes until the frame with the fin
* bit set has been received.
*
* @return Whether or not the fin bit is set
*/
bool get_fin() const {
return m_fin;
}
/// Set the fin bit
/**
* @see get_fin for a more detailed explaination of the fin bit
*
* @param value The value to set the fin bit to.
*/
void set_fin(bool value) {
m_fin = value;
}
/// Return the message opcode
frame::opcode::value get_opcode() const {
return m_opcode;
}
/// Set the opcode
void set_opcode(frame::opcode::value op) {
m_opcode = op;
}
/// Return the prepared frame header
/**
* This value is typically set by a websocket protocol processor
* and shouldn't be tampered with.
*/
std::string const & get_header() const {
return m_header;
}
/// Set prepared frame header
/**
* Under normal circumstances this should not be called by end users
*
* @param header A string to set the header to.
*/
void set_header(std::string const & header) {
m_header = header;
}
std::string const & get_extension_data() const {
return m_extension_data;
}
/// Get a reference to the payload string
/**
* @return A const reference to the message's payload string
*/
std::string const & get_payload() const {
return m_payload;
}
/// Get a non-const reference to the payload string
/**
* @return A reference to the message's payload string
*/
std::string & get_raw_payload() {
return m_payload;
}
/// Set payload data
/**
* Set the message buffer's payload to the given value.
*
* @param payload A string to set the payload to.
*/
void set_payload(std::string const & payload) {
m_payload = payload;
}
/// Set payload data
/**
* Set the message buffer's payload to the given value.
*
* @param payload A pointer to a data array to set to.
* @param len The length of new payload in bytes.
*/
void set_payload(void const * payload, size_t len) {
m_payload.reserve(len);
char const * pl = static_cast<char const *>(payload);
m_payload.assign(pl, pl + len);
}
/// Append payload data
/**
* Append data to the message buffer's payload.
*
* @param payload A string containing the data array to append.
*/
void append_payload(std::string const & payload) {
m_payload.append(payload);
}
/// Append payload data
/**
* Append data to the message buffer's payload.
*
* @param payload A pointer to a data array to append
* @param len The length of payload in bytes
*/
void append_payload(void const * payload, size_t len) {
m_payload.reserve(m_payload.size()+len);
m_payload.append(static_cast<char const *>(payload),len);
}
/// Recycle the message
/**
* A request to recycle this message was received. Forward that request to
* the connection message manager for processing. Errors and exceptions
* from the manager's recycle member function should be passed back up the
* call chain. The caller to message::recycle will deal with them.
*
* Recycle must *only* be called by the message shared_ptr's destructor.
* Once recycled successfully, ownership of the memory has been passed to
* another system and must not be accessed again.
*
* @return true if the message was successfully recycled, false otherwise.
*/
bool recycle() {
con_msg_man_ptr shared = m_manager.lock();
if (shared) {
return shared->recycle(this);
} else {
return false;
}
}
private:
con_msg_man_weak_ptr m_manager;
std::string m_header;
std::string m_extension_data;
std::string m_payload;
frame::opcode::value m_opcode;
bool m_prepared;
bool m_fin;
bool m_terminal;
bool m_compressed;
};
} // namespace message_buffer
} // namespace websocketpp
#endif // WEBSOCKETPP_MESSAGE_BUFFER_MESSAGE_HPP

View File

@@ -1,229 +1,229 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP
#define WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP
#include <websocketpp/common/memory.hpp>
#include <string>
namespace websocketpp {
namespace message_buffer {
/* # message:
* object that stores a message while it is being sent or received. Contains
* the message payload itself, the message header, the extension data, and the
* opcode.
*
* # connection_message_manager:
* An object that manages all of the message_buffers associated with a given
* connection. Implements the get_message_buffer(size) method that returns
* a message buffer at least size bytes long.
*
* Message buffers are reference counted with shared ownership semantics. Once
* requested from the manager the requester and it's associated downstream code
* may keep a pointer to the message indefinitely at a cost of extra resource
* usage. Once the reference count drops to the point where the manager is the
* only reference the messages is recycled using whatever method is implemented
* in the manager.
*
* # endpoint_message_manager:
* An object that manages connection_message_managers. Implements the
* get_message_manager() method. This is used once by each connection to
* request the message manager that they are supposed to use to manage message
* buffers for their own use.
*
* TYPES OF CONNECTION_MESSAGE_MANAGERS
* - allocate a message with the exact size every time one is requested
* - maintain a pool of pre-allocated messages and return one when needed.
* Recycle previously used messages back into the pool
*
* TYPES OF ENDPOINT_MESSAGE_MANAGERS
* - allocate a new connection manager for each connection. Message pools
* become connection specific. This increases memory usage but improves
* concurrency.
* - allocate a single connection manager and share a pointer to it with all
* connections created by this endpoint. The message pool will be shared
* among all connections, improving memory usage and performance at the cost
* of reduced concurrency
*/
/// Custom deleter for use in shared_ptrs to message.
/**
* This is used to catch messages about to be deleted and offer the manager the
* ability to recycle them instead. Message::recycle will return true if it was
* successfully recycled and false otherwise. In the case of exceptions or error
* this deleter frees the memory.
*/
template <typename T>
void message_deleter(T* msg) {
try {
if (!msg->recycle()) {
delete msg;
}
} catch (...) {
// TODO: is there a better way to ensure this function doesn't throw?
delete msg;
}
}
/// Represents a buffer for a single WebSocket message.
/**
*
*
*/
template <typename con_msg_manager>
class message {
public:
typedef lib::shared_ptr<message> ptr;
typedef typename con_msg_manager::weak_ptr con_msg_man_ptr;
message(con_msg_man_ptr manager, size_t size = 128)
: m_manager(manager)
, m_payload(size) {}
frame::opcode::value get_opcode() const {
return m_opcode;
}
const std::string& get_header() const {
return m_header;
}
const std::string& get_extension_data() const {
return m_extension_data;
}
const std::string& get_payload() const {
return m_payload;
}
/// Recycle the message
/**
* A request to recycle this message was received. Forward that request to
* the connection message manager for processing. Errors and exceptions
* from the manager's recycle member function should be passed back up the
* call chain. The caller to message::recycle will deal with them.
*
* Recycle must *only* be called by the message shared_ptr's destructor.
* Once recycled successfully, ownership of the memory has been passed to
* another system and must not be accessed again.
*
* @return true if the message was successfully recycled, false otherwise.
*/
bool recycle() {
typename con_msg_manager::ptr shared = m_manager.lock();
if (shared) {
return shared->(recycle(this));
} else {
return false;
}
}
private:
con_msg_man_ptr m_manager;
frame::opcode::value m_opcode;
std::string m_header;
std::string m_extension_data;
std::string m_payload;
};
namespace alloc {
/// A connection message manager that allocates a new message for each
/// request.
template <typename message>
class con_msg_manager {
public:
typedef lib::shared_ptr<con_msg_manager> ptr;
typedef lib::weak_ptr<con_msg_manager> weak_ptr;
typedef typename message::ptr message_ptr;
/// Get a message buffer with specified size
/**
* @param size Minimum size in bytes to request for the message payload.
*
* @return A shared pointer to a new message with specified size.
*/
message_ptr get_message(size_t size) const {
return lib::make_shared<message>(size);
}
/// Recycle a message
/**
* This method shouldn't be called. If it is, return false to indicate an
* error. The rest of the method recycle chain should notice this and free
* the memory.
*
* @param msg The message to be recycled.
*
* @return true if the message was successfully recycled, false otherwse.
*/
bool recycle(message * msg) {
return false;
}
};
/// An endpoint message manager that allocates a new manager for each
/// connection.
template <typename con_msg_manager>
class endpoint_msg_manager {
public:
typedef typename con_msg_manager::ptr con_msg_man_ptr;
/// Get a pointer to a connection message manager
/**
* @return A pointer to the requested connection message manager.
*/
con_msg_man_ptr get_manager() const {
return lib::make_shared<con_msg_manager>();
}
};
} // namespace alloc
namespace pool {
/// A connection messages manager that maintains a pool of messages that is
/// used to fulfill get_message requests.
class con_msg_manager {
};
/// An endpoint manager that maintains a shared pool of connection managers
/// and returns an appropriate one for the requesting connection.
class endpoint_msg_manager {
};
} // namespace pool
} // namespace message_buffer
} // namespace websocketpp
#endif // WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP
#define WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP
#include <websocketpp/common/memory.hpp>
#include <string>
namespace websocketpp {
namespace message_buffer {
/* # message:
* object that stores a message while it is being sent or received. Contains
* the message payload itself, the message header, the extension data, and the
* opcode.
*
* # connection_message_manager:
* An object that manages all of the message_buffers associated with a given
* connection. Implements the get_message_buffer(size) method that returns
* a message buffer at least size bytes long.
*
* Message buffers are reference counted with shared ownership semantics. Once
* requested from the manager the requester and it's associated downstream code
* may keep a pointer to the message indefinitely at a cost of extra resource
* usage. Once the reference count drops to the point where the manager is the
* only reference the messages is recycled using whatever method is implemented
* in the manager.
*
* # endpoint_message_manager:
* An object that manages connection_message_managers. Implements the
* get_message_manager() method. This is used once by each connection to
* request the message manager that they are supposed to use to manage message
* buffers for their own use.
*
* TYPES OF CONNECTION_MESSAGE_MANAGERS
* - allocate a message with the exact size every time one is requested
* - maintain a pool of pre-allocated messages and return one when needed.
* Recycle previously used messages back into the pool
*
* TYPES OF ENDPOINT_MESSAGE_MANAGERS
* - allocate a new connection manager for each connection. Message pools
* become connection specific. This increases memory usage but improves
* concurrency.
* - allocate a single connection manager and share a pointer to it with all
* connections created by this endpoint. The message pool will be shared
* among all connections, improving memory usage and performance at the cost
* of reduced concurrency
*/
/// Custom deleter for use in shared_ptrs to message.
/**
* This is used to catch messages about to be deleted and offer the manager the
* ability to recycle them instead. Message::recycle will return true if it was
* successfully recycled and false otherwise. In the case of exceptions or error
* this deleter frees the memory.
*/
template <typename T>
void message_deleter(T* msg) {
try {
if (!msg->recycle()) {
delete msg;
}
} catch (...) {
// TODO: is there a better way to ensure this function doesn't throw?
delete msg;
}
}
/// Represents a buffer for a single WebSocket message.
/**
*
*
*/
template <typename con_msg_manager>
class message {
public:
typedef lib::shared_ptr<message> ptr;
typedef typename con_msg_manager::weak_ptr con_msg_man_ptr;
message(con_msg_man_ptr manager, size_t size = 128)
: m_manager(manager)
, m_payload(size) {}
frame::opcode::value get_opcode() const {
return m_opcode;
}
const std::string& get_header() const {
return m_header;
}
const std::string& get_extension_data() const {
return m_extension_data;
}
const std::string& get_payload() const {
return m_payload;
}
/// Recycle the message
/**
* A request to recycle this message was received. Forward that request to
* the connection message manager for processing. Errors and exceptions
* from the manager's recycle member function should be passed back up the
* call chain. The caller to message::recycle will deal with them.
*
* Recycle must *only* be called by the message shared_ptr's destructor.
* Once recycled successfully, ownership of the memory has been passed to
* another system and must not be accessed again.
*
* @return true if the message was successfully recycled, false otherwise.
*/
bool recycle() {
typename con_msg_manager::ptr shared = m_manager.lock();
if (shared) {
return shared->(recycle(this));
} else {
return false;
}
}
private:
con_msg_man_ptr m_manager;
frame::opcode::value m_opcode;
std::string m_header;
std::string m_extension_data;
std::string m_payload;
};
namespace alloc {
/// A connection message manager that allocates a new message for each
/// request.
template <typename message>
class con_msg_manager {
public:
typedef lib::shared_ptr<con_msg_manager> ptr;
typedef lib::weak_ptr<con_msg_manager> weak_ptr;
typedef typename message::ptr message_ptr;
/// Get a message buffer with specified size
/**
* @param size Minimum size in bytes to request for the message payload.
*
* @return A shared pointer to a new message with specified size.
*/
message_ptr get_message(size_t size) const {
return lib::make_shared<message>(size);
}
/// Recycle a message
/**
* This method shouldn't be called. If it is, return false to indicate an
* error. The rest of the method recycle chain should notice this and free
* the memory.
*
* @param msg The message to be recycled.
*
* @return true if the message was successfully recycled, false otherwse.
*/
bool recycle(message * msg) {
return false;
}
};
/// An endpoint message manager that allocates a new manager for each
/// connection.
template <typename con_msg_manager>
class endpoint_msg_manager {
public:
typedef typename con_msg_manager::ptr con_msg_man_ptr;
/// Get a pointer to a connection message manager
/**
* @return A pointer to the requested connection message manager.
*/
con_msg_man_ptr get_manager() const {
return lib::make_shared<con_msg_manager>();
}
};
} // namespace alloc
namespace pool {
/// A connection messages manager that maintains a pool of messages that is
/// used to fulfill get_message requests.
class con_msg_manager {
};
/// An endpoint manager that maintains a shared pool of connection managers
/// and returns an appropriate one for the requesting connection.
class endpoint_msg_manager {
};
} // namespace pool
} // namespace message_buffer
} // namespace websocketpp
#endif // WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP

View File

@@ -1,299 +1,299 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_PROCESSOR_BASE_HPP
#define WEBSOCKETPP_PROCESSOR_BASE_HPP
#include <websocketpp/close.hpp>
#include <websocketpp/utilities.hpp>
#include <websocketpp/uri.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/system_error.hpp>
#include <string>
namespace websocketpp {
namespace processor {
/// Constants related to processing WebSocket connections
namespace constants {
static char const upgrade_token[] = "websocket";
static char const connection_token[] = "Upgrade";
static char const handshake_guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
} // namespace constants
/// Processor class related error codes
namespace error_cat {
enum value {
BAD_REQUEST = 0, // Error was the result of improperly formatted user input
INTERNAL_ERROR = 1, // Error was a logic error internal to WebSocket++
PROTOCOL_VIOLATION = 2,
MESSAGE_TOO_BIG = 3,
PAYLOAD_VIOLATION = 4 // Error was due to receiving invalid payload data
};
} // namespace error_cat
/// Error code category and codes used by all processor types
namespace error {
enum processor_errors {
/// Catch-all error for processor policy errors that don't fit in other
/// categories
general = 1,
/// Error was the result of improperly formatted user input
bad_request,
/// Processor encountered a protocol violation in an incoming message
protocol_violation,
/// Processor encountered a message that was too large
message_too_big,
/// Processor encountered invalid payload data.
invalid_payload,
/// The processor method was called with invalid arguments
invalid_arguments,
/// Opcode was invalid for requested operation
invalid_opcode,
/// Control frame too large
control_too_big,
/// Illegal use of reserved bit
invalid_rsv_bit,
/// Fragmented control message
fragmented_control,
/// Continuation without message
invalid_continuation,
/// Clients may not send unmasked frames
masking_required,
/// Servers may not send masked frames
masking_forbidden,
/// Payload length not minimally encoded
non_minimal_encoding,
/// Not supported on 32 bit systems
requires_64bit,
/// Invalid UTF-8 encoding
invalid_utf8,
/// Operation required not implemented functionality
not_implemented,
/// Invalid HTTP method
invalid_http_method,
/// Invalid HTTP version
invalid_http_version,
/// Invalid HTTP status
invalid_http_status,
/// Missing Required Header
missing_required_header,
/// Embedded SHA-1 library error
sha1_library,
/// No support for this feature in this protocol version.
no_protocol_support,
/// Reserved close code used
reserved_close_code,
/// Invalid close code used
invalid_close_code,
/// Using a reason requires a close code
reason_requires_code,
/// Error parsing subprotocols
subprotocol_parse_error,
/// Error parsing extensions
extension_parse_error,
/// Extension related operation was ignored because extensions are disabled
extensions_disabled,
/// Short Ke3 read. Hybi00 requires a third key to be read from the 8 bytes
/// after the handshake. Less than 8 bytes were read.
short_key3
};
/// Category for processor errors
class processor_category : public lib::error_category {
public:
processor_category() {}
char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
return "websocketpp.processor";
}
std::string message(int value) const {
switch(value) {
case error::general:
return "Generic processor error";
case error::bad_request:
return "invalid user input";
case error::protocol_violation:
return "Generic protocol violation";
case error::message_too_big:
return "A message was too large";
case error::invalid_payload:
return "A payload contained invalid data";
case error::invalid_arguments:
return "invalid function arguments";
case error::invalid_opcode:
return "invalid opcode";
case error::control_too_big:
return "Control messages are limited to fewer than 125 characters";
case error::invalid_rsv_bit:
return "Invalid use of reserved bits";
case error::fragmented_control:
return "Control messages cannot be fragmented";
case error::invalid_continuation:
return "Invalid message continuation";
case error::masking_required:
return "Clients may not send unmasked frames";
case error::masking_forbidden:
return "Servers may not send masked frames";
case error::non_minimal_encoding:
return "Payload length was not minimally encoded";
case error::requires_64bit:
return "64 bit frames are not supported on 32 bit systems";
case error::invalid_utf8:
return "Invalid UTF8 encoding";
case error::not_implemented:
return "Operation required not implemented functionality";
case error::invalid_http_method:
return "Invalid HTTP method.";
case error::invalid_http_version:
return "Invalid HTTP version.";
case error::invalid_http_status:
return "Invalid HTTP status.";
case error::missing_required_header:
return "A required HTTP header is missing";
case error::sha1_library:
return "SHA-1 library error";
case error::no_protocol_support:
return "The WebSocket protocol version in use does not support this feature";
case error::reserved_close_code:
return "Reserved close code used";
case error::invalid_close_code:
return "Invalid close code used";
case error::reason_requires_code:
return "Using a close reason requires a valid close code";
case error::subprotocol_parse_error:
return "Error parsing subprotocol header";
case error::extension_parse_error:
return "Error parsing extension header";
case error::extensions_disabled:
return "Extensions are disabled";
case error::short_key3:
return "Short Hybi00 Key 3 read";
default:
return "Unknown";
}
}
};
/// Get a reference to a static copy of the processor error category
inline lib::error_category const & get_processor_category() {
static processor_category instance;
return instance;
}
/// Create an error code with the given value and the processor category
inline lib::error_code make_error_code(error::processor_errors e) {
return lib::error_code(static_cast<int>(e), get_processor_category());
}
/// Converts a processor error_code into a websocket close code
/**
* Looks up the appropriate WebSocket close code that should be sent after an
* error of this sort occurred.
*
* If the error is not in the processor category close::status::blank is
* returned.
*
* If the error isn't normally associated with reasons to close a connection
* (such as errors intended to be used internally or delivered to client
* applications, ex: invalid arguments) then
* close::status::internal_endpoint_error is returned.
*/
inline close::status::value to_ws(lib::error_code ec) {
if (ec.category() != get_processor_category()) {
return close::status::blank;
}
switch (ec.value()) {
case error::protocol_violation:
case error::control_too_big:
case error::invalid_opcode:
case error::invalid_rsv_bit:
case error::fragmented_control:
case error::invalid_continuation:
case error::masking_required:
case error::masking_forbidden:
case error::reserved_close_code:
case error::invalid_close_code:
return close::status::protocol_error;
case error::invalid_payload:
case error::invalid_utf8:
return close::status::invalid_payload;
case error::message_too_big:
return close::status::message_too_big;
default:
return close::status::internal_endpoint_error;
}
}
} // namespace error
} // namespace processor
} // namespace websocketpp
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
template<> struct is_error_code_enum<websocketpp::processor::error::processor_errors>
{
static bool const value = true;
};
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
#endif //WEBSOCKETPP_PROCESSOR_BASE_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_PROCESSOR_BASE_HPP
#define WEBSOCKETPP_PROCESSOR_BASE_HPP
#include <websocketpp/close.hpp>
#include <websocketpp/utilities.hpp>
#include <websocketpp/uri.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/system_error.hpp>
#include <string>
namespace websocketpp {
namespace processor {
/// Constants related to processing WebSocket connections
namespace constants {
static char const upgrade_token[] = "websocket";
static char const connection_token[] = "Upgrade";
static char const handshake_guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
} // namespace constants
/// Processor class related error codes
namespace error_cat {
enum value {
BAD_REQUEST = 0, // Error was the result of improperly formatted user input
INTERNAL_ERROR = 1, // Error was a logic error internal to WebSocket++
PROTOCOL_VIOLATION = 2,
MESSAGE_TOO_BIG = 3,
PAYLOAD_VIOLATION = 4 // Error was due to receiving invalid payload data
};
} // namespace error_cat
/// Error code category and codes used by all processor types
namespace error {
enum processor_errors {
/// Catch-all error for processor policy errors that don't fit in other
/// categories
general = 1,
/// Error was the result of improperly formatted user input
bad_request,
/// Processor encountered a protocol violation in an incoming message
protocol_violation,
/// Processor encountered a message that was too large
message_too_big,
/// Processor encountered invalid payload data.
invalid_payload,
/// The processor method was called with invalid arguments
invalid_arguments,
/// Opcode was invalid for requested operation
invalid_opcode,
/// Control frame too large
control_too_big,
/// Illegal use of reserved bit
invalid_rsv_bit,
/// Fragmented control message
fragmented_control,
/// Continuation without message
invalid_continuation,
/// Clients may not send unmasked frames
masking_required,
/// Servers may not send masked frames
masking_forbidden,
/// Payload length not minimally encoded
non_minimal_encoding,
/// Not supported on 32 bit systems
requires_64bit,
/// Invalid UTF-8 encoding
invalid_utf8,
/// Operation required not implemented functionality
not_implemented,
/// Invalid HTTP method
invalid_http_method,
/// Invalid HTTP version
invalid_http_version,
/// Invalid HTTP status
invalid_http_status,
/// Missing Required Header
missing_required_header,
/// Embedded SHA-1 library error
sha1_library,
/// No support for this feature in this protocol version.
no_protocol_support,
/// Reserved close code used
reserved_close_code,
/// Invalid close code used
invalid_close_code,
/// Using a reason requires a close code
reason_requires_code,
/// Error parsing subprotocols
subprotocol_parse_error,
/// Error parsing extensions
extension_parse_error,
/// Extension related operation was ignored because extensions are disabled
extensions_disabled,
/// Short Ke3 read. Hybi00 requires a third key to be read from the 8 bytes
/// after the handshake. Less than 8 bytes were read.
short_key3
};
/// Category for processor errors
class processor_category : public lib::error_category {
public:
processor_category() {}
char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
return "websocketpp.processor";
}
std::string message(int value) const {
switch(value) {
case error::general:
return "Generic processor error";
case error::bad_request:
return "invalid user input";
case error::protocol_violation:
return "Generic protocol violation";
case error::message_too_big:
return "A message was too large";
case error::invalid_payload:
return "A payload contained invalid data";
case error::invalid_arguments:
return "invalid function arguments";
case error::invalid_opcode:
return "invalid opcode";
case error::control_too_big:
return "Control messages are limited to fewer than 125 characters";
case error::invalid_rsv_bit:
return "Invalid use of reserved bits";
case error::fragmented_control:
return "Control messages cannot be fragmented";
case error::invalid_continuation:
return "Invalid message continuation";
case error::masking_required:
return "Clients may not send unmasked frames";
case error::masking_forbidden:
return "Servers may not send masked frames";
case error::non_minimal_encoding:
return "Payload length was not minimally encoded";
case error::requires_64bit:
return "64 bit frames are not supported on 32 bit systems";
case error::invalid_utf8:
return "Invalid UTF8 encoding";
case error::not_implemented:
return "Operation required not implemented functionality";
case error::invalid_http_method:
return "Invalid HTTP method.";
case error::invalid_http_version:
return "Invalid HTTP version.";
case error::invalid_http_status:
return "Invalid HTTP status.";
case error::missing_required_header:
return "A required HTTP header is missing";
case error::sha1_library:
return "SHA-1 library error";
case error::no_protocol_support:
return "The WebSocket protocol version in use does not support this feature";
case error::reserved_close_code:
return "Reserved close code used";
case error::invalid_close_code:
return "Invalid close code used";
case error::reason_requires_code:
return "Using a close reason requires a valid close code";
case error::subprotocol_parse_error:
return "Error parsing subprotocol header";
case error::extension_parse_error:
return "Error parsing extension header";
case error::extensions_disabled:
return "Extensions are disabled";
case error::short_key3:
return "Short Hybi00 Key 3 read";
default:
return "Unknown";
}
}
};
/// Get a reference to a static copy of the processor error category
inline lib::error_category const & get_processor_category() {
static processor_category instance;
return instance;
}
/// Create an error code with the given value and the processor category
inline lib::error_code make_error_code(error::processor_errors e) {
return lib::error_code(static_cast<int>(e), get_processor_category());
}
/// Converts a processor error_code into a websocket close code
/**
* Looks up the appropriate WebSocket close code that should be sent after an
* error of this sort occurred.
*
* If the error is not in the processor category close::status::blank is
* returned.
*
* If the error isn't normally associated with reasons to close a connection
* (such as errors intended to be used internally or delivered to client
* applications, ex: invalid arguments) then
* close::status::internal_endpoint_error is returned.
*/
inline close::status::value to_ws(lib::error_code ec) {
if (ec.category() != get_processor_category()) {
return close::status::blank;
}
switch (ec.value()) {
case error::protocol_violation:
case error::control_too_big:
case error::invalid_opcode:
case error::invalid_rsv_bit:
case error::fragmented_control:
case error::invalid_continuation:
case error::masking_required:
case error::masking_forbidden:
case error::reserved_close_code:
case error::invalid_close_code:
return close::status::protocol_error;
case error::invalid_payload:
case error::invalid_utf8:
return close::status::invalid_payload;
case error::message_too_big:
return close::status::message_too_big;
default:
return close::status::internal_endpoint_error;
}
}
} // namespace error
} // namespace processor
} // namespace websocketpp
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
template<> struct is_error_code_enum<websocketpp::processor::error::processor_errors>
{
static bool const value = true;
};
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
#endif //WEBSOCKETPP_PROCESSOR_BASE_HPP

View File

@@ -1,462 +1,462 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_PROCESSOR_HYBI00_HPP
#define WEBSOCKETPP_PROCESSOR_HYBI00_HPP
#include <websocketpp/frame.hpp>
#include <websocketpp/http/constants.hpp>
#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>
#include <algorithm>
#include <cstdlib>
#include <string>
#include <vector>
namespace websocketpp {
namespace processor {
/// Processor for Hybi Draft version 00
/**
* There are many differences between Hybi 00 and Hybi 13
*/
template <typename config>
class hybi00 : public processor<config> {
public:
typedef processor<config> base;
typedef typename config::request_type request_type;
typedef typename config::response_type response_type;
typedef typename config::message_type message_type;
typedef typename message_type::ptr message_ptr;
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
explicit hybi00(bool secure, bool p_is_server, msg_manager_ptr manager)
: processor<config>(secure, p_is_server)
, msg_hdr(0x00)
, msg_ftr(0xff)
, m_state(HEADER)
, m_msg_manager(manager) {}
int get_version() const {
return 0;
}
lib::error_code validate_handshake(request_type const & r) const {
if (r.get_method() != "GET") {
return make_error_code(error::invalid_http_method);
}
if (r.get_version() != "HTTP/1.1") {
return make_error_code(error::invalid_http_version);
}
// required headers
// Host is required by HTTP/1.1
// Connection is required by is_websocket_handshake
// Upgrade is required by is_websocket_handshake
if (r.get_header("Sec-WebSocket-Key1").empty() ||
r.get_header("Sec-WebSocket-Key2").empty() ||
r.get_header("Sec-WebSocket-Key3").empty())
{
return make_error_code(error::missing_required_header);
}
return lib::error_code();
}
lib::error_code process_handshake(request_type const & req,
std::string const & subprotocol, response_type & res) const
{
char key_final[16];
// copy key1 into final key
decode_client_key(req.get_header("Sec-WebSocket-Key1"), &key_final[0]);
// copy key2 into final key
decode_client_key(req.get_header("Sec-WebSocket-Key2"), &key_final[4]);
// copy key3 into final key
// key3 should be exactly 8 bytes. If it is more it will be truncated
// if it is less the final key will almost certainly be wrong.
// TODO: decide if it is best to silently fail here or produce some sort
// of warning or exception.
std::string const & key3 = req.get_header("Sec-WebSocket-Key3");
std::copy(key3.c_str(),
key3.c_str()+(std::min)(static_cast<size_t>(8), key3.size()),
&key_final[8]);
res.append_header(
"Sec-WebSocket-Key3",
md5::md5_hash_string(std::string(key_final,16))
);
res.append_header("Upgrade","WebSocket");
res.append_header("Connection","Upgrade");
// Echo back client's origin unless our local application set a
// more restrictive one.
if (res.get_header("Sec-WebSocket-Origin").empty()) {
res.append_header("Sec-WebSocket-Origin",req.get_header("Origin"));
}
// Echo back the client's request host unless our local application
// set a different one.
if (res.get_header("Sec-WebSocket-Location").empty()) {
uri_ptr uri = get_uri(req);
res.append_header("Sec-WebSocket-Location",uri->str());
}
if (!subprotocol.empty()) {
res.replace_header("Sec-WebSocket-Protocol",subprotocol);
}
return lib::error_code();
}
/// Fill in a set of request headers for a client connection request
/**
* The Hybi 00 processor only implements incoming connections so this will
* always return an error.
*
* @param [out] req Set of headers to fill in
* @param [in] uri The uri being connected to
* @param [in] subprotocols The list of subprotocols to request
*/
lib::error_code client_handshake_request(request_type &, uri_ptr,
std::vector<std::string> const &) const
{
return error::make_error_code(error::no_protocol_support);
}
/// Validate the server's response to an outgoing handshake request
/**
* The Hybi 00 processor only implements incoming connections so this will
* always return an error.
*
* @param req The original request sent
* @param res The reponse to generate
* @return An error code, 0 on success, non-zero for other errors
*/
lib::error_code validate_server_handshake_response(request_type const &,
response_type &) const
{
return error::make_error_code(error::no_protocol_support);
}
std::string get_raw(response_type const & res) const {
response_type temp = res;
temp.remove_header("Sec-WebSocket-Key3");
return temp.raw() + res.get_header("Sec-WebSocket-Key3");
}
std::string const & get_origin(request_type const & r) const {
return r.get_header("Origin");
}
/// Extracts requested subprotocols from a handshake request
/**
* hybi00 does support subprotocols
* https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00#section-1.9
*
* @param [in] req The request to extract from
* @param [out] subprotocol_list A reference to a vector of strings to store
* the results in.
*/
lib::error_code extract_subprotocols(request_type const & req,
std::vector<std::string> & subprotocol_list)
{
if (!req.get_header("Sec-WebSocket-Protocol").empty()) {
http::parameter_list p;
if (!req.get_header_as_plist("Sec-WebSocket-Protocol",p)) {
http::parameter_list::const_iterator it;
for (it = p.begin(); it != p.end(); ++it) {
subprotocol_list.push_back(it->first);
}
} else {
return error::make_error_code(error::subprotocol_parse_error);
}
}
return lib::error_code();
}
uri_ptr get_uri(request_type const & request) const {
std::string h = request.get_header("Host");
size_t last_colon = h.rfind(":");
size_t last_sbrace = h.rfind("]");
// no : = hostname with no port
// last : before ] = ipv6 literal with no port
// : with no ] = hostname with port
// : after ] = ipv6 literal with port
if (last_colon == std::string::npos ||
(last_sbrace != std::string::npos && last_sbrace > last_colon))
{
return lib::make_shared<uri>(base::m_secure, h, request.get_uri());
} else {
return lib::make_shared<uri>(base::m_secure,
h.substr(0,last_colon),
h.substr(last_colon+1),
request.get_uri());
}
// TODO: check if get_uri is a full uri
}
/// Get hybi00 handshake key3
/**
* @todo This doesn't appear to be used anymore. It might be able to be
* removed
*/
std::string get_key3() const {
return "";
}
/// Process new websocket connection bytes
size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) {
// if in state header we are expecting a 0x00 byte, if we don't get one
// it is a fatal error
size_t p = 0; // bytes processed
size_t l = 0;
ec = lib::error_code();
while (p < len) {
if (m_state == HEADER) {
if (buf[p] == msg_hdr) {
p++;
m_msg_ptr = m_msg_manager->get_message(frame::opcode::text,1);
if (!m_msg_ptr) {
ec = make_error_code(websocketpp::error::no_incoming_buffers);
m_state = FATAL_ERROR;
} else {
m_state = PAYLOAD;
}
} else {
ec = make_error_code(error::protocol_violation);
m_state = FATAL_ERROR;
}
} else if (m_state == PAYLOAD) {
uint8_t *it = std::find(buf+p,buf+len,msg_ftr);
// 0 1 2 3 4 5
// 0x00 0x23 0x23 0x23 0xff 0xXX
// Copy payload bytes into message
l = static_cast<size_t>(it-(buf+p));
m_msg_ptr->append_payload(buf+p,l);
p += l;
if (it != buf+len) {
// message is done, copy it and the trailing
p++;
// TODO: validation
m_state = READY;
}
} else {
// TODO
break;
}
}
// If we get one, we create a new message and move to application state
// if in state application we are copying bytes into the output message
// and validating them for UTF8 until we hit a 0xff byte. Once we hit
// 0x00, the message is complete and is dispatched. Then we go back to
// header state.
//ec = make_error_code(error::not_implemented);
return p;
}
bool ready() const {
return (m_state == READY);
}
bool get_error() const {
return false;
}
message_ptr get_message() {
message_ptr ret = m_msg_ptr;
m_msg_ptr = message_ptr();
m_state = HEADER;
return ret;
}
/// Prepare a message for writing
/**
* Performs validation, masking, compression, etc. will return an error if
* there was an error, otherwise msg will be ready to be written
*/
virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out)
{
if (!in || !out) {
return make_error_code(error::invalid_arguments);
}
// TODO: check if the message is prepared already
// validate opcode
if (in->get_opcode() != frame::opcode::text) {
return make_error_code(error::invalid_opcode);
}
std::string& i = in->get_raw_payload();
//std::string& o = out->get_raw_payload();
// validate payload utf8
if (!utf8_validator::validate(i)) {
return make_error_code(error::invalid_payload);
}
// generate header
out->set_header(std::string(reinterpret_cast<char const *>(&msg_hdr),1));
// process payload
out->set_payload(i);
out->append_payload(std::string(reinterpret_cast<char const *>(&msg_ftr),1));
// hybi00 doesn't support compression
// hybi00 doesn't have masking
out->set_prepared(true);
return lib::error_code();
}
/// Prepare a ping frame
/**
* Hybi 00 doesn't support pings so this will always return an error
*
* @param in The string to use for the ping payload
* @param out The message buffer to prepare the ping in.
* @return Status code, zero on success, non-zero on failure
*/
lib::error_code prepare_ping(std::string const &, message_ptr) const
{
return lib::error_code(error::no_protocol_support);
}
/// Prepare a pong frame
/**
* Hybi 00 doesn't support pongs so this will always return an error
*
* @param in The string to use for the pong payload
* @param out The message buffer to prepare the pong in.
* @return Status code, zero on success, non-zero on failure
*/
lib::error_code prepare_pong(std::string const &, message_ptr) const
{
return lib::error_code(error::no_protocol_support);
}
/// Prepare a close frame
/**
* Hybi 00 doesn't support the close code or reason so these parameters are
* ignored.
*
* @param code The close code to send
* @param reason The reason string to send
* @param out The message buffer to prepare the fame in
* @return Status code, zero on success, non-zero on failure
*/
lib::error_code prepare_close(close::status::value, std::string const &,
message_ptr out) const
{
if (!out) {
return lib::error_code(error::invalid_arguments);
}
std::string val;
val.append(1,'\xff');
val.append(1,'\x00');
out->set_payload(val);
out->set_prepared(true);
return lib::error_code();
}
private:
void decode_client_key(std::string const & key, char * result) const {
unsigned int spaces = 0;
std::string digits;
uint32_t num;
// key2
for (size_t i = 0; i < key.size(); i++) {
if (key[i] == ' ') {
spaces++;
} else if (key[i] >= '0' && key[i] <= '9') {
digits += key[i];
}
}
num = static_cast<uint32_t>(strtoul(digits.c_str(), NULL, 10));
if (spaces > 0 && num > 0) {
num = htonl(num/spaces);
std::copy(reinterpret_cast<char*>(&num),
reinterpret_cast<char*>(&num)+4,
result);
} else {
std::fill(result,result+4,0);
}
}
enum state {
HEADER = 0,
PAYLOAD = 1,
READY = 2,
FATAL_ERROR = 3
};
uint8_t const msg_hdr;
uint8_t const msg_ftr;
state m_state;
msg_manager_ptr m_msg_manager;
message_ptr m_msg_ptr;
utf8_validator::validator m_validator;
};
} // namespace processor
} // namespace websocketpp
#endif //WEBSOCKETPP_PROCESSOR_HYBI00_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_PROCESSOR_HYBI00_HPP
#define WEBSOCKETPP_PROCESSOR_HYBI00_HPP
#include <websocketpp/frame.hpp>
#include <websocketpp/http/constants.hpp>
#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>
#include <algorithm>
#include <cstdlib>
#include <string>
#include <vector>
namespace websocketpp {
namespace processor {
/// Processor for Hybi Draft version 00
/**
* There are many differences between Hybi 00 and Hybi 13
*/
template <typename config>
class hybi00 : public processor<config> {
public:
typedef processor<config> base;
typedef typename config::request_type request_type;
typedef typename config::response_type response_type;
typedef typename config::message_type message_type;
typedef typename message_type::ptr message_ptr;
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
explicit hybi00(bool secure, bool p_is_server, msg_manager_ptr manager)
: processor<config>(secure, p_is_server)
, msg_hdr(0x00)
, msg_ftr(0xff)
, m_state(HEADER)
, m_msg_manager(manager) {}
int get_version() const {
return 0;
}
lib::error_code validate_handshake(request_type const & r) const {
if (r.get_method() != "GET") {
return make_error_code(error::invalid_http_method);
}
if (r.get_version() != "HTTP/1.1") {
return make_error_code(error::invalid_http_version);
}
// required headers
// Host is required by HTTP/1.1
// Connection is required by is_websocket_handshake
// Upgrade is required by is_websocket_handshake
if (r.get_header("Sec-WebSocket-Key1").empty() ||
r.get_header("Sec-WebSocket-Key2").empty() ||
r.get_header("Sec-WebSocket-Key3").empty())
{
return make_error_code(error::missing_required_header);
}
return lib::error_code();
}
lib::error_code process_handshake(request_type const & req,
std::string const & subprotocol, response_type & res) const
{
char key_final[16];
// copy key1 into final key
decode_client_key(req.get_header("Sec-WebSocket-Key1"), &key_final[0]);
// copy key2 into final key
decode_client_key(req.get_header("Sec-WebSocket-Key2"), &key_final[4]);
// copy key3 into final key
// key3 should be exactly 8 bytes. If it is more it will be truncated
// if it is less the final key will almost certainly be wrong.
// TODO: decide if it is best to silently fail here or produce some sort
// of warning or exception.
std::string const & key3 = req.get_header("Sec-WebSocket-Key3");
std::copy(key3.c_str(),
key3.c_str()+(std::min)(static_cast<size_t>(8), key3.size()),
&key_final[8]);
res.append_header(
"Sec-WebSocket-Key3",
md5::md5_hash_string(std::string(key_final,16))
);
res.append_header("Upgrade","WebSocket");
res.append_header("Connection","Upgrade");
// Echo back client's origin unless our local application set a
// more restrictive one.
if (res.get_header("Sec-WebSocket-Origin").empty()) {
res.append_header("Sec-WebSocket-Origin",req.get_header("Origin"));
}
// Echo back the client's request host unless our local application
// set a different one.
if (res.get_header("Sec-WebSocket-Location").empty()) {
uri_ptr uri = get_uri(req);
res.append_header("Sec-WebSocket-Location",uri->str());
}
if (!subprotocol.empty()) {
res.replace_header("Sec-WebSocket-Protocol",subprotocol);
}
return lib::error_code();
}
/// Fill in a set of request headers for a client connection request
/**
* The Hybi 00 processor only implements incoming connections so this will
* always return an error.
*
* @param [out] req Set of headers to fill in
* @param [in] uri The uri being connected to
* @param [in] subprotocols The list of subprotocols to request
*/
lib::error_code client_handshake_request(request_type &, uri_ptr,
std::vector<std::string> const &) const
{
return error::make_error_code(error::no_protocol_support);
}
/// Validate the server's response to an outgoing handshake request
/**
* The Hybi 00 processor only implements incoming connections so this will
* always return an error.
*
* @param req The original request sent
* @param res The reponse to generate
* @return An error code, 0 on success, non-zero for other errors
*/
lib::error_code validate_server_handshake_response(request_type const &,
response_type &) const
{
return error::make_error_code(error::no_protocol_support);
}
std::string get_raw(response_type const & res) const {
response_type temp = res;
temp.remove_header("Sec-WebSocket-Key3");
return temp.raw() + res.get_header("Sec-WebSocket-Key3");
}
std::string const & get_origin(request_type const & r) const {
return r.get_header("Origin");
}
/// Extracts requested subprotocols from a handshake request
/**
* hybi00 does support subprotocols
* https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00#section-1.9
*
* @param [in] req The request to extract from
* @param [out] subprotocol_list A reference to a vector of strings to store
* the results in.
*/
lib::error_code extract_subprotocols(request_type const & req,
std::vector<std::string> & subprotocol_list)
{
if (!req.get_header("Sec-WebSocket-Protocol").empty()) {
http::parameter_list p;
if (!req.get_header_as_plist("Sec-WebSocket-Protocol",p)) {
http::parameter_list::const_iterator it;
for (it = p.begin(); it != p.end(); ++it) {
subprotocol_list.push_back(it->first);
}
} else {
return error::make_error_code(error::subprotocol_parse_error);
}
}
return lib::error_code();
}
uri_ptr get_uri(request_type const & request) const {
std::string h = request.get_header("Host");
size_t last_colon = h.rfind(":");
size_t last_sbrace = h.rfind("]");
// no : = hostname with no port
// last : before ] = ipv6 literal with no port
// : with no ] = hostname with port
// : after ] = ipv6 literal with port
if (last_colon == std::string::npos ||
(last_sbrace != std::string::npos && last_sbrace > last_colon))
{
return lib::make_shared<uri>(base::m_secure, h, request.get_uri());
} else {
return lib::make_shared<uri>(base::m_secure,
h.substr(0,last_colon),
h.substr(last_colon+1),
request.get_uri());
}
// TODO: check if get_uri is a full uri
}
/// Get hybi00 handshake key3
/**
* @todo This doesn't appear to be used anymore. It might be able to be
* removed
*/
std::string get_key3() const {
return "";
}
/// Process new websocket connection bytes
size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) {
// if in state header we are expecting a 0x00 byte, if we don't get one
// it is a fatal error
size_t p = 0; // bytes processed
size_t l = 0;
ec = lib::error_code();
while (p < len) {
if (m_state == HEADER) {
if (buf[p] == msg_hdr) {
p++;
m_msg_ptr = m_msg_manager->get_message(frame::opcode::text,1);
if (!m_msg_ptr) {
ec = make_error_code(websocketpp::error::no_incoming_buffers);
m_state = FATAL_ERROR;
} else {
m_state = PAYLOAD;
}
} else {
ec = make_error_code(error::protocol_violation);
m_state = FATAL_ERROR;
}
} else if (m_state == PAYLOAD) {
uint8_t *it = std::find(buf+p,buf+len,msg_ftr);
// 0 1 2 3 4 5
// 0x00 0x23 0x23 0x23 0xff 0xXX
// Copy payload bytes into message
l = static_cast<size_t>(it-(buf+p));
m_msg_ptr->append_payload(buf+p,l);
p += l;
if (it != buf+len) {
// message is done, copy it and the trailing
p++;
// TODO: validation
m_state = READY;
}
} else {
// TODO
break;
}
}
// If we get one, we create a new message and move to application state
// if in state application we are copying bytes into the output message
// and validating them for UTF8 until we hit a 0xff byte. Once we hit
// 0x00, the message is complete and is dispatched. Then we go back to
// header state.
//ec = make_error_code(error::not_implemented);
return p;
}
bool ready() const {
return (m_state == READY);
}
bool get_error() const {
return false;
}
message_ptr get_message() {
message_ptr ret = m_msg_ptr;
m_msg_ptr = message_ptr();
m_state = HEADER;
return ret;
}
/// Prepare a message for writing
/**
* Performs validation, masking, compression, etc. will return an error if
* there was an error, otherwise msg will be ready to be written
*/
virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out)
{
if (!in || !out) {
return make_error_code(error::invalid_arguments);
}
// TODO: check if the message is prepared already
// validate opcode
if (in->get_opcode() != frame::opcode::text) {
return make_error_code(error::invalid_opcode);
}
std::string& i = in->get_raw_payload();
//std::string& o = out->get_raw_payload();
// validate payload utf8
if (!utf8_validator::validate(i)) {
return make_error_code(error::invalid_payload);
}
// generate header
out->set_header(std::string(reinterpret_cast<char const *>(&msg_hdr),1));
// process payload
out->set_payload(i);
out->append_payload(std::string(reinterpret_cast<char const *>(&msg_ftr),1));
// hybi00 doesn't support compression
// hybi00 doesn't have masking
out->set_prepared(true);
return lib::error_code();
}
/// Prepare a ping frame
/**
* Hybi 00 doesn't support pings so this will always return an error
*
* @param in The string to use for the ping payload
* @param out The message buffer to prepare the ping in.
* @return Status code, zero on success, non-zero on failure
*/
lib::error_code prepare_ping(std::string const &, message_ptr) const
{
return lib::error_code(error::no_protocol_support);
}
/// Prepare a pong frame
/**
* Hybi 00 doesn't support pongs so this will always return an error
*
* @param in The string to use for the pong payload
* @param out The message buffer to prepare the pong in.
* @return Status code, zero on success, non-zero on failure
*/
lib::error_code prepare_pong(std::string const &, message_ptr) const
{
return lib::error_code(error::no_protocol_support);
}
/// Prepare a close frame
/**
* Hybi 00 doesn't support the close code or reason so these parameters are
* ignored.
*
* @param code The close code to send
* @param reason The reason string to send
* @param out The message buffer to prepare the fame in
* @return Status code, zero on success, non-zero on failure
*/
lib::error_code prepare_close(close::status::value, std::string const &,
message_ptr out) const
{
if (!out) {
return lib::error_code(error::invalid_arguments);
}
std::string val;
val.append(1,'\xff');
val.append(1,'\x00');
out->set_payload(val);
out->set_prepared(true);
return lib::error_code();
}
private:
void decode_client_key(std::string const & key, char * result) const {
unsigned int spaces = 0;
std::string digits;
uint32_t num;
// key2
for (size_t i = 0; i < key.size(); i++) {
if (key[i] == ' ') {
spaces++;
} else if (key[i] >= '0' && key[i] <= '9') {
digits += key[i];
}
}
num = static_cast<uint32_t>(strtoul(digits.c_str(), NULL, 10));
if (spaces > 0 && num > 0) {
num = htonl(num/spaces);
std::copy(reinterpret_cast<char*>(&num),
reinterpret_cast<char*>(&num)+4,
result);
} else {
std::fill(result,result+4,0);
}
}
enum state {
HEADER = 0,
PAYLOAD = 1,
READY = 2,
FATAL_ERROR = 3
};
uint8_t const msg_hdr;
uint8_t const msg_ftr;
state m_state;
msg_manager_ptr m_msg_manager;
message_ptr m_msg_ptr;
utf8_validator::validator m_validator;
};
} // namespace processor
} // namespace websocketpp
#endif //WEBSOCKETPP_PROCESSOR_HYBI00_HPP

View File

@@ -1,78 +1,78 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_PROCESSOR_HYBI07_HPP
#define WEBSOCKETPP_PROCESSOR_HYBI07_HPP
#include <websocketpp/processors/hybi08.hpp>
#include <string>
#include <vector>
namespace websocketpp {
namespace processor {
/// Processor for Hybi Draft version 07
/**
* The primary difference between 07 and 08 is a version number.
*/
template <typename config>
class hybi07 : public hybi08<config> {
public:
typedef typename config::request_type request_type;
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
typedef typename config::rng_type rng_type;
explicit hybi07(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
: hybi08<config>(secure, p_is_server, manager, rng) {}
/// Fill in a set of request headers for a client connection request
/**
* The Hybi 07 processor only implements incoming connections so this will
* always return an error.
*
* @param [out] req Set of headers to fill in
* @param [in] uri The uri being connected to
* @param [in] subprotocols The list of subprotocols to request
*/
lib::error_code client_handshake_request(request_type &, uri_ptr,
std::vector<std::string> const &) const
{
return error::make_error_code(error::no_protocol_support);
}
int get_version() const {
return 7;
}
private:
};
} // namespace processor
} // namespace websocketpp
#endif //WEBSOCKETPP_PROCESSOR_HYBI07_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_PROCESSOR_HYBI07_HPP
#define WEBSOCKETPP_PROCESSOR_HYBI07_HPP
#include <websocketpp/processors/hybi08.hpp>
#include <string>
#include <vector>
namespace websocketpp {
namespace processor {
/// Processor for Hybi Draft version 07
/**
* The primary difference between 07 and 08 is a version number.
*/
template <typename config>
class hybi07 : public hybi08<config> {
public:
typedef typename config::request_type request_type;
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
typedef typename config::rng_type rng_type;
explicit hybi07(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
: hybi08<config>(secure, p_is_server, manager, rng) {}
/// Fill in a set of request headers for a client connection request
/**
* The Hybi 07 processor only implements incoming connections so this will
* always return an error.
*
* @param [out] req Set of headers to fill in
* @param [in] uri The uri being connected to
* @param [in] subprotocols The list of subprotocols to request
*/
lib::error_code client_handshake_request(request_type &, uri_ptr,
std::vector<std::string> const &) const
{
return error::make_error_code(error::no_protocol_support);
}
int get_version() const {
return 7;
}
private:
};
} // namespace processor
} // namespace websocketpp
#endif //WEBSOCKETPP_PROCESSOR_HYBI07_HPP

View File

@@ -1,83 +1,83 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_PROCESSOR_HYBI08_HPP
#define WEBSOCKETPP_PROCESSOR_HYBI08_HPP
#include <websocketpp/processors/hybi13.hpp>
#include <string>
#include <vector>
namespace websocketpp {
namespace processor {
/// Processor for Hybi Draft version 08
/**
* The primary difference between 08 and 13 is a different origin header name
*/
template <typename config>
class hybi08 : public hybi13<config> {
public:
typedef hybi08<config> type;
typedef typename config::request_type request_type;
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
typedef typename config::rng_type rng_type;
explicit hybi08(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
: hybi13<config>(secure, p_is_server, manager, rng) {}
/// Fill in a set of request headers for a client connection request
/**
* The Hybi 08 processor only implements incoming connections so this will
* always return an error.
*
* @param [out] req Set of headers to fill in
* @param [in] uri The uri being connected to
* @param [in] subprotocols The list of subprotocols to request
*/
lib::error_code client_handshake_request(request_type &, uri_ptr,
std::vector<std::string> const &) const
{
return error::make_error_code(error::no_protocol_support);
}
int get_version() const {
return 8;
}
std::string const & get_origin(request_type const & r) const {
return r.get_header("Sec-WebSocket-Origin");
}
private:
};
} // namespace processor
} // namespace websocketpp
#endif //WEBSOCKETPP_PROCESSOR_HYBI08_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_PROCESSOR_HYBI08_HPP
#define WEBSOCKETPP_PROCESSOR_HYBI08_HPP
#include <websocketpp/processors/hybi13.hpp>
#include <string>
#include <vector>
namespace websocketpp {
namespace processor {
/// Processor for Hybi Draft version 08
/**
* The primary difference between 08 and 13 is a different origin header name
*/
template <typename config>
class hybi08 : public hybi13<config> {
public:
typedef hybi08<config> type;
typedef typename config::request_type request_type;
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
typedef typename config::rng_type rng_type;
explicit hybi08(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
: hybi13<config>(secure, p_is_server, manager, rng) {}
/// Fill in a set of request headers for a client connection request
/**
* The Hybi 08 processor only implements incoming connections so this will
* always return an error.
*
* @param [out] req Set of headers to fill in
* @param [in] uri The uri being connected to
* @param [in] subprotocols The list of subprotocols to request
*/
lib::error_code client_handshake_request(request_type &, uri_ptr,
std::vector<std::string> const &) const
{
return error::make_error_code(error::no_protocol_support);
}
int get_version() const {
return 8;
}
std::string const & get_origin(request_type const & r) const {
return r.get_header("Sec-WebSocket-Origin");
}
private:
};
} // namespace processor
} // namespace websocketpp
#endif //WEBSOCKETPP_PROCESSOR_HYBI08_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -1,407 +1,407 @@
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_PROCESSOR_HPP
#define WEBSOCKETPP_PROCESSOR_HPP
#include <websocketpp/processors/base.hpp>
#include <websocketpp/common/system_error.hpp>
#include <websocketpp/close.hpp>
#include <websocketpp/utilities.hpp>
#include <websocketpp/uri.hpp>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
namespace websocketpp {
/// Processors encapsulate the protocol rules specific to each WebSocket version
/**
* The processors namespace includes a number of free functions that operate on
* various WebSocket related data structures and perform processing that is not
* related to specific versions of the protocol.
*
* It also includes the abstract interface for the protocol specific processing
* engines. These engines wrap all of the logic necessary for parsing and
* validating WebSocket handshakes and messages of specific protocol version
* and set of allowed extensions.
*
* An instance of a processor represents the state of a single WebSocket
* connection of the associated version. One processor instance is needed per
* logical WebSocket connection.
*/
namespace processor {
/// Determine whether or not a generic HTTP request is a WebSocket handshake
/**
* @param r The HTTP request to read.
*
* @return True if the request is a WebSocket handshake, false otherwise
*/
template <typename request_type>
bool is_websocket_handshake(request_type& r) {
using utility::ci_find_substr;
std::string const & upgrade_header = r.get_header("Upgrade");
if (ci_find_substr(upgrade_header, constants::upgrade_token,
sizeof(constants::upgrade_token)-1) == upgrade_header.end())
{
return false;
}
std::string const & con_header = r.get_header("Connection");
if (ci_find_substr(con_header, constants::connection_token,
sizeof(constants::connection_token)-1) == con_header.end())
{
return false;
}
return true;
}
/// Extract the version from a WebSocket handshake request
/**
* A blank version header indicates a spec before versions were introduced.
* The only such versions in shipping products are Hixie Draft 75 and Hixie
* Draft 76. Draft 75 is present in Chrome 4-5 and Safari 5.0.0, Draft 76 (also
* known as hybi 00 is present in Chrome 6-13 and Safari 5.0.1+. As
* differentiating between these two sets of browsers is very difficult and
* Safari 5.0.1+ accounts for the vast majority of cases in the wild this
* function assumes that all handshakes without a valid version header are
* Hybi 00.
*
* @param r The WebSocket handshake request to read.
*
* @return The WebSocket handshake version or -1 if there was an extraction
* error.
*/
template <typename request_type>
int get_websocket_version(request_type& r) {
if (!r.ready()) {
return -2;
}
if (r.get_header("Sec-WebSocket-Version").empty()) {
return 0;
}
int version;
std::istringstream ss(r.get_header("Sec-WebSocket-Version"));
if ((ss >> version).fail()) {
return -1;
}
return version;
}
/// Extract a URI ptr from the host header of the request
/**
* @param request The request to extract the Host header from.
*
* @param scheme The scheme under which this request was received (ws, wss,
* http, https, etc)
*
* @return A uri_pointer that encodes the value of the host header.
*/
template <typename request_type>
uri_ptr get_uri_from_host(request_type & request, std::string scheme) {
std::string h = request.get_header("Host");
size_t last_colon = h.rfind(":");
size_t last_sbrace = h.rfind("]");
// no : = hostname with no port
// last : before ] = ipv6 literal with no port
// : with no ] = hostname with port
// : after ] = ipv6 literal with port
if (last_colon == std::string::npos ||
(last_sbrace != std::string::npos && last_sbrace > last_colon))
{
return lib::make_shared<uri>(scheme, h, request.get_uri());
} else {
return lib::make_shared<uri>(scheme,
h.substr(0,last_colon),
h.substr(last_colon+1),
request.get_uri());
}
}
/// WebSocket protocol processor abstract base class
template <typename config>
class processor {
public:
typedef processor<config> type;
typedef typename config::request_type request_type;
typedef typename config::response_type response_type;
typedef typename config::message_type::ptr message_ptr;
typedef std::pair<lib::error_code,std::string> err_str_pair;
explicit processor(bool secure, bool p_is_server)
: m_secure(secure)
, m_server(p_is_server)
, m_max_message_size(config::max_message_size)
{}
virtual ~processor() {}
/// Get the protocol version of this processor
virtual int get_version() const = 0;
/// Get maximum message size
/**
* Get maximum message size. Maximum message size determines the point at which the
* processor will fail a connection with the message_too_big protocol error.
*
* The default is retrieved from the max_message_size value from the template config
*
* @since 0.3.0
*/
size_t get_max_message_size() const {
return m_max_message_size;
}
/// Set maximum message size
/**
* Set maximum message size. Maximum message size determines the point at which the
* processor will fail a connection with the message_too_big protocol error.
*
* The default is retrieved from the max_message_size value from the template config
*
* @since 0.3.0
*
* @param new_value The value to set as the maximum message size.
*/
void set_max_message_size(size_t new_value) {
m_max_message_size = new_value;
}
/// Returns whether or not the permessage_compress extension is implemented
/**
* Compile time flag that indicates whether this processor has implemented
* the permessage_compress extension. By default this is false.
*/
virtual bool has_permessage_compress() const {
return false;
}
/// Initializes extensions based on the Sec-WebSocket-Extensions header
/**
* Reads the Sec-WebSocket-Extensions header and determines if any of the
* requested extensions are supported by this processor. If they are their
* settings data is initialized and an extension string to send to the
* is returned.
*
* @param request The request or response headers to look at.
*/
virtual err_str_pair negotiate_extensions(request_type const &) {
return err_str_pair();
}
/// Initializes extensions based on the Sec-WebSocket-Extensions header
/**
* Reads the Sec-WebSocket-Extensions header and determines if any of the
* requested extensions were accepted by the server. If they are their
* settings data is initialized. If they are not a list of required
* extensions (if any) is returned. This list may be sent back to the server
* as a part of the 1010/Extension required close code.
*
* @param response The request or response headers to look at.
*/
virtual err_str_pair negotiate_extensions(response_type const &) {
return err_str_pair();
}
/// validate a WebSocket handshake request for this version
/**
* @param request The WebSocket handshake request to validate.
* is_websocket_handshake(request) must be true and
* get_websocket_version(request) must equal this->get_version().
*
* @return A status code, 0 on success, non-zero for specific sorts of
* failure
*/
virtual lib::error_code validate_handshake(request_type const & request) const = 0;
/// Calculate the appropriate response for this websocket request
/**
* @param req The request to process
*
* @param subprotocol The subprotocol in use
*
* @param res The response to store the processed response in
*
* @return An error code, 0 on success, non-zero for other errors
*/
virtual lib::error_code process_handshake(request_type const & req,
std::string const & subprotocol, response_type& res) const = 0;
/// Fill in an HTTP request for an outgoing connection handshake
/**
* @param req The request to process.
*
* @return An error code, 0 on success, non-zero for other errors
*/
virtual lib::error_code client_handshake_request(request_type & req,
uri_ptr uri, std::vector<std::string> const & subprotocols) const = 0;
/// Validate the server's response to an outgoing handshake request
/**
* @param req The original request sent
* @param res The reponse to generate
* @return An error code, 0 on success, non-zero for other errors
*/
virtual lib::error_code validate_server_handshake_response(request_type
const & req, response_type & res) const = 0;
/// Given a completed response, get the raw bytes to put on the wire
virtual std::string get_raw(response_type const & request) const = 0;
/// Return the value of the header containing the CORS origin.
virtual std::string const & get_origin(request_type const & request) const = 0;
/// Extracts requested subprotocols from a handshake request
/**
* Extracts a list of all subprotocols that the client has requested in the
* given opening handshake request.
*
* @param [in] req The request to extract from
* @param [out] subprotocol_list A reference to a vector of strings to store
* the results in.
*/
virtual lib::error_code extract_subprotocols(const request_type & req,
std::vector<std::string> & subprotocol_list) = 0;
/// Extracts client uri from a handshake request
virtual uri_ptr get_uri(request_type const & request) const = 0;
/// process new websocket connection bytes
/**
* WebSocket connections are a continous stream of bytes that must be
* interpreted by a protocol processor into discrete frames.
*
* @param buf Buffer from which bytes should be read.
* @param len Length of buffer
* @param ec Reference to an error code to return any errors in
* @return Number of bytes processed
*/
virtual size_t consume(uint8_t *buf, size_t len, lib::error_code & ec) = 0;
/// Checks if there is a message ready
/**
* Checks if the most recent consume operation processed enough bytes to
* complete a new WebSocket message. The message can be retrieved by calling
* get_message() which will reset the internal state to not-ready and allow
* consume to read more bytes.
*
* @return Whether or not a message is ready.
*/
virtual bool ready() const = 0;
/// Retrieves the most recently processed message
/**
* Retrieves a shared pointer to the recently completed message if there is
* one. If ready() returns true then there is a message available.
* Retrieving the message with get_message will reset the state of ready.
* As such, each new message may be retrieved only once. Calling get_message
* when there is no message available will result in a null pointer being
* returned.
*
* @return A pointer to the most recently processed message or a null shared
* pointer.
*/
virtual message_ptr get_message() = 0;
/// Tests whether the processor is in a fatal error state
virtual bool get_error() const = 0;
/// Retrieves the number of bytes presently needed by the processor
/// This value may be used as a hint to the transport layer as to how many
/// bytes to wait for before running consume again.
virtual size_t get_bytes_needed() const {
return 1;
}
/// Prepare a data message for writing
/**
* Performs validation, masking, compression, etc. will return an error if
* there was an error, otherwise msg will be ready to be written
*/
virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) = 0;
/// Prepare a ping frame
/**
* Ping preparation is entirely state free. There is no payload validation
* other than length. Payload need not be UTF-8.
*
* @param in The string to use for the ping payload
* @param out The message buffer to prepare the ping in.
* @return Status code, zero on success, non-zero on failure
*/
virtual lib::error_code prepare_ping(std::string const & in, message_ptr out) const
= 0;
/// Prepare a pong frame
/**
* Pong preparation is entirely state free. There is no payload validation
* other than length. Payload need not be UTF-8.
*
* @param in The string to use for the pong payload
* @param out The message buffer to prepare the pong in.
* @return Status code, zero on success, non-zero on failure
*/
virtual lib::error_code prepare_pong(std::string const & in, message_ptr out) const
= 0;
/// Prepare a close frame
/**
* Close preparation is entirely state free. The code and reason are both
* subject to validation. Reason must be valid UTF-8. Code must be a valid
* un-reserved WebSocket close code. Use close::status::no_status to
* indicate no code. If no code is supplied a reason may not be specified.
*
* @param code The close code to send
* @param reason The reason string to send
* @param out The message buffer to prepare the fame in
* @return Status code, zero on success, non-zero on failure
*/
virtual lib::error_code prepare_close(close::status::value code,
std::string const & reason, message_ptr out) const = 0;
protected:
bool const m_secure;
bool const m_server;
size_t m_max_message_size;
};
} // namespace processor
} // namespace websocketpp
#endif //WEBSOCKETPP_PROCESSOR_HPP
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_PROCESSOR_HPP
#define WEBSOCKETPP_PROCESSOR_HPP
#include <websocketpp/processors/base.hpp>
#include <websocketpp/common/system_error.hpp>
#include <websocketpp/close.hpp>
#include <websocketpp/utilities.hpp>
#include <websocketpp/uri.hpp>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
namespace websocketpp {
/// Processors encapsulate the protocol rules specific to each WebSocket version
/**
* The processors namespace includes a number of free functions that operate on
* various WebSocket related data structures and perform processing that is not
* related to specific versions of the protocol.
*
* It also includes the abstract interface for the protocol specific processing
* engines. These engines wrap all of the logic necessary for parsing and
* validating WebSocket handshakes and messages of specific protocol version
* and set of allowed extensions.
*
* An instance of a processor represents the state of a single WebSocket
* connection of the associated version. One processor instance is needed per
* logical WebSocket connection.
*/
namespace processor {
/// Determine whether or not a generic HTTP request is a WebSocket handshake
/**
* @param r The HTTP request to read.
*
* @return True if the request is a WebSocket handshake, false otherwise
*/
template <typename request_type>
bool is_websocket_handshake(request_type& r) {
using utility::ci_find_substr;
std::string const & upgrade_header = r.get_header("Upgrade");
if (ci_find_substr(upgrade_header, constants::upgrade_token,
sizeof(constants::upgrade_token)-1) == upgrade_header.end())
{
return false;
}
std::string const & con_header = r.get_header("Connection");
if (ci_find_substr(con_header, constants::connection_token,
sizeof(constants::connection_token)-1) == con_header.end())
{
return false;
}
return true;
}
/// Extract the version from a WebSocket handshake request
/**
* A blank version header indicates a spec before versions were introduced.
* The only such versions in shipping products are Hixie Draft 75 and Hixie
* Draft 76. Draft 75 is present in Chrome 4-5 and Safari 5.0.0, Draft 76 (also
* known as hybi 00 is present in Chrome 6-13 and Safari 5.0.1+. As
* differentiating between these two sets of browsers is very difficult and
* Safari 5.0.1+ accounts for the vast majority of cases in the wild this
* function assumes that all handshakes without a valid version header are
* Hybi 00.
*
* @param r The WebSocket handshake request to read.
*
* @return The WebSocket handshake version or -1 if there was an extraction
* error.
*/
template <typename request_type>
int get_websocket_version(request_type& r) {
if (!r.ready()) {
return -2;
}
if (r.get_header("Sec-WebSocket-Version").empty()) {
return 0;
}
int version;
std::istringstream ss(r.get_header("Sec-WebSocket-Version"));
if ((ss >> version).fail()) {
return -1;
}
return version;
}
/// Extract a URI ptr from the host header of the request
/**
* @param request The request to extract the Host header from.
*
* @param scheme The scheme under which this request was received (ws, wss,
* http, https, etc)
*
* @return A uri_pointer that encodes the value of the host header.
*/
template <typename request_type>
uri_ptr get_uri_from_host(request_type & request, std::string scheme) {
std::string h = request.get_header("Host");
size_t last_colon = h.rfind(":");
size_t last_sbrace = h.rfind("]");
// no : = hostname with no port
// last : before ] = ipv6 literal with no port
// : with no ] = hostname with port
// : after ] = ipv6 literal with port
if (last_colon == std::string::npos ||
(last_sbrace != std::string::npos && last_sbrace > last_colon))
{
return lib::make_shared<uri>(scheme, h, request.get_uri());
} else {
return lib::make_shared<uri>(scheme,
h.substr(0,last_colon),
h.substr(last_colon+1),
request.get_uri());
}
}
/// WebSocket protocol processor abstract base class
template <typename config>
class processor {
public:
typedef processor<config> type;
typedef typename config::request_type request_type;
typedef typename config::response_type response_type;
typedef typename config::message_type::ptr message_ptr;
typedef std::pair<lib::error_code,std::string> err_str_pair;
explicit processor(bool secure, bool p_is_server)
: m_secure(secure)
, m_server(p_is_server)
, m_max_message_size(config::max_message_size)
{}
virtual ~processor() {}
/// Get the protocol version of this processor
virtual int get_version() const = 0;
/// Get maximum message size
/**
* Get maximum message size. Maximum message size determines the point at which the
* processor will fail a connection with the message_too_big protocol error.
*
* The default is retrieved from the max_message_size value from the template config
*
* @since 0.3.0
*/
size_t get_max_message_size() const {
return m_max_message_size;
}
/// Set maximum message size
/**
* Set maximum message size. Maximum message size determines the point at which the
* processor will fail a connection with the message_too_big protocol error.
*
* The default is retrieved from the max_message_size value from the template config
*
* @since 0.3.0
*
* @param new_value The value to set as the maximum message size.
*/
void set_max_message_size(size_t new_value) {
m_max_message_size = new_value;
}
/// Returns whether or not the permessage_compress extension is implemented
/**
* Compile time flag that indicates whether this processor has implemented
* the permessage_compress extension. By default this is false.
*/
virtual bool has_permessage_compress() const {
return false;
}
/// Initializes extensions based on the Sec-WebSocket-Extensions header
/**
* Reads the Sec-WebSocket-Extensions header and determines if any of the
* requested extensions are supported by this processor. If they are their
* settings data is initialized and an extension string to send to the
* is returned.
*
* @param request The request or response headers to look at.
*/
virtual err_str_pair negotiate_extensions(request_type const &) {
return err_str_pair();
}
/// Initializes extensions based on the Sec-WebSocket-Extensions header
/**
* Reads the Sec-WebSocket-Extensions header and determines if any of the
* requested extensions were accepted by the server. If they are their
* settings data is initialized. If they are not a list of required
* extensions (if any) is returned. This list may be sent back to the server
* as a part of the 1010/Extension required close code.
*
* @param response The request or response headers to look at.
*/
virtual err_str_pair negotiate_extensions(response_type const &) {
return err_str_pair();
}
/// validate a WebSocket handshake request for this version
/**
* @param request The WebSocket handshake request to validate.
* is_websocket_handshake(request) must be true and
* get_websocket_version(request) must equal this->get_version().
*
* @return A status code, 0 on success, non-zero for specific sorts of
* failure
*/
virtual lib::error_code validate_handshake(request_type const & request) const = 0;
/// Calculate the appropriate response for this websocket request
/**
* @param req The request to process
*
* @param subprotocol The subprotocol in use
*
* @param res The response to store the processed response in
*
* @return An error code, 0 on success, non-zero for other errors
*/
virtual lib::error_code process_handshake(request_type const & req,
std::string const & subprotocol, response_type& res) const = 0;
/// Fill in an HTTP request for an outgoing connection handshake
/**
* @param req The request to process.
*
* @return An error code, 0 on success, non-zero for other errors
*/
virtual lib::error_code client_handshake_request(request_type & req,
uri_ptr uri, std::vector<std::string> const & subprotocols) const = 0;
/// Validate the server's response to an outgoing handshake request
/**
* @param req The original request sent
* @param res The reponse to generate
* @return An error code, 0 on success, non-zero for other errors
*/
virtual lib::error_code validate_server_handshake_response(request_type
const & req, response_type & res) const = 0;
/// Given a completed response, get the raw bytes to put on the wire
virtual std::string get_raw(response_type const & request) const = 0;
/// Return the value of the header containing the CORS origin.
virtual std::string const & get_origin(request_type const & request) const = 0;
/// Extracts requested subprotocols from a handshake request
/**
* Extracts a list of all subprotocols that the client has requested in the
* given opening handshake request.
*
* @param [in] req The request to extract from
* @param [out] subprotocol_list A reference to a vector of strings to store
* the results in.
*/
virtual lib::error_code extract_subprotocols(const request_type & req,
std::vector<std::string> & subprotocol_list) = 0;
/// Extracts client uri from a handshake request
virtual uri_ptr get_uri(request_type const & request) const = 0;
/// process new websocket connection bytes
/**
* WebSocket connections are a continous stream of bytes that must be
* interpreted by a protocol processor into discrete frames.
*
* @param buf Buffer from which bytes should be read.
* @param len Length of buffer
* @param ec Reference to an error code to return any errors in
* @return Number of bytes processed
*/
virtual size_t consume(uint8_t *buf, size_t len, lib::error_code & ec) = 0;
/// Checks if there is a message ready
/**
* Checks if the most recent consume operation processed enough bytes to
* complete a new WebSocket message. The message can be retrieved by calling
* get_message() which will reset the internal state to not-ready and allow
* consume to read more bytes.
*
* @return Whether or not a message is ready.
*/
virtual bool ready() const = 0;
/// Retrieves the most recently processed message
/**
* Retrieves a shared pointer to the recently completed message if there is
* one. If ready() returns true then there is a message available.
* Retrieving the message with get_message will reset the state of ready.
* As such, each new message may be retrieved only once. Calling get_message
* when there is no message available will result in a null pointer being
* returned.
*
* @return A pointer to the most recently processed message or a null shared
* pointer.
*/
virtual message_ptr get_message() = 0;
/// Tests whether the processor is in a fatal error state
virtual bool get_error() const = 0;
/// Retrieves the number of bytes presently needed by the processor
/// This value may be used as a hint to the transport layer as to how many
/// bytes to wait for before running consume again.
virtual size_t get_bytes_needed() const {
return 1;
}
/// Prepare a data message for writing
/**
* Performs validation, masking, compression, etc. will return an error if
* there was an error, otherwise msg will be ready to be written
*/
virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) = 0;
/// Prepare a ping frame
/**
* Ping preparation is entirely state free. There is no payload validation
* other than length. Payload need not be UTF-8.
*
* @param in The string to use for the ping payload
* @param out The message buffer to prepare the ping in.
* @return Status code, zero on success, non-zero on failure
*/
virtual lib::error_code prepare_ping(std::string const & in, message_ptr out) const
= 0;
/// Prepare a pong frame
/**
* Pong preparation is entirely state free. There is no payload validation
* other than length. Payload need not be UTF-8.
*
* @param in The string to use for the pong payload
* @param out The message buffer to prepare the pong in.
* @return Status code, zero on success, non-zero on failure
*/
virtual lib::error_code prepare_pong(std::string const & in, message_ptr out) const
= 0;
/// Prepare a close frame
/**
* Close preparation is entirely state free. The code and reason are both
* subject to validation. Reason must be valid UTF-8. Code must be a valid
* un-reserved WebSocket close code. Use close::status::no_status to
* indicate no code. If no code is supplied a reason may not be specified.
*
* @param code The close code to send
* @param reason The reason string to send
* @param out The message buffer to prepare the fame in
* @return Status code, zero on success, non-zero on failure
*/
virtual lib::error_code prepare_close(close::status::value code,
std::string const & reason, message_ptr out) const = 0;
protected:
bool const m_secure;
bool const m_server;
size_t m_max_message_size;
};
} // namespace processor
} // namespace websocketpp
#endif //WEBSOCKETPP_PROCESSOR_HPP

View File

@@ -1,60 +1,60 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_RANDOM_NONE_HPP
#define WEBSOCKETPP_RANDOM_NONE_HPP
namespace websocketpp {
/// Random number generation policies
namespace random {
/// Stub RNG policy that always returns 0
namespace none {
/// Thread safe stub "random" integer generator.
/**
* This template class provides a random integer stub. The interface mimics the
* WebSocket++ RNG generator classes but the generater function always returns
* zero. This can be used to stub out the RNG for unit and performance testing.
*
* Call operator() to generate the next number
*/
template <typename int_type>
class int_generator {
public:
int_generator() {}
/// advances the engine's state and returns the generated value
int_type operator()() {
return 0;
}
};
} // namespace none
} // namespace random
} // namespace websocketpp
#endif //WEBSOCKETPP_RANDOM_NONE_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_RANDOM_NONE_HPP
#define WEBSOCKETPP_RANDOM_NONE_HPP
namespace websocketpp {
/// Random number generation policies
namespace random {
/// Stub RNG policy that always returns 0
namespace none {
/// Thread safe stub "random" integer generator.
/**
* This template class provides a random integer stub. The interface mimics the
* WebSocket++ RNG generator classes but the generater function always returns
* zero. This can be used to stub out the RNG for unit and performance testing.
*
* Call operator() to generate the next number
*/
template <typename int_type>
class int_generator {
public:
int_generator() {}
/// advances the engine's state and returns the generated value
int_type operator()() {
return 0;
}
};
} // namespace none
} // namespace random
} // namespace websocketpp
#endif //WEBSOCKETPP_RANDOM_NONE_HPP

View File

@@ -1,80 +1,80 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_RANDOM_RANDOM_DEVICE_HPP
#define WEBSOCKETPP_RANDOM_RANDOM_DEVICE_HPP
#include <websocketpp/common/random.hpp>
namespace websocketpp {
namespace random {
/// RNG policy based on std::random_device or boost::random_device
namespace random_device {
/// Thread safe non-deterministic random integer generator.
/**
* This template class provides thread safe non-deterministic random integer
* generation. Numbers are produced in a uniformly distributed range from the
* smallest to largest value that int_type can store.
*
* Thread-safety is provided via locking based on the concurrency template
* parameter.
*
* Non-deterministic RNG is provided via websocketpp::lib which uses either
* C++11 or Boost 1.47+'s random_device class.
*
* Call operator() to generate the next number
*/
template <typename int_type, typename concurrency>
class int_generator {
public:
typedef typename concurrency::scoped_lock_type scoped_lock_type;
typedef typename concurrency::mutex_type mutex_type;
/// constructor
//mac TODO: figure out if signed types present a range problem
int_generator() {}
/// advances the engine's state and returns the generated value
int_type operator()() {
scoped_lock_type guard(m_lock);
return m_dis(m_rng);
}
private:
lib::random_device m_rng;
lib::uniform_int_distribution<int_type> m_dis;
mutex_type m_lock;
};
} // namespace random_device
} // namespace random
} // namespace websocketpp
#endif //WEBSOCKETPP_RANDOM_RANDOM_DEVICE_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_RANDOM_RANDOM_DEVICE_HPP
#define WEBSOCKETPP_RANDOM_RANDOM_DEVICE_HPP
#include <websocketpp/common/random.hpp>
namespace websocketpp {
namespace random {
/// RNG policy based on std::random_device or boost::random_device
namespace random_device {
/// Thread safe non-deterministic random integer generator.
/**
* This template class provides thread safe non-deterministic random integer
* generation. Numbers are produced in a uniformly distributed range from the
* smallest to largest value that int_type can store.
*
* Thread-safety is provided via locking based on the concurrency template
* parameter.
*
* Non-deterministic RNG is provided via websocketpp::lib which uses either
* C++11 or Boost 1.47+'s random_device class.
*
* Call operator() to generate the next number
*/
template <typename int_type, typename concurrency>
class int_generator {
public:
typedef typename concurrency::scoped_lock_type scoped_lock_type;
typedef typename concurrency::mutex_type mutex_type;
/// constructor
//mac TODO: figure out if signed types present a range problem
int_generator() {}
/// advances the engine's state and returns the generated value
int_type operator()() {
scoped_lock_type guard(m_lock);
return m_dis(m_rng);
}
private:
lib::random_device m_rng;
lib::uniform_int_distribution<int_type> m_dis;
mutex_type m_lock;
};
} // namespace random_device
} // namespace random
} // namespace websocketpp
#endif //WEBSOCKETPP_RANDOM_RANDOM_DEVICE_HPP

View File

@@ -1,173 +1,173 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CLIENT_ENDPOINT_HPP
#define WEBSOCKETPP_CLIENT_ENDPOINT_HPP
#include <websocketpp/endpoint.hpp>
#include <websocketpp/uri.hpp>
#include <websocketpp/logger/levels.hpp>
#include <websocketpp/common/system_error.hpp>
#include <string>
namespace websocketpp {
/// Client endpoint role based on the given config
/**
*
*/
template <typename config>
class client : public endpoint<connection<config>,config> {
public:
/// Type of this endpoint
typedef client<config> type;
/// Type of the endpoint concurrency component
typedef typename config::concurrency_type concurrency_type;
/// Type of the endpoint transport component
typedef typename config::transport_type transport_type;
/// Type of the connections this server will create
typedef connection<config> connection_type;
/// Type of a shared pointer to the connections this server will create
typedef typename connection_type::ptr connection_ptr;
/// Type of the connection transport component
typedef typename transport_type::transport_con_type transport_con_type;
/// Type of a shared pointer to the connection transport component
typedef typename transport_con_type::ptr transport_con_ptr;
/// Type of the endpoint component of this server
typedef endpoint<connection_type,config> endpoint_type;
friend class connection<config>;
explicit client() : endpoint_type(false)
{
endpoint_type::m_alog->write(log::alevel::devel, "client constructor");
}
/// Get a new connection
/**
* Creates and returns a pointer to a new connection to the given URI
* suitable for passing to connect(connection_ptr). This method allows
* applying connection specific settings before performing the opening
* handshake.
*
* @param [in] location URI to open the connection to as a uri_ptr
* @param [out] ec An status code indicating failure reasons, if any
*
* @return A connection_ptr to the new connection
*/
connection_ptr get_connection(uri_ptr location, lib::error_code & ec) {
if (location->get_secure() && !transport_type::is_secure()) {
ec = error::make_error_code(error::endpoint_not_secure);
return connection_ptr();
}
connection_ptr con = endpoint_type::create_connection();
if (!con) {
ec = error::make_error_code(error::con_creation_failed);
return con;
}
con->set_uri(location);
ec = lib::error_code();
return con;
}
/// Get a new connection (string version)
/**
* Creates and returns a pointer to a new connection to the given URI
* suitable for passing to connect(connection_ptr). This overload allows
* default construction of the uri_ptr from a standard string.
*
* @param [in] u URI to open the connection to as a string
* @param [out] ec An status code indicating failure reasons, if any
*
* @return A connection_ptr to the new connection
*/
connection_ptr get_connection(std::string const & u, lib::error_code & ec) {
uri_ptr location = lib::make_shared<uri>(u);
if (!location->get_valid()) {
ec = error::make_error_code(error::invalid_uri);
return connection_ptr();
}
return get_connection(location, ec);
}
/// Begin the connection process for the given connection
/**
* Initiates the opening connection handshake for connection con. Exact
* behavior depends on the underlying transport policy.
*
* @param con The connection to connect
*
* @return The pointer to the connection originally passed in.
*/
connection_ptr connect(connection_ptr con) {
// Ask transport to perform a connection
transport_type::async_connect(
lib::static_pointer_cast<transport_con_type>(con),
con->get_uri(),
lib::bind(
&type::handle_connect,
this,
con,
lib::placeholders::_1
)
);
return con;
}
private:
// handle_connect
void handle_connect(connection_ptr con, lib::error_code const & ec) {
if (ec) {
con->terminate(ec);
endpoint_type::m_elog->write(log::elevel::rerror,
"handle_connect error: "+ec.message());
} else {
endpoint_type::m_alog->write(log::alevel::connect,
"Successful connection");
con->start();
}
}
};
} // namespace websocketpp
#endif //WEBSOCKETPP_CLIENT_ENDPOINT_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_CLIENT_ENDPOINT_HPP
#define WEBSOCKETPP_CLIENT_ENDPOINT_HPP
#include <websocketpp/endpoint.hpp>
#include <websocketpp/uri.hpp>
#include <websocketpp/logger/levels.hpp>
#include <websocketpp/common/system_error.hpp>
#include <string>
namespace websocketpp {
/// Client endpoint role based on the given config
/**
*
*/
template <typename config>
class client : public endpoint<connection<config>,config> {
public:
/// Type of this endpoint
typedef client<config> type;
/// Type of the endpoint concurrency component
typedef typename config::concurrency_type concurrency_type;
/// Type of the endpoint transport component
typedef typename config::transport_type transport_type;
/// Type of the connections this server will create
typedef connection<config> connection_type;
/// Type of a shared pointer to the connections this server will create
typedef typename connection_type::ptr connection_ptr;
/// Type of the connection transport component
typedef typename transport_type::transport_con_type transport_con_type;
/// Type of a shared pointer to the connection transport component
typedef typename transport_con_type::ptr transport_con_ptr;
/// Type of the endpoint component of this server
typedef endpoint<connection_type,config> endpoint_type;
friend class connection<config>;
explicit client() : endpoint_type(false)
{
endpoint_type::m_alog->write(log::alevel::devel, "client constructor");
}
/// Get a new connection
/**
* Creates and returns a pointer to a new connection to the given URI
* suitable for passing to connect(connection_ptr). This method allows
* applying connection specific settings before performing the opening
* handshake.
*
* @param [in] location URI to open the connection to as a uri_ptr
* @param [out] ec An status code indicating failure reasons, if any
*
* @return A connection_ptr to the new connection
*/
connection_ptr get_connection(uri_ptr location, lib::error_code & ec) {
if (location->get_secure() && !transport_type::is_secure()) {
ec = error::make_error_code(error::endpoint_not_secure);
return connection_ptr();
}
connection_ptr con = endpoint_type::create_connection();
if (!con) {
ec = error::make_error_code(error::con_creation_failed);
return con;
}
con->set_uri(location);
ec = lib::error_code();
return con;
}
/// Get a new connection (string version)
/**
* Creates and returns a pointer to a new connection to the given URI
* suitable for passing to connect(connection_ptr). This overload allows
* default construction of the uri_ptr from a standard string.
*
* @param [in] u URI to open the connection to as a string
* @param [out] ec An status code indicating failure reasons, if any
*
* @return A connection_ptr to the new connection
*/
connection_ptr get_connection(std::string const & u, lib::error_code & ec) {
uri_ptr location = lib::make_shared<uri>(u);
if (!location->get_valid()) {
ec = error::make_error_code(error::invalid_uri);
return connection_ptr();
}
return get_connection(location, ec);
}
/// Begin the connection process for the given connection
/**
* Initiates the opening connection handshake for connection con. Exact
* behavior depends on the underlying transport policy.
*
* @param con The connection to connect
*
* @return The pointer to the connection originally passed in.
*/
connection_ptr connect(connection_ptr con) {
// Ask transport to perform a connection
transport_type::async_connect(
lib::static_pointer_cast<transport_con_type>(con),
con->get_uri(),
lib::bind(
&type::handle_connect,
this,
con,
lib::placeholders::_1
)
);
return con;
}
private:
// handle_connect
void handle_connect(connection_ptr con, lib::error_code const & ec) {
if (ec) {
con->terminate(ec);
endpoint_type::m_elog->write(log::elevel::rerror,
"handle_connect error: "+ec.message());
} else {
endpoint_type::m_alog->write(log::alevel::connect,
"Successful connection");
con->start();
}
}
};
} // namespace websocketpp
#endif //WEBSOCKETPP_CLIENT_ENDPOINT_HPP

View File

@@ -1,195 +1,195 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_SERVER_ENDPOINT_HPP
#define WEBSOCKETPP_SERVER_ENDPOINT_HPP
#include <websocketpp/endpoint.hpp>
#include <websocketpp/logger/levels.hpp>
#include <websocketpp/common/system_error.hpp>
namespace websocketpp {
/// Server endpoint role based on the given config
/**
*
*/
template <typename config>
class server : public endpoint<connection<config>,config> {
public:
/// Type of this endpoint
typedef server<config> type;
/// Type of the endpoint concurrency component
typedef typename config::concurrency_type concurrency_type;
/// Type of the endpoint transport component
typedef typename config::transport_type transport_type;
/// Type of the connections this server will create
typedef connection<config> connection_type;
/// Type of a shared pointer to the connections this server will create
typedef typename connection_type::ptr connection_ptr;
/// Type of the connection transport component
typedef typename transport_type::transport_con_type transport_con_type;
/// Type of a shared pointer to the connection transport component
typedef typename transport_con_type::ptr transport_con_ptr;
/// Type of the endpoint component of this server
typedef endpoint<connection_type,config> endpoint_type;
friend class connection<config>;
explicit server() : endpoint_type(true)
{
endpoint_type::m_alog->write(log::alevel::devel, "server constructor");
}
/// Destructor
~server<config>() {}
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
// no copy constructor because endpoints are not copyable
server<config>(server<config> &) = delete;
// no copy assignment operator because endpoints are not copyable
server<config> & operator=(server<config> const &) = delete;
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
/// Move constructor
server<config>(server<config> && o) : endpoint<connection<config>,config>(std::move(o)) {}
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
// no move assignment operator because of const member variables
server<config> & operator=(server<config> &&) = delete;
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
/// Create and initialize a new connection
/**
* The connection will be initialized and ready to begin. Call its start()
* method to begin the processing loop.
*
* Note: The connection must either be started or terminated using
* connection::terminate in order to avoid memory leaks.
*
* @return A pointer to the new connection.
*/
connection_ptr get_connection() {
return endpoint_type::create_connection();
}
/// Starts the server's async connection acceptance loop (exception free)
/**
* Initiates the server connection acceptance loop. Must be called after
* listen. This method will have no effect until the underlying io_service
* starts running. It may be called after the io_service is already running.
*
* Refer to documentation for the transport policy you are using for
* instructions on how to stop this acceptance loop.
*
* @param [out] ec A status code indicating an error, if any.
*/
void start_accept(lib::error_code & ec) {
if (!transport_type::is_listening()) {
ec = error::make_error_code(error::async_accept_not_listening);
return;
}
ec = lib::error_code();
connection_ptr con = get_connection();
if (!con) {
ec = error::make_error_code(error::con_creation_failed);
return;
}
transport_type::async_accept(
lib::static_pointer_cast<transport_con_type>(con),
lib::bind(&type::handle_accept,this,con,lib::placeholders::_1),
ec
);
if (ec && con) {
// If the connection was constructed but the accept failed,
// terminate the connection to prevent memory leaks
con->terminate(lib::error_code());
}
}
/// Starts the server's async connection acceptance loop
/**
* Initiates the server connection acceptance loop. Must be called after
* listen. This method will have no effect until the underlying io_service
* starts running. It may be called after the io_service is already running.
*
* Refer to documentation for the transport policy you are using for
* instructions on how to stop this acceptance loop.
*/
void start_accept() {
lib::error_code ec;
start_accept(ec);
if (ec) {
throw exception(ec);
}
}
/// Handler callback for start_accept
void handle_accept(connection_ptr con, lib::error_code const & ec) {
if (ec) {
con->terminate(ec);
if (ec == error::operation_canceled) {
endpoint_type::m_elog->write(log::elevel::info,
"handle_accept error: "+ec.message());
} else {
endpoint_type::m_elog->write(log::elevel::rerror,
"handle_accept error: "+ec.message());
}
} else {
con->start();
}
lib::error_code start_ec;
start_accept(start_ec);
if (start_ec == error::async_accept_not_listening) {
endpoint_type::m_elog->write(log::elevel::info,
"Stopping acceptance of new connections because the underlying transport is no longer listening.");
} else if (start_ec) {
endpoint_type::m_elog->write(log::elevel::rerror,
"Restarting async_accept loop failed: "+ec.message());
}
}
};
} // namespace websocketpp
#endif //WEBSOCKETPP_SERVER_ENDPOINT_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_SERVER_ENDPOINT_HPP
#define WEBSOCKETPP_SERVER_ENDPOINT_HPP
#include <websocketpp/endpoint.hpp>
#include <websocketpp/logger/levels.hpp>
#include <websocketpp/common/system_error.hpp>
namespace websocketpp {
/// Server endpoint role based on the given config
/**
*
*/
template <typename config>
class server : public endpoint<connection<config>,config> {
public:
/// Type of this endpoint
typedef server<config> type;
/// Type of the endpoint concurrency component
typedef typename config::concurrency_type concurrency_type;
/// Type of the endpoint transport component
typedef typename config::transport_type transport_type;
/// Type of the connections this server will create
typedef connection<config> connection_type;
/// Type of a shared pointer to the connections this server will create
typedef typename connection_type::ptr connection_ptr;
/// Type of the connection transport component
typedef typename transport_type::transport_con_type transport_con_type;
/// Type of a shared pointer to the connection transport component
typedef typename transport_con_type::ptr transport_con_ptr;
/// Type of the endpoint component of this server
typedef endpoint<connection_type,config> endpoint_type;
friend class connection<config>;
explicit server() : endpoint_type(true)
{
endpoint_type::m_alog->write(log::alevel::devel, "server constructor");
}
/// Destructor
~server<config>() {}
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
// no copy constructor because endpoints are not copyable
server<config>(server<config> &) = delete;
// no copy assignment operator because endpoints are not copyable
server<config> & operator=(server<config> const &) = delete;
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
/// Move constructor
server<config>(server<config> && o) : endpoint<connection<config>,config>(std::move(o)) {}
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
// no move assignment operator because of const member variables
server<config> & operator=(server<config> &&) = delete;
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
/// Create and initialize a new connection
/**
* The connection will be initialized and ready to begin. Call its start()
* method to begin the processing loop.
*
* Note: The connection must either be started or terminated using
* connection::terminate in order to avoid memory leaks.
*
* @return A pointer to the new connection.
*/
connection_ptr get_connection() {
return endpoint_type::create_connection();
}
/// Starts the server's async connection acceptance loop (exception free)
/**
* Initiates the server connection acceptance loop. Must be called after
* listen. This method will have no effect until the underlying io_service
* starts running. It may be called after the io_service is already running.
*
* Refer to documentation for the transport policy you are using for
* instructions on how to stop this acceptance loop.
*
* @param [out] ec A status code indicating an error, if any.
*/
void start_accept(lib::error_code & ec) {
if (!transport_type::is_listening()) {
ec = error::make_error_code(error::async_accept_not_listening);
return;
}
ec = lib::error_code();
connection_ptr con = get_connection();
if (!con) {
ec = error::make_error_code(error::con_creation_failed);
return;
}
transport_type::async_accept(
lib::static_pointer_cast<transport_con_type>(con),
lib::bind(&type::handle_accept,this,con,lib::placeholders::_1),
ec
);
if (ec && con) {
// If the connection was constructed but the accept failed,
// terminate the connection to prevent memory leaks
con->terminate(lib::error_code());
}
}
/// Starts the server's async connection acceptance loop
/**
* Initiates the server connection acceptance loop. Must be called after
* listen. This method will have no effect until the underlying io_service
* starts running. It may be called after the io_service is already running.
*
* Refer to documentation for the transport policy you are using for
* instructions on how to stop this acceptance loop.
*/
void start_accept() {
lib::error_code ec;
start_accept(ec);
if (ec) {
throw exception(ec);
}
}
/// Handler callback for start_accept
void handle_accept(connection_ptr con, lib::error_code const & ec) {
if (ec) {
con->terminate(ec);
if (ec == error::operation_canceled) {
endpoint_type::m_elog->write(log::elevel::info,
"handle_accept error: "+ec.message());
} else {
endpoint_type::m_elog->write(log::elevel::rerror,
"handle_accept error: "+ec.message());
}
} else {
con->start();
}
lib::error_code start_ec;
start_accept(start_ec);
if (start_ec == error::async_accept_not_listening) {
endpoint_type::m_elog->write(log::elevel::info,
"Stopping acceptance of new connections because the underlying transport is no longer listening.");
} else if (start_ec) {
endpoint_type::m_elog->write(log::elevel::rerror,
"Restarting async_accept loop failed: "+ec.message());
}
}
};
} // namespace websocketpp
#endif //WEBSOCKETPP_SERVER_ENDPOINT_HPP

View File

@@ -1,33 +1,33 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_SERVER_HPP
#define WEBSOCKETPP_SERVER_HPP
#include <websocketpp/roles/server_endpoint.hpp>
#endif //WEBSOCKETPP_SERVER_HPP
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_SERVER_HPP
#define WEBSOCKETPP_SERVER_HPP
#include <websocketpp/roles/server_endpoint.hpp>
#endif //WEBSOCKETPP_SERVER_HPP

View File

@@ -1,189 +1,189 @@
/*
*****
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
/*
*****
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

View File

@@ -1,232 +1,232 @@
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_TRANSPORT_ASIO_BASE_HPP
#define WEBSOCKETPP_TRANSPORT_ASIO_BASE_HPP
#include <websocketpp/common/asio.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/functional.hpp>
#include <websocketpp/common/system_error.hpp>
#include <websocketpp/common/type_traits.hpp>
#include <string>
namespace websocketpp {
namespace transport {
/// Transport policy that uses asio
/**
* This policy uses a single asio io_service to provide transport
* services to a WebSocket++ endpoint.
*/
namespace asio {
// Class to manage the memory to be used for handler-based custom allocation.
// It contains a single block of memory which may be returned for allocation
// requests. If the memory is in use when an allocation request is made, the
// allocator delegates allocation to the global heap.
class handler_allocator {
public:
static const size_t size = 1024;
handler_allocator() : m_in_use(false) {}
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
handler_allocator(handler_allocator const & cpy) = delete;
handler_allocator & operator =(handler_allocator const &) = delete;
#endif
void * allocate(std::size_t memsize) {
if (!m_in_use && memsize < size) {
m_in_use = true;
return static_cast<void*>(&m_storage);
} else {
return ::operator new(memsize);
}
}
void deallocate(void * pointer) {
if (pointer == &m_storage) {
m_in_use = false;
} else {
::operator delete(pointer);
}
}
private:
// Storage space used for handler-based custom memory allocation.
lib::aligned_storage<size>::type m_storage;
// Whether the handler-based custom allocation storage has been used.
bool m_in_use;
};
// Wrapper class template for handler objects to allow handler memory
// allocation to be customised. Calls to operator() are forwarded to the
// encapsulated handler.
template <typename Handler>
class custom_alloc_handler {
public:
custom_alloc_handler(handler_allocator& a, Handler h)
: allocator_(a),
handler_(h)
{}
template <typename Arg1>
void operator()(Arg1 arg1) {
handler_(arg1);
}
template <typename Arg1, typename Arg2>
void operator()(Arg1 arg1, Arg2 arg2) {
handler_(arg1, arg2);
}
friend void* asio_handler_allocate(std::size_t size,
custom_alloc_handler<Handler> * this_handler)
{
return this_handler->allocator_.allocate(size);
}
friend void asio_handler_deallocate(void* pointer, std::size_t /*size*/,
custom_alloc_handler<Handler> * this_handler)
{
this_handler->allocator_.deallocate(pointer);
}
private:
handler_allocator & allocator_;
Handler handler_;
};
// Helper function to wrap a handler object to add custom allocation.
template <typename Handler>
inline custom_alloc_handler<Handler> make_custom_alloc_handler(
handler_allocator & a, Handler h)
{
return custom_alloc_handler<Handler>(a, h);
}
// Forward declaration of class endpoint so that it can be friended/referenced
// before being included.
template <typename config>
class endpoint;
typedef lib::function<void (lib::asio::error_code const & ec,
size_t bytes_transferred)> async_read_handler;
typedef lib::function<void (lib::asio::error_code const & ec,
size_t bytes_transferred)> async_write_handler;
typedef lib::function<void (lib::error_code const & ec)> pre_init_handler;
// handle_timer: dynamic parameters, multiple copies
// handle_proxy_write
// handle_proxy_read
// handle_async_write
// handle_pre_init
/// Asio transport errors
namespace error {
enum value {
/// Catch-all error for transport policy errors that don't fit in other
/// categories
general = 1,
/// async_read_at_least call requested more bytes than buffer can store
invalid_num_bytes,
/// there was an error in the underlying transport library
pass_through,
/// The connection to the requested proxy server failed
proxy_failed,
/// Invalid Proxy URI
proxy_invalid,
/// Invalid host or service
invalid_host_service
};
/// Asio transport error category
class category : public lib::error_category {
public:
char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
return "websocketpp.transport.asio";
}
std::string message(int value) const {
switch(value) {
case error::general:
return "Generic asio transport policy error";
case error::invalid_num_bytes:
return "async_read_at_least call requested more bytes than buffer can store";
case error::pass_through:
return "Underlying Transport Error";
case error::proxy_failed:
return "Proxy connection failed";
case error::proxy_invalid:
return "Invalid proxy URI";
case error::invalid_host_service:
return "Invalid host or service";
default:
return "Unknown";
}
}
};
/// Get a reference to a static copy of the asio transport error category
inline lib::error_category const & get_category() {
static category instance;
return instance;
}
/// Create an error code with the given value and the asio transport category
inline lib::error_code make_error_code(error::value e) {
return lib::error_code(static_cast<int>(e), get_category());
}
} // namespace error
} // namespace asio
} // namespace transport
} // namespace websocketpp
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
template<> struct is_error_code_enum<websocketpp::transport::asio::error::value>
{
static bool const value = true;
};
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
#endif // WEBSOCKETPP_TRANSPORT_ASIO_HPP
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_TRANSPORT_ASIO_BASE_HPP
#define WEBSOCKETPP_TRANSPORT_ASIO_BASE_HPP
#include <websocketpp/common/asio.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/functional.hpp>
#include <websocketpp/common/system_error.hpp>
#include <websocketpp/common/type_traits.hpp>
#include <string>
namespace websocketpp {
namespace transport {
/// Transport policy that uses asio
/**
* This policy uses a single asio io_service to provide transport
* services to a WebSocket++ endpoint.
*/
namespace asio {
// Class to manage the memory to be used for handler-based custom allocation.
// It contains a single block of memory which may be returned for allocation
// requests. If the memory is in use when an allocation request is made, the
// allocator delegates allocation to the global heap.
class handler_allocator {
public:
static const size_t size = 1024;
handler_allocator() : m_in_use(false) {}
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
handler_allocator(handler_allocator const & cpy) = delete;
handler_allocator & operator =(handler_allocator const &) = delete;
#endif
void * allocate(std::size_t memsize) {
if (!m_in_use && memsize < size) {
m_in_use = true;
return static_cast<void*>(&m_storage);
} else {
return ::operator new(memsize);
}
}
void deallocate(void * pointer) {
if (pointer == &m_storage) {
m_in_use = false;
} else {
::operator delete(pointer);
}
}
private:
// Storage space used for handler-based custom memory allocation.
lib::aligned_storage<size>::type m_storage;
// Whether the handler-based custom allocation storage has been used.
bool m_in_use;
};
// Wrapper class template for handler objects to allow handler memory
// allocation to be customised. Calls to operator() are forwarded to the
// encapsulated handler.
template <typename Handler>
class custom_alloc_handler {
public:
custom_alloc_handler(handler_allocator& a, Handler h)
: allocator_(a),
handler_(h)
{}
template <typename Arg1>
void operator()(Arg1 arg1) {
handler_(arg1);
}
template <typename Arg1, typename Arg2>
void operator()(Arg1 arg1, Arg2 arg2) {
handler_(arg1, arg2);
}
friend void* asio_handler_allocate(std::size_t size,
custom_alloc_handler<Handler> * this_handler)
{
return this_handler->allocator_.allocate(size);
}
friend void asio_handler_deallocate(void* pointer, std::size_t /*size*/,
custom_alloc_handler<Handler> * this_handler)
{
this_handler->allocator_.deallocate(pointer);
}
private:
handler_allocator & allocator_;
Handler handler_;
};
// Helper function to wrap a handler object to add custom allocation.
template <typename Handler>
inline custom_alloc_handler<Handler> make_custom_alloc_handler(
handler_allocator & a, Handler h)
{
return custom_alloc_handler<Handler>(a, h);
}
// Forward declaration of class endpoint so that it can be friended/referenced
// before being included.
template <typename config>
class endpoint;
typedef lib::function<void (lib::asio::error_code const & ec,
size_t bytes_transferred)> async_read_handler;
typedef lib::function<void (lib::asio::error_code const & ec,
size_t bytes_transferred)> async_write_handler;
typedef lib::function<void (lib::error_code const & ec)> pre_init_handler;
// handle_timer: dynamic parameters, multiple copies
// handle_proxy_write
// handle_proxy_read
// handle_async_write
// handle_pre_init
/// Asio transport errors
namespace error {
enum value {
/// Catch-all error for transport policy errors that don't fit in other
/// categories
general = 1,
/// async_read_at_least call requested more bytes than buffer can store
invalid_num_bytes,
/// there was an error in the underlying transport library
pass_through,
/// The connection to the requested proxy server failed
proxy_failed,
/// Invalid Proxy URI
proxy_invalid,
/// Invalid host or service
invalid_host_service
};
/// Asio transport error category
class category : public lib::error_category {
public:
char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
return "websocketpp.transport.asio";
}
std::string message(int value) const {
switch(value) {
case error::general:
return "Generic asio transport policy error";
case error::invalid_num_bytes:
return "async_read_at_least call requested more bytes than buffer can store";
case error::pass_through:
return "Underlying Transport Error";
case error::proxy_failed:
return "Proxy connection failed";
case error::proxy_invalid:
return "Invalid proxy URI";
case error::invalid_host_service:
return "Invalid host or service";
default:
return "Unknown";
}
}
};
/// Get a reference to a static copy of the asio transport error category
inline lib::error_category const & get_category() {
static category instance;
return instance;
}
/// Create an error code with the given value and the asio transport category
inline lib::error_code make_error_code(error::value e) {
return lib::error_code(static_cast<int>(e), get_category());
}
} // namespace error
} // namespace asio
} // namespace transport
} // namespace websocketpp
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
template<> struct is_error_code_enum<websocketpp::transport::asio::error::value>
{
static bool const value = true;
};
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
#endif // WEBSOCKETPP_TRANSPORT_ASIO_HPP

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,159 +1,159 @@
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP
#define WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP
#include <websocketpp/common/asio.hpp>
#include <websocketpp/common/memory.hpp>
#include <websocketpp/common/functional.hpp>
#include <websocketpp/common/system_error.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/connection_hdl.hpp>
#include <string>
// Interface that sockets/security policies must implement
/*
* Endpoint Interface
*
* bool is_secure() const;
* @return Whether or not the endpoint creates secure connections
*
* lib::error_code init(socket_con_ptr scon);
* Called by the transport after a new connection is created to initialize
* the socket component of the connection.
* @param scon Pointer to the socket component of the connection
* @return Error code (empty on success)
*/
// Connection
// TODO
// set_hostname(std::string hostname)
// pre_init(init_handler);
// post_init(init_handler);
namespace websocketpp {
namespace transport {
namespace asio {
namespace socket {
typedef lib::function<void(lib::asio::error_code const &)> shutdown_handler;
/**
* The transport::asio::socket::* classes are a set of security/socket related
* policies and support code for the ASIO transport types.
*/
/// Errors related to asio transport sockets
namespace error {
enum value {
/// Catch-all error for security policy errors that don't fit in other
/// categories
security = 1,
/// Catch-all error for socket component errors that don't fit in other
/// categories
socket,
/// A function was called in a state that it was illegal to do so.
invalid_state,
/// The application was prompted to provide a TLS context and it was
/// empty or otherwise invalid
invalid_tls_context,
/// TLS Handshake Timeout
tls_handshake_timeout,
/// pass_through from underlying library
pass_through,
/// Required tls_init handler not present
missing_tls_init_handler,
/// TLS Handshake Failed
tls_handshake_failed,
/// Failed to set TLS SNI hostname
tls_failed_sni_hostname
};
} // namespace error
/// Error category related to asio transport socket policies
class socket_category : public lib::error_category {
public:
char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
return "websocketpp.transport.asio.socket";
}
std::string message(int value) const {
switch(value) {
case error::security:
return "Security policy error";
case error::socket:
return "Socket component error";
case error::invalid_state:
return "Invalid state";
case error::invalid_tls_context:
return "Invalid or empty TLS context supplied";
case error::tls_handshake_timeout:
return "TLS handshake timed out";
case error::pass_through:
return "Pass through from socket policy";
case error::missing_tls_init_handler:
return "Required tls_init handler not present.";
case error::tls_handshake_failed:
return "TLS handshake failed";
case error::tls_failed_sni_hostname:
return "Failed to set TLS SNI hostname";
default:
return "Unknown";
}
}
};
inline lib::error_category const & get_socket_category() {
static socket_category instance;
return instance;
}
inline lib::error_code make_error_code(error::value e) {
return lib::error_code(static_cast<int>(e), get_socket_category());
}
/// Type of asio transport socket policy initialization handlers
typedef lib::function<void(const lib::error_code&)> init_handler;
} // namespace socket
} // namespace asio
} // namespace transport
} // namespace websocketpp
#endif // WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP
#define WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP
#include <websocketpp/common/asio.hpp>
#include <websocketpp/common/memory.hpp>
#include <websocketpp/common/functional.hpp>
#include <websocketpp/common/system_error.hpp>
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/connection_hdl.hpp>
#include <string>
// Interface that sockets/security policies must implement
/*
* Endpoint Interface
*
* bool is_secure() const;
* @return Whether or not the endpoint creates secure connections
*
* lib::error_code init(socket_con_ptr scon);
* Called by the transport after a new connection is created to initialize
* the socket component of the connection.
* @param scon Pointer to the socket component of the connection
* @return Error code (empty on success)
*/
// Connection
// TODO
// set_hostname(std::string hostname)
// pre_init(init_handler);
// post_init(init_handler);
namespace websocketpp {
namespace transport {
namespace asio {
namespace socket {
typedef lib::function<void(lib::asio::error_code const &)> shutdown_handler;
/**
* The transport::asio::socket::* classes are a set of security/socket related
* policies and support code for the ASIO transport types.
*/
/// Errors related to asio transport sockets
namespace error {
enum value {
/// Catch-all error for security policy errors that don't fit in other
/// categories
security = 1,
/// Catch-all error for socket component errors that don't fit in other
/// categories
socket,
/// A function was called in a state that it was illegal to do so.
invalid_state,
/// The application was prompted to provide a TLS context and it was
/// empty or otherwise invalid
invalid_tls_context,
/// TLS Handshake Timeout
tls_handshake_timeout,
/// pass_through from underlying library
pass_through,
/// Required tls_init handler not present
missing_tls_init_handler,
/// TLS Handshake Failed
tls_handshake_failed,
/// Failed to set TLS SNI hostname
tls_failed_sni_hostname
};
} // namespace error
/// Error category related to asio transport socket policies
class socket_category : public lib::error_category {
public:
char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
return "websocketpp.transport.asio.socket";
}
std::string message(int value) const {
switch(value) {
case error::security:
return "Security policy error";
case error::socket:
return "Socket component error";
case error::invalid_state:
return "Invalid state";
case error::invalid_tls_context:
return "Invalid or empty TLS context supplied";
case error::tls_handshake_timeout:
return "TLS handshake timed out";
case error::pass_through:
return "Pass through from socket policy";
case error::missing_tls_init_handler:
return "Required tls_init handler not present.";
case error::tls_handshake_failed:
return "TLS handshake failed";
case error::tls_failed_sni_hostname:
return "Failed to set TLS SNI hostname";
default:
return "Unknown";
}
}
};
inline lib::error_category const & get_socket_category() {
static socket_category instance;
return instance;
}
inline lib::error_code make_error_code(error::value e) {
return lib::error_code(static_cast<int>(e), get_socket_category());
}
/// Type of asio transport socket policy initialization handlers
typedef lib::function<void(const lib::error_code&)> init_handler;
} // namespace socket
} // namespace asio
} // namespace transport
} // namespace websocketpp
#endif // WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP

Some files were not shown because too many files have changed in this diff Show More