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] [signal server]
ip = localhost ip = localhost
port = 9095 port = 9090
[stun server] [stun server]
ip = 120.77.216.215 ip = 120.77.216.215

View File

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

View File

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

View File

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

View File

@@ -8,7 +8,8 @@
class IceTransmission { class IceTransmission {
public: 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); std::function<void(const char *, size_t)> on_receive_ice_msg);
~IceTransmission(); ~IceTransmission();
@@ -18,7 +19,10 @@ class IceTransmission {
int DestroyIceTransmission(); int DestroyIceTransmission();
int CreateTransmission(const std::string &transmission_id); 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); 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::function<void(const char *, size_t)> on_receive_ice_msg_cb_ = nullptr;
std::string local_sdp_; std::string local_sdp_;
std::string remote_sdp_; std::string remote_sdp_;
std::string remote_ice_username_;
std::string local_candidates_; std::string local_candidates_;
std::string remote_candidates_; std::string remote_candidates_;
unsigned int connection_id_ = 0; unsigned int connection_id_ = 0;
std::string transmission_id_ = ""; std::string transmission_id_ = "";
std::string user_id_ = "";
bool offer_peer_ = true; bool offer_peer_ = true;
std::string remote_ice_username_ = "";
}; };
#endif #endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,17 +1,17 @@
#include <iostream> #include <iostream>
#include "signal_server.h" #include "signal_server.h"
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
SignalServer s; SignalServer s;
std::string port = ""; std::string port = "";
if (argc > 1) { if (argc > 1) {
port = argv[1]; port = argv[1];
} else { } else {
port = "9090"; port = "9090";
} }
std::cout << "Port: " << port << std::endl; std::cout << "Port: " << port << std::endl;
s.run(std::stoi(port)); s.run(std::stoi(port));
return 0; 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) { void SignalServer::run(uint16_t port) {
server_.set_reuse_addr(true);
server_.listen(port); server_.listen(port);
// Queues a connection accept operation // Queues a connection accept operation
@@ -95,6 +96,7 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl,
switch (HASH_STRING_PIECE(type.c_str())) { switch (HASH_STRING_PIECE(type.c_str())) {
case "create_transmission"_H: { case "create_transmission"_H: {
std::string transmission_id = j["transmission_id"].get<std::string>(); 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 [{}]", LOG_INFO("Receive create transmission request with id [{}]",
transmission_id); transmission_id);
if (transmission_list_.find(transmission_id) == if (transmission_list_.find(transmission_id) ==
@@ -111,7 +113,16 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl,
transmission_id); transmission_id);
} }
transmission_list_.insert(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); LOG_INFO("Create transmission id [{}]", transmission_id);
json message = {{"type", "transmission_id"}, json message = {{"type", "transmission_id"},
@@ -129,37 +140,6 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl,
break; 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: { case "query_members"_H: {
std::string transmission_id = j["transmission_id"].get<std::string>(); std::string transmission_id = j["transmission_id"].get<std::string>();
std::vector<std::string> member_list = std::vector<std::string> member_list =
@@ -169,23 +149,44 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl,
{"transmission_id", transmission_id}, {"transmission_id", transmission_id},
{"transmission_members", member_list}, {"transmission_members", member_list},
{"status", "success"}}; {"status", "success"}};
LOG_INFO("Send member_list: [{}]", message.dump());
send_msg(hdl, message); send_msg(hdl, message);
break; 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: { case "answer"_H: {
std::string transmission_id = j["transmission_id"].get<std::string>(); std::string transmission_id = j["transmission_id"].get<std::string>();
std::string sdp = j["sdp"].get<std::string>(); std::string sdp = j["sdp"].get<std::string>();
std::string guest_ice_username = j["guest"].get<std::string>(); std::string guest_ice_username = j["guest"].get<std::string>();
std::string host_ice_username = GetIceUsername(sdp); std::string host_ice_username = GetIceUsername(sdp);
if (transmission_manager_.GetHostUsername(hdl).empty()) { if (transmission_manager_.GetUsername(hdl) == "host") {
transmission_manager_.BindHostUsernameToWsHandle(host_ice_username, LOG_INFO("Update transmission [{}] [host] to [{}]", transmission_id,
hdl); 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 = 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 [{}]", sdp);
LOG_INFO("[{}] send answer sdp to [{}]", host_ice_username, LOG_INFO("[{}] send answer sdp to [{}]", host_ice_username,

View File

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

View File

@@ -6,101 +6,114 @@ TransmissionManager::TransmissionManager() {}
TransmissionManager::~TransmissionManager() {} TransmissionManager::~TransmissionManager() {}
bool TransmissionManager::BindHostToTransmission( // bool TransmissionManager::BindHostToTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) { // websocketpp::connection_hdl hdl, const std::string& transmission_id) {
if (transmission_host_list_.find(transmission_id) != // if (transmission_host_list_.find(transmission_id) !=
transmission_host_list_.end()) { // transmission_host_list_.end()) {
LOG_WARN("Transmission already has a host [{}]", // LOG_WARN("Transmission already has a host [{}]",
transmission_host_list_[transmission_id].lock().get()); // transmission_host_list_[transmission_id].lock().get());
return false; // return false;
} else { // } else {
transmission_host_list_[transmission_id] = hdl; // transmission_host_list_[transmission_id] = hdl;
} // }
return true; // return true;
} // }
bool TransmissionManager::BindGuestToTransmission( // bool TransmissionManager::BindGuestToTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) { // websocketpp::connection_hdl hdl, const std::string& transmission_id) {
if (transmission_guest_list_.find(transmission_id) != // if (transmission_guest_list_.find(transmission_id) !=
transmission_guest_list_.end()) { // transmission_guest_list_.end()) {
transmission_guest_list_[transmission_id].push_back(hdl); // transmission_guest_list_[transmission_id].push_back(hdl);
} else { // } else {
std::vector<websocketpp::connection_hdl> guest_hdl_list; // std::vector<websocketpp::connection_hdl> guest_hdl_list;
guest_hdl_list.push_back(hdl); // guest_hdl_list.push_back(hdl);
transmission_guest_list_[transmission_id] = guest_hdl_list; // transmission_guest_list_[transmission_id] = guest_hdl_list;
} // }
return true; // return true;
} // }
bool TransmissionManager::ReleaseHostFromTransmission( // bool TransmissionManager::ReleaseHostFromTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) { // websocketpp::connection_hdl hdl, const std::string& transmission_id) {
return true; // return true;
} // }
bool TransmissionManager::ReleaseGuestFromTransmission( // bool TransmissionManager::ReleaseGuestFromTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) { // websocketpp::connection_hdl hdl, const std::string& transmission_id) {
return true; // return true;
} // }
bool TransmissionManager::BindHostUsernameToWsHandle( // bool TransmissionManager::BindHostUsernameToWsHandle(
const std::string& host_username, websocketpp::connection_hdl hdl) { // websocketpp::connection_hdl hdl) {
if (transmission_host_username_list_.find(host_username) != // if (transmission_host_username_list_.find("host") !=
transmission_host_username_list_.end()) { // transmission_host_username_list_.end()) {
LOG_ERROR("Guest already bind to username [{}]", host_username.c_str()); // LOG_ERROR("Host already exist");
return false; // return false;
} else { // } else {
transmission_host_username_list_[host_username] = hdl; // transmission_host_username_list_["host"] = hdl;
} // }
return true; // return true;
} // }
bool TransmissionManager::BindGuestUsernameToWsHandle( // bool TransmissionManager::UpdateHostUsernameToWsHandle(
const std::string& guest_username, websocketpp::connection_hdl hdl) { // const std::string& host_username, websocketpp::connection_hdl hdl) {
if (transmission_guest_username_list_.find(guest_username) != // if (transmission_host_username_list_.find("host") ==
transmission_guest_username_list_.end()) { // transmission_host_username_list_.end()) {
LOG_ERROR("Guest already bind to username [{}]", guest_username.c_str()); // LOG_ERROR("Host not exist");
return false; // return false;
} else { // }
transmission_guest_username_list_[guest_username] = hdl; // transmission_host_username_list_.erase("host");
} // transmission_host_username_list_[host_username] = hdl;
return true;
}
websocketpp::connection_hdl TransmissionManager::GetHostOfTransmission( // return true;
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::GetHostUsername( // bool TransmissionManager::BindGuestUsernameToWsHandle(
websocketpp::connection_hdl hdl) { // const std::string& guest_username, websocketpp::connection_hdl hdl) {
for (auto host : transmission_host_username_list_) { // if (transmission_guest_username_list_.find(guest_username) !=
if (host.second.lock().get() == hdl.lock().get()) return host.first; // 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( // std::string TransmissionManager::GetHostUsername(
websocketpp::connection_hdl hdl) { // websocketpp::connection_hdl hdl) {
for (auto guest : transmission_guest_username_list_) { // for (auto host : transmission_host_username_list_) {
if (guest.second.lock().get() == hdl.lock().get()) return guest.first; // 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> std::vector<websocketpp::connection_hdl>
TransmissionManager::GetAllGuestsOfTransmission( TransmissionManager::GetAllGuestsOfTransmission(
const std::string& transmission_id) { const std::string& transmission_id) {
if (transmission_guest_list_.find(transmission_id) != if (transmission_user_ws_hdl_list_.find(transmission_id) !=
transmission_guest_list_.end()) { transmission_user_ws_hdl_list_.end()) {
return transmission_guest_list_[transmission_id]; return transmission_user_ws_hdl_list_[transmission_id];
} else { } else {
return std::vector<websocketpp::connection_hdl>(); return std::vector<websocketpp::connection_hdl>();
} }
@@ -121,12 +134,127 @@ std::vector<std::string> TransmissionManager::GetAllMembersOfTransmission(
const std::string& transmission_id) { const std::string& transmission_id) {
std::vector<std::string> member_list; std::vector<std::string> member_list;
member_list.push_back(
GetHostUsername(GetHostOfTransmission(transmission_id)));
for (auto guest_hdl : GetAllGuestsOfTransmission(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; 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(); ~TransmissionManager();
public: public:
bool BindHostToTransmission(websocketpp::connection_hdl hdl, // bool BindHostToTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id); // const std::string& transmission_id);
bool BindGuestToTransmission(websocketpp::connection_hdl hdl, // bool BindGuestToTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id); // const std::string& transmission_id);
bool ReleaseHostFromTransmission(websocketpp::connection_hdl hdl, // bool ReleaseHostFromTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id); // const std::string& transmission_id);
bool ReleaseGuestFromTransmission(websocketpp::connection_hdl hdl, // bool ReleaseGuestFromTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id); // const std::string& transmission_id);
bool BindHostUsernameToWsHandle(const std::string& host_username, // bool BindHostUsernameToWsHandle(websocketpp::connection_hdl hdl);
websocketpp::connection_hdl hdl); // bool UpdateHostUsernameToWsHandle(const std::string& host_username,
bool BindGuestUsernameToWsHandle(const std::string& guest_username, // websocketpp::connection_hdl hdl);
websocketpp::connection_hdl hdl); // bool BindGuestUsernameToWsHandle(const std::string& guest_username,
// websocketpp::connection_hdl hdl);
std::string GetHostUsername(websocketpp::connection_hdl hdl); // std::string GetHostUsername(websocketpp::connection_hdl hdl);
std::string GetGuestUsername(websocketpp::connection_hdl hdl); // std::string GetGuestUsername(websocketpp::connection_hdl hdl);
websocketpp::connection_hdl GetHostOfTransmission( websocketpp::connection_hdl GetHostOfTransmission(
const std::string& transmission_id); const std::string& transmission_id);
@@ -38,6 +39,25 @@ class TransmissionManager {
std::vector<std::string> GetAllMembersOfTransmission( std::vector<std::string> GetAllMembersOfTransmission(
const std::string& transmission_id); 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: private:
std::map<std::string, websocketpp::connection_hdl> transmission_host_list_; std::map<std::string, websocketpp::connection_hdl> transmission_host_list_;
std::map<std::string, std::vector<websocketpp::connection_hdl>> std::map<std::string, std::vector<websocketpp::connection_hdl>>
@@ -47,6 +67,15 @@ class TransmissionManager {
transmission_host_username_list_; transmission_host_username_list_;
std::map<std::string, websocketpp::connection_hdl> std::map<std::string, websocketpp::connection_hdl>
transmission_guest_username_list_; 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 #endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,105 +1,105 @@
/* /*
* Copyright (c) 2014, Peter Thorson. All rights reserved. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef WEBSOCKETPP_COMMON_FUNCTIONAL_HPP #ifndef WEBSOCKETPP_COMMON_FUNCTIONAL_HPP
#define WEBSOCKETPP_COMMON_FUNCTIONAL_HPP #define WEBSOCKETPP_COMMON_FUNCTIONAL_HPP
#include <websocketpp/common/cpp11.hpp> #include <websocketpp/common/cpp11.hpp>
// If we've determined that we're in full C++11 mode and the user hasn't // 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 // explicitly disabled the use of C++11 functional header, then prefer it to
// boost. // boost.
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_ #if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_
#ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_ #ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_ #define _WEBSOCKETPP_CPP11_FUNCTIONAL_
#endif #endif
#endif #endif
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled // 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. // the use of C++11 functional header then prefer it to boost.
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_ #if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_
#ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_ #ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_ #define _WEBSOCKETPP_CPP11_FUNCTIONAL_
#endif #endif
#endif #endif
#ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_ #ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_
#include <functional> #include <functional>
#else #else
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/function.hpp> #include <boost/function.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
#endif #endif
namespace websocketpp { namespace websocketpp {
namespace lib { namespace lib {
#ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_ #ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_
using std::function; using std::function;
using std::bind; using std::bind;
using std::ref; using std::ref;
namespace placeholders = std::placeholders; namespace placeholders = std::placeholders;
// There are some cases where a C++11 compiler balks at using std::ref // 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 // 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 // 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 // of boost::ref in the case of a boost compile or no reference wrapper at
// all in the case of a C++11 compile // all in the case of a C++11 compile
#define _WEBSOCKETPP_REF(x) x #define _WEBSOCKETPP_REF(x) x
template <typename T> template <typename T>
void clear_function(T & x) { void clear_function(T & x) {
x = nullptr; x = nullptr;
} }
#else #else
using boost::function; using boost::function;
using boost::bind; using boost::bind;
using boost::ref; using boost::ref;
namespace placeholders { namespace placeholders {
/// \todo this feels hacky, is there a better way? /// \todo this feels hacky, is there a better way?
using ::_1; using ::_1;
using ::_2; using ::_2;
using ::_3; using ::_3;
} }
// See above definition for more details on what this is and why it exists // See above definition for more details on what this is and why it exists
#define _WEBSOCKETPP_REF(x) boost::ref(x) #define _WEBSOCKETPP_REF(x) boost::ref(x)
template <typename T> template <typename T>
void clear_function(T & x) { void clear_function(T & x) {
x.clear(); x.clear();
} }
#endif #endif
} // namespace lib } // namespace lib
} // namespace websocketpp } // namespace websocketpp
#endif // WEBSOCKETPP_COMMON_FUNCTIONAL_HPP #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 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 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 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 Peter Thorson (webmaster@zaphoyd.com) in 2012 for the WebSocket++ project. The
changes are released under the same license as the original (listed below) changes are released under the same license as the original (listed below)
*/ */
/* /*
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
arising from the use of this software. arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions: freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not 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 claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be in a product, an acknowledgment in the product documentation would be
appreciated but is not required. appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be 2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software. misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch L. Peter Deutsch
ghost@aladdin.com ghost@aladdin.com
*/ */
/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ /* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
/* /*
Independent implementation of MD5 (RFC 1321). Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at text is available at
http://www.ietf.org/rfc/rfc1321.txt http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include (section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being any code or documentation that is identified in the RFC as being
copyrighted. copyrighted.
The original and principal author of md5.h is L. Peter Deutsch The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history <ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order): that follows (in reverse chronological order):
2002-04-13 lpd Removed support for non-ANSI compilers; removed 2002-04-13 lpd Removed support for non-ANSI compilers; removed
references to Ghostscript; clarified derivation from RFC 1321; references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically. now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>. Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version. 1999-05-03 lpd Original version.
*/ */
#ifndef WEBSOCKETPP_COMMON_MD5_HPP #ifndef WEBSOCKETPP_COMMON_MD5_HPP
#define WEBSOCKETPP_COMMON_MD5_HPP #define WEBSOCKETPP_COMMON_MD5_HPP
/* /*
* This package supports both compile-time and run-time determination of CPU * 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 * 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 * 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 * 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 * 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 * 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. * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
*/ */
#include <stddef.h> #include <stddef.h>
#include <string> #include <string>
#include <cstring> #include <cstring>
namespace websocketpp { namespace websocketpp {
/// Provides MD5 hashing functionality /// Provides MD5 hashing functionality
namespace md5 { namespace md5 {
typedef unsigned char md5_byte_t; /* 8-bit byte */ typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef unsigned int md5_word_t; /* 32-bit word */ typedef unsigned int md5_word_t; /* 32-bit word */
/* Define the state of the MD5 Algorithm. */ /* Define the state of the MD5 Algorithm. */
typedef struct md5_state_s { typedef struct md5_state_s {
md5_word_t count[2]; /* message length in bits, lsw first */ md5_word_t count[2]; /* message length in bits, lsw first */
md5_word_t abcd[4]; /* digest buffer */ md5_word_t abcd[4]; /* digest buffer */
md5_byte_t buf[64]; /* accumulate block */ md5_byte_t buf[64]; /* accumulate block */
} md5_state_t; } md5_state_t;
/* Initialize the algorithm. */ /* Initialize the algorithm. */
inline void md5_init(md5_state_t *pms); inline void md5_init(md5_state_t *pms);
/* Append a string to the message. */ /* Append a string to the message. */
inline void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes); inline void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes);
/* Finish the message and return the digest. */ /* Finish the message and return the digest. */
inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ #undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN #ifdef ARCH_IS_BIG_ENDIAN
# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) # define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
#else #else
# define ZSW_MD5_BYTE_ORDER 0 # define ZSW_MD5_BYTE_ORDER 0
#endif #endif
#define ZSW_MD5_T_MASK ((md5_word_t)~0) #define ZSW_MD5_T_MASK ((md5_word_t)~0)
#define ZSW_MD5_T1 /* 0xd76aa478 */ (ZSW_MD5_T_MASK ^ 0x28955b87) #define ZSW_MD5_T1 /* 0xd76aa478 */ (ZSW_MD5_T_MASK ^ 0x28955b87)
#define ZSW_MD5_T2 /* 0xe8c7b756 */ (ZSW_MD5_T_MASK ^ 0x173848a9) #define ZSW_MD5_T2 /* 0xe8c7b756 */ (ZSW_MD5_T_MASK ^ 0x173848a9)
#define ZSW_MD5_T3 0x242070db #define ZSW_MD5_T3 0x242070db
#define ZSW_MD5_T4 /* 0xc1bdceee */ (ZSW_MD5_T_MASK ^ 0x3e423111) #define ZSW_MD5_T4 /* 0xc1bdceee */ (ZSW_MD5_T_MASK ^ 0x3e423111)
#define ZSW_MD5_T5 /* 0xf57c0faf */ (ZSW_MD5_T_MASK ^ 0x0a83f050) #define ZSW_MD5_T5 /* 0xf57c0faf */ (ZSW_MD5_T_MASK ^ 0x0a83f050)
#define ZSW_MD5_T6 0x4787c62a #define ZSW_MD5_T6 0x4787c62a
#define ZSW_MD5_T7 /* 0xa8304613 */ (ZSW_MD5_T_MASK ^ 0x57cfb9ec) #define ZSW_MD5_T7 /* 0xa8304613 */ (ZSW_MD5_T_MASK ^ 0x57cfb9ec)
#define ZSW_MD5_T8 /* 0xfd469501 */ (ZSW_MD5_T_MASK ^ 0x02b96afe) #define ZSW_MD5_T8 /* 0xfd469501 */ (ZSW_MD5_T_MASK ^ 0x02b96afe)
#define ZSW_MD5_T9 0x698098d8 #define ZSW_MD5_T9 0x698098d8
#define ZSW_MD5_T10 /* 0x8b44f7af */ (ZSW_MD5_T_MASK ^ 0x74bb0850) #define ZSW_MD5_T10 /* 0x8b44f7af */ (ZSW_MD5_T_MASK ^ 0x74bb0850)
#define ZSW_MD5_T11 /* 0xffff5bb1 */ (ZSW_MD5_T_MASK ^ 0x0000a44e) #define ZSW_MD5_T11 /* 0xffff5bb1 */ (ZSW_MD5_T_MASK ^ 0x0000a44e)
#define ZSW_MD5_T12 /* 0x895cd7be */ (ZSW_MD5_T_MASK ^ 0x76a32841) #define ZSW_MD5_T12 /* 0x895cd7be */ (ZSW_MD5_T_MASK ^ 0x76a32841)
#define ZSW_MD5_T13 0x6b901122 #define ZSW_MD5_T13 0x6b901122
#define ZSW_MD5_T14 /* 0xfd987193 */ (ZSW_MD5_T_MASK ^ 0x02678e6c) #define ZSW_MD5_T14 /* 0xfd987193 */ (ZSW_MD5_T_MASK ^ 0x02678e6c)
#define ZSW_MD5_T15 /* 0xa679438e */ (ZSW_MD5_T_MASK ^ 0x5986bc71) #define ZSW_MD5_T15 /* 0xa679438e */ (ZSW_MD5_T_MASK ^ 0x5986bc71)
#define ZSW_MD5_T16 0x49b40821 #define ZSW_MD5_T16 0x49b40821
#define ZSW_MD5_T17 /* 0xf61e2562 */ (ZSW_MD5_T_MASK ^ 0x09e1da9d) #define ZSW_MD5_T17 /* 0xf61e2562 */ (ZSW_MD5_T_MASK ^ 0x09e1da9d)
#define ZSW_MD5_T18 /* 0xc040b340 */ (ZSW_MD5_T_MASK ^ 0x3fbf4cbf) #define ZSW_MD5_T18 /* 0xc040b340 */ (ZSW_MD5_T_MASK ^ 0x3fbf4cbf)
#define ZSW_MD5_T19 0x265e5a51 #define ZSW_MD5_T19 0x265e5a51
#define ZSW_MD5_T20 /* 0xe9b6c7aa */ (ZSW_MD5_T_MASK ^ 0x16493855) #define ZSW_MD5_T20 /* 0xe9b6c7aa */ (ZSW_MD5_T_MASK ^ 0x16493855)
#define ZSW_MD5_T21 /* 0xd62f105d */ (ZSW_MD5_T_MASK ^ 0x29d0efa2) #define ZSW_MD5_T21 /* 0xd62f105d */ (ZSW_MD5_T_MASK ^ 0x29d0efa2)
#define ZSW_MD5_T22 0x02441453 #define ZSW_MD5_T22 0x02441453
#define ZSW_MD5_T23 /* 0xd8a1e681 */ (ZSW_MD5_T_MASK ^ 0x275e197e) #define ZSW_MD5_T23 /* 0xd8a1e681 */ (ZSW_MD5_T_MASK ^ 0x275e197e)
#define ZSW_MD5_T24 /* 0xe7d3fbc8 */ (ZSW_MD5_T_MASK ^ 0x182c0437) #define ZSW_MD5_T24 /* 0xe7d3fbc8 */ (ZSW_MD5_T_MASK ^ 0x182c0437)
#define ZSW_MD5_T25 0x21e1cde6 #define ZSW_MD5_T25 0x21e1cde6
#define ZSW_MD5_T26 /* 0xc33707d6 */ (ZSW_MD5_T_MASK ^ 0x3cc8f829) #define ZSW_MD5_T26 /* 0xc33707d6 */ (ZSW_MD5_T_MASK ^ 0x3cc8f829)
#define ZSW_MD5_T27 /* 0xf4d50d87 */ (ZSW_MD5_T_MASK ^ 0x0b2af278) #define ZSW_MD5_T27 /* 0xf4d50d87 */ (ZSW_MD5_T_MASK ^ 0x0b2af278)
#define ZSW_MD5_T28 0x455a14ed #define ZSW_MD5_T28 0x455a14ed
#define ZSW_MD5_T29 /* 0xa9e3e905 */ (ZSW_MD5_T_MASK ^ 0x561c16fa) #define ZSW_MD5_T29 /* 0xa9e3e905 */ (ZSW_MD5_T_MASK ^ 0x561c16fa)
#define ZSW_MD5_T30 /* 0xfcefa3f8 */ (ZSW_MD5_T_MASK ^ 0x03105c07) #define ZSW_MD5_T30 /* 0xfcefa3f8 */ (ZSW_MD5_T_MASK ^ 0x03105c07)
#define ZSW_MD5_T31 0x676f02d9 #define ZSW_MD5_T31 0x676f02d9
#define ZSW_MD5_T32 /* 0x8d2a4c8a */ (ZSW_MD5_T_MASK ^ 0x72d5b375) #define ZSW_MD5_T32 /* 0x8d2a4c8a */ (ZSW_MD5_T_MASK ^ 0x72d5b375)
#define ZSW_MD5_T33 /* 0xfffa3942 */ (ZSW_MD5_T_MASK ^ 0x0005c6bd) #define ZSW_MD5_T33 /* 0xfffa3942 */ (ZSW_MD5_T_MASK ^ 0x0005c6bd)
#define ZSW_MD5_T34 /* 0x8771f681 */ (ZSW_MD5_T_MASK ^ 0x788e097e) #define ZSW_MD5_T34 /* 0x8771f681 */ (ZSW_MD5_T_MASK ^ 0x788e097e)
#define ZSW_MD5_T35 0x6d9d6122 #define ZSW_MD5_T35 0x6d9d6122
#define ZSW_MD5_T36 /* 0xfde5380c */ (ZSW_MD5_T_MASK ^ 0x021ac7f3) #define ZSW_MD5_T36 /* 0xfde5380c */ (ZSW_MD5_T_MASK ^ 0x021ac7f3)
#define ZSW_MD5_T37 /* 0xa4beea44 */ (ZSW_MD5_T_MASK ^ 0x5b4115bb) #define ZSW_MD5_T37 /* 0xa4beea44 */ (ZSW_MD5_T_MASK ^ 0x5b4115bb)
#define ZSW_MD5_T38 0x4bdecfa9 #define ZSW_MD5_T38 0x4bdecfa9
#define ZSW_MD5_T39 /* 0xf6bb4b60 */ (ZSW_MD5_T_MASK ^ 0x0944b49f) #define ZSW_MD5_T39 /* 0xf6bb4b60 */ (ZSW_MD5_T_MASK ^ 0x0944b49f)
#define ZSW_MD5_T40 /* 0xbebfbc70 */ (ZSW_MD5_T_MASK ^ 0x4140438f) #define ZSW_MD5_T40 /* 0xbebfbc70 */ (ZSW_MD5_T_MASK ^ 0x4140438f)
#define ZSW_MD5_T41 0x289b7ec6 #define ZSW_MD5_T41 0x289b7ec6
#define ZSW_MD5_T42 /* 0xeaa127fa */ (ZSW_MD5_T_MASK ^ 0x155ed805) #define ZSW_MD5_T42 /* 0xeaa127fa */ (ZSW_MD5_T_MASK ^ 0x155ed805)
#define ZSW_MD5_T43 /* 0xd4ef3085 */ (ZSW_MD5_T_MASK ^ 0x2b10cf7a) #define ZSW_MD5_T43 /* 0xd4ef3085 */ (ZSW_MD5_T_MASK ^ 0x2b10cf7a)
#define ZSW_MD5_T44 0x04881d05 #define ZSW_MD5_T44 0x04881d05
#define ZSW_MD5_T45 /* 0xd9d4d039 */ (ZSW_MD5_T_MASK ^ 0x262b2fc6) #define ZSW_MD5_T45 /* 0xd9d4d039 */ (ZSW_MD5_T_MASK ^ 0x262b2fc6)
#define ZSW_MD5_T46 /* 0xe6db99e5 */ (ZSW_MD5_T_MASK ^ 0x1924661a) #define ZSW_MD5_T46 /* 0xe6db99e5 */ (ZSW_MD5_T_MASK ^ 0x1924661a)
#define ZSW_MD5_T47 0x1fa27cf8 #define ZSW_MD5_T47 0x1fa27cf8
#define ZSW_MD5_T48 /* 0xc4ac5665 */ (ZSW_MD5_T_MASK ^ 0x3b53a99a) #define ZSW_MD5_T48 /* 0xc4ac5665 */ (ZSW_MD5_T_MASK ^ 0x3b53a99a)
#define ZSW_MD5_T49 /* 0xf4292244 */ (ZSW_MD5_T_MASK ^ 0x0bd6ddbb) #define ZSW_MD5_T49 /* 0xf4292244 */ (ZSW_MD5_T_MASK ^ 0x0bd6ddbb)
#define ZSW_MD5_T50 0x432aff97 #define ZSW_MD5_T50 0x432aff97
#define ZSW_MD5_T51 /* 0xab9423a7 */ (ZSW_MD5_T_MASK ^ 0x546bdc58) #define ZSW_MD5_T51 /* 0xab9423a7 */ (ZSW_MD5_T_MASK ^ 0x546bdc58)
#define ZSW_MD5_T52 /* 0xfc93a039 */ (ZSW_MD5_T_MASK ^ 0x036c5fc6) #define ZSW_MD5_T52 /* 0xfc93a039 */ (ZSW_MD5_T_MASK ^ 0x036c5fc6)
#define ZSW_MD5_T53 0x655b59c3 #define ZSW_MD5_T53 0x655b59c3
#define ZSW_MD5_T54 /* 0x8f0ccc92 */ (ZSW_MD5_T_MASK ^ 0x70f3336d) #define ZSW_MD5_T54 /* 0x8f0ccc92 */ (ZSW_MD5_T_MASK ^ 0x70f3336d)
#define ZSW_MD5_T55 /* 0xffeff47d */ (ZSW_MD5_T_MASK ^ 0x00100b82) #define ZSW_MD5_T55 /* 0xffeff47d */ (ZSW_MD5_T_MASK ^ 0x00100b82)
#define ZSW_MD5_T56 /* 0x85845dd1 */ (ZSW_MD5_T_MASK ^ 0x7a7ba22e) #define ZSW_MD5_T56 /* 0x85845dd1 */ (ZSW_MD5_T_MASK ^ 0x7a7ba22e)
#define ZSW_MD5_T57 0x6fa87e4f #define ZSW_MD5_T57 0x6fa87e4f
#define ZSW_MD5_T58 /* 0xfe2ce6e0 */ (ZSW_MD5_T_MASK ^ 0x01d3191f) #define ZSW_MD5_T58 /* 0xfe2ce6e0 */ (ZSW_MD5_T_MASK ^ 0x01d3191f)
#define ZSW_MD5_T59 /* 0xa3014314 */ (ZSW_MD5_T_MASK ^ 0x5cfebceb) #define ZSW_MD5_T59 /* 0xa3014314 */ (ZSW_MD5_T_MASK ^ 0x5cfebceb)
#define ZSW_MD5_T60 0x4e0811a1 #define ZSW_MD5_T60 0x4e0811a1
#define ZSW_MD5_T61 /* 0xf7537e82 */ (ZSW_MD5_T_MASK ^ 0x08ac817d) #define ZSW_MD5_T61 /* 0xf7537e82 */ (ZSW_MD5_T_MASK ^ 0x08ac817d)
#define ZSW_MD5_T62 /* 0xbd3af235 */ (ZSW_MD5_T_MASK ^ 0x42c50dca) #define ZSW_MD5_T62 /* 0xbd3af235 */ (ZSW_MD5_T_MASK ^ 0x42c50dca)
#define ZSW_MD5_T63 0x2ad7d2bb #define ZSW_MD5_T63 0x2ad7d2bb
#define ZSW_MD5_T64 /* 0xeb86d391 */ (ZSW_MD5_T_MASK ^ 0x14792c6e) #define ZSW_MD5_T64 /* 0xeb86d391 */ (ZSW_MD5_T_MASK ^ 0x14792c6e)
static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) { static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
md5_word_t md5_word_t
a = pms->abcd[0], b = pms->abcd[1], a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3]; c = pms->abcd[2], d = pms->abcd[3];
md5_word_t t; md5_word_t t;
#if ZSW_MD5_BYTE_ORDER > 0 #if ZSW_MD5_BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */ /* Define storage only for big-endian CPUs. */
md5_word_t X[16]; md5_word_t X[16];
#else #else
/* Define storage for little-endian or both types of CPUs. */ /* Define storage for little-endian or both types of CPUs. */
md5_word_t xbuf[16]; md5_word_t xbuf[16];
md5_word_t const * X; md5_word_t const * X;
#endif #endif
{ {
#if ZSW_MD5_BYTE_ORDER == 0 #if ZSW_MD5_BYTE_ORDER == 0
/* /*
* Determine dynamically whether this is a big-endian or * Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient * little-endian machine, since we can use a more efficient
* algorithm on the latter. * algorithm on the latter.
*/ */
static int const w = 1; static int const w = 1;
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */ if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
#endif #endif
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */ #if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
{ {
/* /*
* On little-endian machines, we can process properly aligned * On little-endian machines, we can process properly aligned
* data without copying it. * data without copying it.
*/ */
if (!((data - (md5_byte_t const *)0) & 3)) { if (!((data - (md5_byte_t const *)0) & 3)) {
/* data are properly aligned */ /* data are properly aligned */
X = (md5_word_t const *)data; X = (md5_word_t const *)data;
} else { } else {
/* not aligned */ /* not aligned */
std::memcpy(xbuf, data, 64); std::memcpy(xbuf, data, 64);
X = xbuf; X = xbuf;
} }
} }
#endif #endif
#if ZSW_MD5_BYTE_ORDER == 0 #if ZSW_MD5_BYTE_ORDER == 0
else /* dynamic big-endian */ else /* dynamic big-endian */
#endif #endif
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */ #if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
{ {
/* /*
* On big-endian machines, we must arrange the bytes in the * On big-endian machines, we must arrange the bytes in the
* right order. * right order.
*/ */
const md5_byte_t *xp = data; const md5_byte_t *xp = data;
int i; int i;
# if ZSW_MD5_BYTE_ORDER == 0 # if ZSW_MD5_BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */ X = xbuf; /* (dynamic only) */
# else # else
# define xbuf X /* (static only) */ # define xbuf X /* (static only) */
# endif # endif
for (i = 0; i < 16; ++i, xp += 4) for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
} }
#endif #endif
} }
#define ZSW_MD5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) #define ZSW_MD5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */ /* Round 1. */
/* Let [abcd k s i] denote the operation /* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define ZSW_MD5_F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\ #define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_F(b,c,d) + X[k] + Ti;\ t = a + ZSW_MD5_F(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */ /* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, ZSW_MD5_T1); SET(a, b, c, d, 0, 7, ZSW_MD5_T1);
SET(d, a, b, c, 1, 12, ZSW_MD5_T2); SET(d, a, b, c, 1, 12, ZSW_MD5_T2);
SET(c, d, a, b, 2, 17, ZSW_MD5_T3); SET(c, d, a, b, 2, 17, ZSW_MD5_T3);
SET(b, c, d, a, 3, 22, ZSW_MD5_T4); SET(b, c, d, a, 3, 22, ZSW_MD5_T4);
SET(a, b, c, d, 4, 7, ZSW_MD5_T5); SET(a, b, c, d, 4, 7, ZSW_MD5_T5);
SET(d, a, b, c, 5, 12, ZSW_MD5_T6); SET(d, a, b, c, 5, 12, ZSW_MD5_T6);
SET(c, d, a, b, 6, 17, ZSW_MD5_T7); SET(c, d, a, b, 6, 17, ZSW_MD5_T7);
SET(b, c, d, a, 7, 22, ZSW_MD5_T8); SET(b, c, d, a, 7, 22, ZSW_MD5_T8);
SET(a, b, c, d, 8, 7, ZSW_MD5_T9); SET(a, b, c, d, 8, 7, ZSW_MD5_T9);
SET(d, a, b, c, 9, 12, ZSW_MD5_T10); SET(d, a, b, c, 9, 12, ZSW_MD5_T10);
SET(c, d, a, b, 10, 17, ZSW_MD5_T11); SET(c, d, a, b, 10, 17, ZSW_MD5_T11);
SET(b, c, d, a, 11, 22, ZSW_MD5_T12); SET(b, c, d, a, 11, 22, ZSW_MD5_T12);
SET(a, b, c, d, 12, 7, ZSW_MD5_T13); SET(a, b, c, d, 12, 7, ZSW_MD5_T13);
SET(d, a, b, c, 13, 12, ZSW_MD5_T14); SET(d, a, b, c, 13, 12, ZSW_MD5_T14);
SET(c, d, a, b, 14, 17, ZSW_MD5_T15); SET(c, d, a, b, 14, 17, ZSW_MD5_T15);
SET(b, c, d, a, 15, 22, ZSW_MD5_T16); SET(b, c, d, a, 15, 22, ZSW_MD5_T16);
#undef SET #undef SET
/* Round 2. */ /* Round 2. */
/* Let [abcd k s i] denote the operation /* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\ #define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_G(b,c,d) + X[k] + Ti;\ t = a + ZSW_MD5_G(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */ /* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, ZSW_MD5_T17); SET(a, b, c, d, 1, 5, ZSW_MD5_T17);
SET(d, a, b, c, 6, 9, ZSW_MD5_T18); SET(d, a, b, c, 6, 9, ZSW_MD5_T18);
SET(c, d, a, b, 11, 14, ZSW_MD5_T19); SET(c, d, a, b, 11, 14, ZSW_MD5_T19);
SET(b, c, d, a, 0, 20, ZSW_MD5_T20); SET(b, c, d, a, 0, 20, ZSW_MD5_T20);
SET(a, b, c, d, 5, 5, ZSW_MD5_T21); SET(a, b, c, d, 5, 5, ZSW_MD5_T21);
SET(d, a, b, c, 10, 9, ZSW_MD5_T22); SET(d, a, b, c, 10, 9, ZSW_MD5_T22);
SET(c, d, a, b, 15, 14, ZSW_MD5_T23); SET(c, d, a, b, 15, 14, ZSW_MD5_T23);
SET(b, c, d, a, 4, 20, ZSW_MD5_T24); SET(b, c, d, a, 4, 20, ZSW_MD5_T24);
SET(a, b, c, d, 9, 5, ZSW_MD5_T25); SET(a, b, c, d, 9, 5, ZSW_MD5_T25);
SET(d, a, b, c, 14, 9, ZSW_MD5_T26); SET(d, a, b, c, 14, 9, ZSW_MD5_T26);
SET(c, d, a, b, 3, 14, ZSW_MD5_T27); SET(c, d, a, b, 3, 14, ZSW_MD5_T27);
SET(b, c, d, a, 8, 20, ZSW_MD5_T28); SET(b, c, d, a, 8, 20, ZSW_MD5_T28);
SET(a, b, c, d, 13, 5, ZSW_MD5_T29); SET(a, b, c, d, 13, 5, ZSW_MD5_T29);
SET(d, a, b, c, 2, 9, ZSW_MD5_T30); SET(d, a, b, c, 2, 9, ZSW_MD5_T30);
SET(c, d, a, b, 7, 14, ZSW_MD5_T31); SET(c, d, a, b, 7, 14, ZSW_MD5_T31);
SET(b, c, d, a, 12, 20, ZSW_MD5_T32); SET(b, c, d, a, 12, 20, ZSW_MD5_T32);
#undef SET #undef SET
/* Round 3. */ /* Round 3. */
/* Let [abcd k s t] denote the operation /* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z)) #define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\ #define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_H(b,c,d) + X[k] + Ti;\ t = a + ZSW_MD5_H(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */ /* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, ZSW_MD5_T33); SET(a, b, c, d, 5, 4, ZSW_MD5_T33);
SET(d, a, b, c, 8, 11, ZSW_MD5_T34); SET(d, a, b, c, 8, 11, ZSW_MD5_T34);
SET(c, d, a, b, 11, 16, ZSW_MD5_T35); SET(c, d, a, b, 11, 16, ZSW_MD5_T35);
SET(b, c, d, a, 14, 23, ZSW_MD5_T36); SET(b, c, d, a, 14, 23, ZSW_MD5_T36);
SET(a, b, c, d, 1, 4, ZSW_MD5_T37); SET(a, b, c, d, 1, 4, ZSW_MD5_T37);
SET(d, a, b, c, 4, 11, ZSW_MD5_T38); SET(d, a, b, c, 4, 11, ZSW_MD5_T38);
SET(c, d, a, b, 7, 16, ZSW_MD5_T39); SET(c, d, a, b, 7, 16, ZSW_MD5_T39);
SET(b, c, d, a, 10, 23, ZSW_MD5_T40); SET(b, c, d, a, 10, 23, ZSW_MD5_T40);
SET(a, b, c, d, 13, 4, ZSW_MD5_T41); SET(a, b, c, d, 13, 4, ZSW_MD5_T41);
SET(d, a, b, c, 0, 11, ZSW_MD5_T42); SET(d, a, b, c, 0, 11, ZSW_MD5_T42);
SET(c, d, a, b, 3, 16, ZSW_MD5_T43); SET(c, d, a, b, 3, 16, ZSW_MD5_T43);
SET(b, c, d, a, 6, 23, ZSW_MD5_T44); SET(b, c, d, a, 6, 23, ZSW_MD5_T44);
SET(a, b, c, d, 9, 4, ZSW_MD5_T45); SET(a, b, c, d, 9, 4, ZSW_MD5_T45);
SET(d, a, b, c, 12, 11, ZSW_MD5_T46); SET(d, a, b, c, 12, 11, ZSW_MD5_T46);
SET(c, d, a, b, 15, 16, ZSW_MD5_T47); SET(c, d, a, b, 15, 16, ZSW_MD5_T47);
SET(b, c, d, a, 2, 23, ZSW_MD5_T48); SET(b, c, d, a, 2, 23, ZSW_MD5_T48);
#undef SET #undef SET
/* Round 4. */ /* Round 4. */
/* Let [abcd k s t] denote the operation /* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z))) #define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\ #define SET(a, b, c, d, k, s, Ti)\
t = a + ZSW_MD5_I(b,c,d) + X[k] + Ti;\ t = a + ZSW_MD5_I(b,c,d) + X[k] + Ti;\
a = ZSW_MD5_ROTATE_LEFT(t, s) + b a = ZSW_MD5_ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */ /* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, ZSW_MD5_T49); SET(a, b, c, d, 0, 6, ZSW_MD5_T49);
SET(d, a, b, c, 7, 10, ZSW_MD5_T50); SET(d, a, b, c, 7, 10, ZSW_MD5_T50);
SET(c, d, a, b, 14, 15, ZSW_MD5_T51); SET(c, d, a, b, 14, 15, ZSW_MD5_T51);
SET(b, c, d, a, 5, 21, ZSW_MD5_T52); SET(b, c, d, a, 5, 21, ZSW_MD5_T52);
SET(a, b, c, d, 12, 6, ZSW_MD5_T53); SET(a, b, c, d, 12, 6, ZSW_MD5_T53);
SET(d, a, b, c, 3, 10, ZSW_MD5_T54); SET(d, a, b, c, 3, 10, ZSW_MD5_T54);
SET(c, d, a, b, 10, 15, ZSW_MD5_T55); SET(c, d, a, b, 10, 15, ZSW_MD5_T55);
SET(b, c, d, a, 1, 21, ZSW_MD5_T56); SET(b, c, d, a, 1, 21, ZSW_MD5_T56);
SET(a, b, c, d, 8, 6, ZSW_MD5_T57); SET(a, b, c, d, 8, 6, ZSW_MD5_T57);
SET(d, a, b, c, 15, 10, ZSW_MD5_T58); SET(d, a, b, c, 15, 10, ZSW_MD5_T58);
SET(c, d, a, b, 6, 15, ZSW_MD5_T59); SET(c, d, a, b, 6, 15, ZSW_MD5_T59);
SET(b, c, d, a, 13, 21, ZSW_MD5_T60); SET(b, c, d, a, 13, 21, ZSW_MD5_T60);
SET(a, b, c, d, 4, 6, ZSW_MD5_T61); SET(a, b, c, d, 4, 6, ZSW_MD5_T61);
SET(d, a, b, c, 11, 10, ZSW_MD5_T62); SET(d, a, b, c, 11, 10, ZSW_MD5_T62);
SET(c, d, a, b, 2, 15, ZSW_MD5_T63); SET(c, d, a, b, 2, 15, ZSW_MD5_T63);
SET(b, c, d, a, 9, 21, ZSW_MD5_T64); SET(b, c, d, a, 9, 21, ZSW_MD5_T64);
#undef SET #undef SET
/* Then perform the following additions. (That is increment each /* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block of the four registers by the value it had before this block
was started.) */ was started.) */
pms->abcd[0] += a; pms->abcd[0] += a;
pms->abcd[1] += b; pms->abcd[1] += b;
pms->abcd[2] += c; pms->abcd[2] += c;
pms->abcd[3] += d; pms->abcd[3] += d;
} }
void md5_init(md5_state_t *pms) { void md5_init(md5_state_t *pms) {
pms->count[0] = pms->count[1] = 0; pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301; pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ ZSW_MD5_T_MASK ^ 0x10325476; pms->abcd[1] = /*0xefcdab89*/ ZSW_MD5_T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ ZSW_MD5_T_MASK ^ 0x67452301; pms->abcd[2] = /*0x98badcfe*/ ZSW_MD5_T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476; pms->abcd[3] = 0x10325476;
} }
void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes) { void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes) {
md5_byte_t const * p = data; md5_byte_t const * p = data;
size_t left = nbytes; size_t left = nbytes;
int offset = (pms->count[0] >> 3) & 63; int offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3); md5_word_t nbits = (md5_word_t)(nbytes << 3);
if (nbytes <= 0) if (nbytes <= 0)
return; return;
/* Update the message length. */ /* Update the message length. */
pms->count[1] += nbytes >> 29; pms->count[1] += nbytes >> 29;
pms->count[0] += nbits; pms->count[0] += nbits;
if (pms->count[0] < nbits) if (pms->count[0] < nbits)
pms->count[1]++; pms->count[1]++;
/* Process an initial partial block. */ /* Process an initial partial block. */
if (offset) { if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes)); int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes));
std::memcpy(pms->buf + offset, p, copy); std::memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64) if (offset + copy < 64)
return; return;
p += copy; p += copy;
left -= copy; left -= copy;
md5_process(pms, pms->buf); md5_process(pms, pms->buf);
} }
/* Process full blocks. */ /* Process full blocks. */
for (; left >= 64; p += 64, left -= 64) for (; left >= 64; p += 64, left -= 64)
md5_process(pms, p); md5_process(pms, p);
/* Process a final partial block. */ /* Process a final partial block. */
if (left) if (left)
std::memcpy(pms->buf, p, left); std::memcpy(pms->buf, p, left);
} }
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) { void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
static md5_byte_t const pad[64] = { static md5_byte_t const pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}; };
md5_byte_t data[8]; md5_byte_t data[8];
int i; int i;
/* Save the length before padding. */ /* Save the length before padding. */
for (i = 0; i < 8; ++i) for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */ /* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */ /* Append the length. */
md5_append(pms, data, 8); md5_append(pms, data, 8);
for (i = 0; i < 16; ++i) for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
} }
// some convenience c++ functions // some convenience c++ functions
inline std::string md5_hash_string(std::string const & s) { inline std::string md5_hash_string(std::string const & s) {
char digest[16]; char digest[16];
md5_state_t state; md5_state_t state;
md5_init(&state); md5_init(&state);
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size()); md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
md5_finish(&state, (md5_byte_t *)digest); md5_finish(&state, (md5_byte_t *)digest);
std::string ret; std::string ret;
ret.resize(16); ret.resize(16);
std::copy(digest,digest+16,ret.begin()); std::copy(digest,digest+16,ret.begin());
return ret; return ret;
} }
const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
inline std::string md5_hash_hex(std::string const & input) { inline std::string md5_hash_hex(std::string const & input) {
std::string hash = md5_hash_string(input); std::string hash = md5_hash_string(input);
std::string hex; std::string hex;
for (size_t i = 0; i < hash.size(); i++) { for (size_t i = 0; i < hash.size(); i++) {
hex.push_back(hexval[((hash[i] >> 4) & 0xF)]); hex.push_back(hexval[((hash[i] >> 4) & 0xF)]);
hex.push_back(hexval[(hash[i]) & 0x0F]); hex.push_back(hexval[(hash[i]) & 0x0F]);
} }
return hex; return hex;
} }
} // md5 } // md5
} // websocketpp } // websocketpp
#endif // WEBSOCKETPP_COMMON_MD5_HPP #endif // WEBSOCKETPP_COMMON_MD5_HPP

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,56 +1,56 @@
/* /*
* Copyright (c) 2014, Peter Thorson. All rights reserved. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef WEBSOCKETPP_COMMON_TIME_HPP #ifndef WEBSOCKETPP_COMMON_TIME_HPP
#define WEBSOCKETPP_COMMON_TIME_HPP #define WEBSOCKETPP_COMMON_TIME_HPP
#include <ctime> #include <ctime>
namespace websocketpp { namespace websocketpp {
namespace lib { namespace lib {
// Code in this header was inspired by the following article and includes some // 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 // 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/ // http://kjellkod.wordpress.com/2013/01/22/exploring-c11-part-2-localtime-and-time-again/
/// Thread safe cross platform localtime /// Thread safe cross platform localtime
inline std::tm localtime(std::time_t const & time) { inline std::tm localtime(std::time_t const & time) {
std::tm tm_snapshot; std::tm tm_snapshot;
#if (defined(__MINGW32__) || defined(__MINGW64__)) #if (defined(__MINGW32__) || defined(__MINGW64__))
memcpy(&tm_snapshot, ::localtime(&time), sizeof(std::tm)); memcpy(&tm_snapshot, ::localtime(&time), sizeof(std::tm));
#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) #elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
localtime_s(&tm_snapshot, &time); localtime_s(&tm_snapshot, &time);
#else #else
localtime_r(&time, &tm_snapshot); // POSIX localtime_r(&time, &tm_snapshot); // POSIX
#endif #endif
return tm_snapshot; return tm_snapshot;
} }
} // lib } // lib
} // websocketpp } // websocketpp
#endif // WEBSOCKETPP_COMMON_TIME_HPP #endif // WEBSOCKETPP_COMMON_TIME_HPP

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,297 +1,297 @@
/* /*
* Copyright (c) 2014, Peter Thorson. All rights reserved. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef WEBSOCKETPP_CONFIG_CORE_HPP #ifndef WEBSOCKETPP_CONFIG_CORE_HPP
#define WEBSOCKETPP_CONFIG_CORE_HPP #define WEBSOCKETPP_CONFIG_CORE_HPP
// Non-Policy common stuff // Non-Policy common stuff
#include <websocketpp/common/platforms.hpp> #include <websocketpp/common/platforms.hpp>
#include <websocketpp/common/cpp11.hpp> #include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp> #include <websocketpp/common/stdint.hpp>
// Concurrency // Concurrency
#include <websocketpp/concurrency/basic.hpp> #include <websocketpp/concurrency/basic.hpp>
// Transport // Transport
#include <websocketpp/transport/iostream/endpoint.hpp> #include <websocketpp/transport/iostream/endpoint.hpp>
// HTTP // HTTP
#include <websocketpp/http/request.hpp> #include <websocketpp/http/request.hpp>
#include <websocketpp/http/response.hpp> #include <websocketpp/http/response.hpp>
// Messages // Messages
#include <websocketpp/message_buffer/message.hpp> #include <websocketpp/message_buffer/message.hpp>
#include <websocketpp/message_buffer/alloc.hpp> #include <websocketpp/message_buffer/alloc.hpp>
// Loggers // Loggers
#include <websocketpp/logger/basic.hpp> #include <websocketpp/logger/basic.hpp>
#include <websocketpp/logger/levels.hpp> #include <websocketpp/logger/levels.hpp>
// RNG // RNG
#include <websocketpp/random/none.hpp> #include <websocketpp/random/none.hpp>
// User stub base classes // User stub base classes
#include <websocketpp/endpoint_base.hpp> #include <websocketpp/endpoint_base.hpp>
#include <websocketpp/connection_base.hpp> #include <websocketpp/connection_base.hpp>
// Extensions // Extensions
#include <websocketpp/extensions/permessage_deflate/disabled.hpp> #include <websocketpp/extensions/permessage_deflate/disabled.hpp>
namespace websocketpp { namespace websocketpp {
namespace config { namespace config {
/// Server config with iostream transport /// Server config with iostream transport
struct core { struct core {
typedef core type; typedef core type;
// Concurrency policy // Concurrency policy
typedef websocketpp::concurrency::basic concurrency_type; typedef websocketpp::concurrency::basic concurrency_type;
// HTTP Parser Policies // HTTP Parser Policies
typedef http::parser::request request_type; typedef http::parser::request request_type;
typedef http::parser::response response_type; typedef http::parser::response response_type;
// Message Policies // Message Policies
typedef message_buffer::message<message_buffer::alloc::con_msg_manager> typedef message_buffer::message<message_buffer::alloc::con_msg_manager>
message_type; message_type;
typedef message_buffer::alloc::con_msg_manager<message_type> typedef message_buffer::alloc::con_msg_manager<message_type>
con_msg_manager_type; con_msg_manager_type;
typedef message_buffer::alloc::endpoint_msg_manager<con_msg_manager_type> typedef message_buffer::alloc::endpoint_msg_manager<con_msg_manager_type>
endpoint_msg_manager_type; endpoint_msg_manager_type;
/// Logging policies /// Logging policies
typedef websocketpp::log::basic<concurrency_type, typedef websocketpp::log::basic<concurrency_type,
websocketpp::log::elevel> elog_type; websocketpp::log::elevel> elog_type;
typedef websocketpp::log::basic<concurrency_type, typedef websocketpp::log::basic<concurrency_type,
websocketpp::log::alevel> alog_type; websocketpp::log::alevel> alog_type;
/// RNG policies /// RNG policies
typedef websocketpp::random::none::int_generator<uint32_t> rng_type; typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
/// Controls compile time enabling/disabling of thread syncronization /// Controls compile time enabling/disabling of thread syncronization
/// code Disabling can provide a minor performance improvement to single /// code Disabling can provide a minor performance improvement to single
/// threaded applications /// threaded applications
static bool const enable_multithreading = true; static bool const enable_multithreading = true;
struct transport_config { struct transport_config {
typedef type::concurrency_type concurrency_type; typedef type::concurrency_type concurrency_type;
typedef type::elog_type elog_type; typedef type::elog_type elog_type;
typedef type::alog_type alog_type; typedef type::alog_type alog_type;
typedef type::request_type request_type; typedef type::request_type request_type;
typedef type::response_type response_type; typedef type::response_type response_type;
/// Controls compile time enabling/disabling of thread syncronization /// Controls compile time enabling/disabling of thread syncronization
/// code Disabling can provide a minor performance improvement to single /// code Disabling can provide a minor performance improvement to single
/// threaded applications /// threaded applications
static bool const enable_multithreading = true; static bool const enable_multithreading = true;
/// Default timer values (in ms) /// Default timer values (in ms)
/// Length of time to wait for socket pre-initialization /// Length of time to wait for socket pre-initialization
/** /**
* Exactly what this includes depends on the socket policy in use * Exactly what this includes depends on the socket policy in use
*/ */
static const long timeout_socket_pre_init = 5000; static const long timeout_socket_pre_init = 5000;
/// Length of time to wait before a proxy handshake is aborted /// Length of time to wait before a proxy handshake is aborted
static const long timeout_proxy = 5000; static const long timeout_proxy = 5000;
/// Length of time to wait for socket post-initialization /// Length of time to wait for socket post-initialization
/** /**
* Exactly what this includes depends on the socket policy in use. * Exactly what this includes depends on the socket policy in use.
* Often this means the TLS handshake * Often this means the TLS handshake
*/ */
static const long timeout_socket_post_init = 5000; static const long timeout_socket_post_init = 5000;
/// Length of time to wait for dns resolution /// Length of time to wait for dns resolution
static const long timeout_dns_resolve = 5000; static const long timeout_dns_resolve = 5000;
/// Length of time to wait for TCP connect /// Length of time to wait for TCP connect
static const long timeout_connect = 5000; static const long timeout_connect = 5000;
/// Length of time to wait for socket shutdown /// Length of time to wait for socket shutdown
static const long timeout_socket_shutdown = 5000; static const long timeout_socket_shutdown = 5000;
}; };
/// Transport Endpoint Component /// Transport Endpoint Component
typedef websocketpp::transport::iostream::endpoint<transport_config> typedef websocketpp::transport::iostream::endpoint<transport_config>
transport_type; transport_type;
/// User overridable Endpoint base class /// User overridable Endpoint base class
typedef websocketpp::endpoint_base endpoint_base; typedef websocketpp::endpoint_base endpoint_base;
/// User overridable Connection base class /// User overridable Connection base class
typedef websocketpp::connection_base connection_base; typedef websocketpp::connection_base connection_base;
/// Default timer values (in ms) /// Default timer values (in ms)
/// Length of time before an opening handshake is aborted /// Length of time before an opening handshake is aborted
static const long timeout_open_handshake = 5000; static const long timeout_open_handshake = 5000;
/// Length of time before a closing handshake is aborted /// Length of time before a closing handshake is aborted
static const long timeout_close_handshake = 5000; static const long timeout_close_handshake = 5000;
/// Length of time to wait for a pong after a ping /// Length of time to wait for a pong after a ping
static const long timeout_pong = 5000; static const long timeout_pong = 5000;
/// WebSocket Protocol version to use as a client /// WebSocket Protocol version to use as a client
/** /**
* What version of the WebSocket Protocol to use for outgoing client * What version of the WebSocket Protocol to use for outgoing client
* connections. Setting this to a value other than 13 (RFC6455) is not * connections. Setting this to a value other than 13 (RFC6455) is not
* recommended. * recommended.
*/ */
static const int client_version = 13; // RFC6455 static const int client_version = 13; // RFC6455
/// Default static error logging channels /// Default static error logging channels
/** /**
* Which error logging channels to enable at compile time. Channels not * Which error logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library. * enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely * 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 * code to test whether or not to print out log messages on a certain
* channel * channel
* *
* Default is all except for development/debug level errors * Default is all except for development/debug level errors
*/ */
static const websocketpp::log::level elog_level = static const websocketpp::log::level elog_level =
websocketpp::log::elevel::all ^ websocketpp::log::elevel::devel; websocketpp::log::elevel::all ^ websocketpp::log::elevel::devel;
/// Default static access logging channels /// Default static access logging channels
/** /**
* Which access logging channels to enable at compile time. Channels not * Which access logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library. * enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely * 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 * code to test whether or not to print out log messages on a certain
* channel * channel
* *
* Default is all except for development/debug level access messages * Default is all except for development/debug level access messages
*/ */
static const websocketpp::log::level alog_level = static const websocketpp::log::level alog_level =
websocketpp::log::alevel::all ^ websocketpp::log::alevel::devel; websocketpp::log::alevel::all ^ websocketpp::log::alevel::devel;
/// Size of the per-connection read buffer /// Size of the per-connection read buffer
/** /**
* Each connection has an internal buffer of this size. A larger value will * 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 * result in fewer trips through the library and less CPU overhead at the
* expense of increased memory usage per connection. * expense of increased memory usage per connection.
* *
* If your application primarily deals in very large messages you may want * If your application primarily deals in very large messages you may want
* to try setting this value higher. * to try setting this value higher.
* *
* If your application has a lot of connections or primarily deals in small * If your application has a lot of connections or primarily deals in small
* messages you may want to try setting this smaller. * messages you may want to try setting this smaller.
*/ */
static const size_t connection_read_buffer_size = 16384; static const size_t connection_read_buffer_size = 16384;
/// Drop connections immediately on protocol error. /// Drop connections immediately on protocol error.
/** /**
* Drop connections on protocol error rather than sending a close frame. * Drop connections on protocol error rather than sending a close frame.
* Off by default. This may result in legit messages near the error being * 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 * dropped as well. It may free up resources otherwise spent dealing with
* misbehaving clients. * misbehaving clients.
*/ */
static const bool drop_on_protocol_error = false; static const bool drop_on_protocol_error = false;
/// Suppresses the return of detailed connection close information /// Suppresses the return of detailed connection close information
/** /**
* Silence close suppresses the return of detailed connection close * Silence close suppresses the return of detailed connection close
* information during the closing handshake. This information is useful * information during the closing handshake. This information is useful
* for debugging and presenting useful errors to end users but may be * for debugging and presenting useful errors to end users but may be
* undesirable for security reasons in some production environments. * undesirable for security reasons in some production environments.
* Close reasons could be used by an attacker to confirm that the endpoint * 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 * is out of resources or be used to identify the WebSocket implementation
* in use. * in use.
* *
* Note: this will suppress *all* close codes, including those explicitly * Note: this will suppress *all* close codes, including those explicitly
* sent by local applications. * sent by local applications.
*/ */
static const bool silent_close = false; static const bool silent_close = false;
/// Default maximum message size /// Default maximum message size
/** /**
* Default value for the processor's maximum message size. 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 * determines the point at which the library will fail a connection with the
* message_too_big protocol error. * message_too_big protocol error.
* *
* The default is 32MB * The default is 32MB
* *
* @since 0.3.0 * @since 0.3.0
*/ */
static const size_t max_message_size = 32000000; static const size_t max_message_size = 32000000;
/// Default maximum http body size /// Default maximum http body size
/** /**
* Default value for the http parser's maximum body size. Maximum 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 * determines the point at which the library will abort reading an HTTP
* connection with the 413/request entity too large error. * connection with the 413/request entity too large error.
* *
* The default is 32MB * The default is 32MB
* *
* @since 0.5.0 * @since 0.5.0
*/ */
static const size_t max_http_body_size = 32000000; static const size_t max_http_body_size = 32000000;
/// Global flag for enabling/disabling extensions /// Global flag for enabling/disabling extensions
static const bool enable_extensions = true; static const bool enable_extensions = true;
/// Extension specific settings: /// Extension specific settings:
/// permessage_compress extension /// permessage_compress extension
struct permessage_deflate_config { struct permessage_deflate_config {
typedef core::request_type request_type; typedef core::request_type request_type;
/// If the remote endpoint requests that we reset the compression /// If the remote endpoint requests that we reset the compression
/// context after each message should we honor the request? /// context after each message should we honor the request?
static const bool allow_disabling_context_takeover = true; static const bool allow_disabling_context_takeover = true;
/// If the remote endpoint requests that we reduce the size of the /// If the remote endpoint requests that we reduce the size of the
/// LZ77 sliding window size this is the lowest value that will be /// 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 /// 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 /// allow any possible window size. A value of 15 means do not allow
/// negotiation of the window size (ie require the default). /// negotiation of the window size (ie require the default).
static const uint8_t minimum_outgoing_window_bits = 8; static const uint8_t minimum_outgoing_window_bits = 8;
}; };
typedef websocketpp::extensions::permessage_deflate::disabled typedef websocketpp::extensions::permessage_deflate::disabled
<permessage_deflate_config> permessage_deflate_type; <permessage_deflate_config> permessage_deflate_type;
/// Autonegotiate permessage-deflate /// Autonegotiate permessage-deflate
/** /**
* Automatically enables the permessage-deflate extension. * Automatically enables the permessage-deflate extension.
* *
* For clients this results in a permessage-deflate extension request being * For clients this results in a permessage-deflate extension request being
* sent with every request rather than requiring it to be requested manually * sent with every request rather than requiring it to be requested manually
* *
* For servers this results in accepting the first set of extension settings * For servers this results in accepting the first set of extension settings
* requested by the client that we understand being used. The alternative is * requested by the client that we understand being used. The alternative is
* requiring the extension to be manually negotiated in `validate`. With * requiring the extension to be manually negotiated in `validate`. With
* auto-negotiate on, you may still override the auto-negotiate manually if * auto-negotiate on, you may still override the auto-negotiate manually if
* needed. * needed.
*/ */
//static const bool autonegotiate_compression = false; //static const bool autonegotiate_compression = false;
}; };
} // namespace config } // namespace config
} // namespace websocketpp } // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_CORE_HPP #endif // WEBSOCKETPP_CONFIG_CORE_HPP

View File

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

View File

@@ -1,286 +1,286 @@
/* /*
* Copyright (c) 2014, Peter Thorson. All rights reserved. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef WEBSOCKETPP_CONFIG_DEBUG_HPP #ifndef WEBSOCKETPP_CONFIG_DEBUG_HPP
#define WEBSOCKETPP_CONFIG_DEBUG_HPP #define WEBSOCKETPP_CONFIG_DEBUG_HPP
// Non-Policy common stuff // Non-Policy common stuff
#include <websocketpp/common/cpp11.hpp> #include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp> #include <websocketpp/common/stdint.hpp>
// Concurrency // Concurrency
#include <websocketpp/concurrency/basic.hpp> #include <websocketpp/concurrency/basic.hpp>
// Transport // Transport
#include <websocketpp/transport/iostream/endpoint.hpp> #include <websocketpp/transport/iostream/endpoint.hpp>
// HTTP // HTTP
#include <websocketpp/http/request.hpp> #include <websocketpp/http/request.hpp>
#include <websocketpp/http/response.hpp> #include <websocketpp/http/response.hpp>
// Messages // Messages
#include <websocketpp/message_buffer/message.hpp> #include <websocketpp/message_buffer/message.hpp>
#include <websocketpp/message_buffer/alloc.hpp> #include <websocketpp/message_buffer/alloc.hpp>
// Loggers // Loggers
#include <websocketpp/logger/basic.hpp> #include <websocketpp/logger/basic.hpp>
// RNG // RNG
#include <websocketpp/random/none.hpp> #include <websocketpp/random/none.hpp>
// User stub base classes // User stub base classes
#include <websocketpp/endpoint_base.hpp> #include <websocketpp/endpoint_base.hpp>
#include <websocketpp/connection_base.hpp> #include <websocketpp/connection_base.hpp>
// Extensions // Extensions
#include <websocketpp/extensions/permessage_deflate/disabled.hpp> #include <websocketpp/extensions/permessage_deflate/disabled.hpp>
namespace websocketpp { namespace websocketpp {
namespace config { namespace config {
/// Client/Server debug config with iostream transport /// Client/Server debug config with iostream transport
struct debug_core { struct debug_core {
typedef debug_core type; typedef debug_core type;
// Concurrency policy // Concurrency policy
typedef websocketpp::concurrency::basic concurrency_type; typedef websocketpp::concurrency::basic concurrency_type;
// HTTP Parser Policies // HTTP Parser Policies
typedef http::parser::request request_type; typedef http::parser::request request_type;
typedef http::parser::response response_type; typedef http::parser::response response_type;
// Message Policies // Message Policies
typedef message_buffer::message<message_buffer::alloc::con_msg_manager> typedef message_buffer::message<message_buffer::alloc::con_msg_manager>
message_type; message_type;
typedef message_buffer::alloc::con_msg_manager<message_type> typedef message_buffer::alloc::con_msg_manager<message_type>
con_msg_manager_type; con_msg_manager_type;
typedef message_buffer::alloc::endpoint_msg_manager<con_msg_manager_type> typedef message_buffer::alloc::endpoint_msg_manager<con_msg_manager_type>
endpoint_msg_manager_type; endpoint_msg_manager_type;
/// Logging policies /// Logging policies
typedef websocketpp::log::basic<concurrency_type, typedef websocketpp::log::basic<concurrency_type,
websocketpp::log::elevel> elog_type; websocketpp::log::elevel> elog_type;
typedef websocketpp::log::basic<concurrency_type, typedef websocketpp::log::basic<concurrency_type,
websocketpp::log::alevel> alog_type; websocketpp::log::alevel> alog_type;
/// RNG policies /// RNG policies
typedef websocketpp::random::none::int_generator<uint32_t> rng_type; typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
/// Controls compile time enabling/disabling of thread syncronization /// Controls compile time enabling/disabling of thread syncronization
/// code Disabling can provide a minor performance improvement to single /// code Disabling can provide a minor performance improvement to single
/// threaded applications /// threaded applications
static bool const enable_multithreading = true; static bool const enable_multithreading = true;
struct transport_config { struct transport_config {
typedef type::concurrency_type concurrency_type; typedef type::concurrency_type concurrency_type;
typedef type::elog_type elog_type; typedef type::elog_type elog_type;
typedef type::alog_type alog_type; typedef type::alog_type alog_type;
typedef type::request_type request_type; typedef type::request_type request_type;
typedef type::response_type response_type; typedef type::response_type response_type;
/// Controls compile time enabling/disabling of thread syncronization /// Controls compile time enabling/disabling of thread syncronization
/// code Disabling can provide a minor performance improvement to single /// code Disabling can provide a minor performance improvement to single
/// threaded applications /// threaded applications
static bool const enable_multithreading = true; static bool const enable_multithreading = true;
/// Default timer values (in ms) /// Default timer values (in ms)
/// Length of time to wait for socket pre-initialization /// Length of time to wait for socket pre-initialization
/** /**
* Exactly what this includes depends on the socket policy in use * Exactly what this includes depends on the socket policy in use
*/ */
static const long timeout_socket_pre_init = 5000; static const long timeout_socket_pre_init = 5000;
/// Length of time to wait before a proxy handshake is aborted /// Length of time to wait before a proxy handshake is aborted
static const long timeout_proxy = 5000; static const long timeout_proxy = 5000;
/// Length of time to wait for socket post-initialization /// Length of time to wait for socket post-initialization
/** /**
* Exactly what this includes depends on the socket policy in use. * Exactly what this includes depends on the socket policy in use.
* Often this means the TLS handshake * Often this means the TLS handshake
*/ */
static const long timeout_socket_post_init = 5000; static const long timeout_socket_post_init = 5000;
/// Length of time to wait for dns resolution /// Length of time to wait for dns resolution
static const long timeout_dns_resolve = 5000; static const long timeout_dns_resolve = 5000;
/// Length of time to wait for TCP connect /// Length of time to wait for TCP connect
static const long timeout_connect = 5000; static const long timeout_connect = 5000;
/// Length of time to wait for socket shutdown /// Length of time to wait for socket shutdown
static const long timeout_socket_shutdown = 5000; static const long timeout_socket_shutdown = 5000;
}; };
/// Transport Endpoint Component /// Transport Endpoint Component
typedef websocketpp::transport::iostream::endpoint<transport_config> typedef websocketpp::transport::iostream::endpoint<transport_config>
transport_type; transport_type;
/// User overridable Endpoint base class /// User overridable Endpoint base class
typedef websocketpp::endpoint_base endpoint_base; typedef websocketpp::endpoint_base endpoint_base;
/// User overridable Connection base class /// User overridable Connection base class
typedef websocketpp::connection_base connection_base; typedef websocketpp::connection_base connection_base;
/// Default timer values (in ms) /// Default timer values (in ms)
/// Length of time before an opening handshake is aborted /// Length of time before an opening handshake is aborted
static const long timeout_open_handshake = 5000; static const long timeout_open_handshake = 5000;
/// Length of time before a closing handshake is aborted /// Length of time before a closing handshake is aborted
static const long timeout_close_handshake = 5000; static const long timeout_close_handshake = 5000;
/// Length of time to wait for a pong after a ping /// Length of time to wait for a pong after a ping
static const long timeout_pong = 5000; static const long timeout_pong = 5000;
/// WebSocket Protocol version to use as a client /// WebSocket Protocol version to use as a client
/** /**
* What version of the WebSocket Protocol to use for outgoing client * What version of the WebSocket Protocol to use for outgoing client
* connections. Setting this to a value other than 13 (RFC6455) is not * connections. Setting this to a value other than 13 (RFC6455) is not
* recommended. * recommended.
*/ */
static const int client_version = 13; // RFC6455 static const int client_version = 13; // RFC6455
/// Default static error logging channels /// Default static error logging channels
/** /**
* Which error logging channels to enable at compile time. Channels not * Which error logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library. * enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely * 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 * code to test whether or not to print out log messages on a certain
* channel * channel
* *
* Default is all except for development/debug level errors * Default is all except for development/debug level errors
*/ */
static const websocketpp::log::level elog_level = static const websocketpp::log::level elog_level =
websocketpp::log::elevel::all; websocketpp::log::elevel::all;
/// Default static access logging channels /// Default static access logging channels
/** /**
* Which access logging channels to enable at compile time. Channels not * Which access logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library. * enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely * 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 * code to test whether or not to print out log messages on a certain
* channel * channel
* *
* Default is all except for development/debug level access messages * Default is all except for development/debug level access messages
*/ */
static const websocketpp::log::level alog_level = static const websocketpp::log::level alog_level =
websocketpp::log::alevel::all; websocketpp::log::alevel::all;
/// ///
static const size_t connection_read_buffer_size = 16384; static const size_t connection_read_buffer_size = 16384;
/// Drop connections immediately on protocol error. /// Drop connections immediately on protocol error.
/** /**
* Drop connections on protocol error rather than sending a close frame. * Drop connections on protocol error rather than sending a close frame.
* Off by default. This may result in legit messages near the error being * 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 * dropped as well. It may free up resources otherwise spent dealing with
* misbehaving clients. * misbehaving clients.
*/ */
static const bool drop_on_protocol_error = false; static const bool drop_on_protocol_error = false;
/// Suppresses the return of detailed connection close information /// Suppresses the return of detailed connection close information
/** /**
* Silence close suppresses the return of detailed connection close * Silence close suppresses the return of detailed connection close
* information during the closing handshake. This information is useful * information during the closing handshake. This information is useful
* for debugging and presenting useful errors to end users but may be * for debugging and presenting useful errors to end users but may be
* undesirable for security reasons in some production environments. * undesirable for security reasons in some production environments.
* Close reasons could be used by an attacker to confirm that the endpoint * 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 * is out of resources or be used to identify the WebSocket implementation
* in use. * in use.
* *
* Note: this will suppress *all* close codes, including those explicitly * Note: this will suppress *all* close codes, including those explicitly
* sent by local applications. * sent by local applications.
*/ */
static const bool silent_close = false; static const bool silent_close = false;
/// Default maximum message size /// Default maximum message size
/** /**
* Default value for the processor's maximum message size. 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 * determines the point at which the library will fail a connection with the
* message_too_big protocol error. * message_too_big protocol error.
* *
* The default is 32MB * The default is 32MB
* *
* @since 0.3.0 * @since 0.3.0
*/ */
static const size_t max_message_size = 32000000; static const size_t max_message_size = 32000000;
/// Default maximum http body size /// Default maximum http body size
/** /**
* Default value for the http parser's maximum body size. Maximum 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 * determines the point at which the library will abort reading an HTTP
* connection with the 413/request entity too large error. * connection with the 413/request entity too large error.
* *
* The default is 32MB * The default is 32MB
* *
* @since 0.5.0 * @since 0.5.0
*/ */
static const size_t max_http_body_size = 32000000; static const size_t max_http_body_size = 32000000;
/// Global flag for enabling/disabling extensions /// Global flag for enabling/disabling extensions
static const bool enable_extensions = true; static const bool enable_extensions = true;
/// Extension specific settings: /// Extension specific settings:
/// permessage_compress extension /// permessage_compress extension
struct permessage_deflate_config { struct permessage_deflate_config {
typedef type::request_type request_type; typedef type::request_type request_type;
/// If the remote endpoint requests that we reset the compression /// If the remote endpoint requests that we reset the compression
/// context after each message should we honor the request? /// context after each message should we honor the request?
static const bool allow_disabling_context_takeover = true; static const bool allow_disabling_context_takeover = true;
/// If the remote endpoint requests that we reduce the size of the /// If the remote endpoint requests that we reduce the size of the
/// LZ77 sliding window size this is the lowest value that will be /// 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 /// 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 /// allow any possible window size. A value of 15 means do not allow
/// negotiation of the window size (ie require the default). /// negotiation of the window size (ie require the default).
static const uint8_t minimum_outgoing_window_bits = 8; static const uint8_t minimum_outgoing_window_bits = 8;
}; };
typedef websocketpp::extensions::permessage_deflate::disabled typedef websocketpp::extensions::permessage_deflate::disabled
<permessage_deflate_config> permessage_deflate_type; <permessage_deflate_config> permessage_deflate_type;
/// Autonegotiate permessage-deflate /// Autonegotiate permessage-deflate
/** /**
* Automatically enables the permessage-deflate extension. * Automatically enables the permessage-deflate extension.
* *
* For clients this results in a permessage-deflate extension request being * For clients this results in a permessage-deflate extension request being
* sent with every request rather than requiring it to be requested manually * sent with every request rather than requiring it to be requested manually
* *
* For servers this results in accepting the first set of extension settings * For servers this results in accepting the first set of extension settings
* requested by the client that we understand being used. The alternative is * requested by the client that we understand being used. The alternative is
* requiring the extension to be manually negotiated in `validate`. With * requiring the extension to be manually negotiated in `validate`. With
* auto-negotiate on, you may still override the auto-negotiate manually if * auto-negotiate on, you may still override the auto-negotiate manually if
* needed. * needed.
*/ */
//static const bool autonegotiate_compression = false; //static const bool autonegotiate_compression = false;
}; };
} // namespace config } // namespace config
} // namespace websocketpp } // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_CORE_HPP #endif // WEBSOCKETPP_CONFIG_CORE_HPP

View File

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

View File

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

View File

@@ -1,72 +1,72 @@
/* /*
* Copyright (c) 2014, Peter Thorson. All rights reserved. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP #ifndef WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP
#define WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP #define WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP
#include <websocketpp/config/minimal_server.hpp> #include <websocketpp/config/minimal_server.hpp>
namespace websocketpp { namespace websocketpp {
namespace config { namespace config {
/// Client config with minimal dependencies /// Client config with minimal dependencies
/** /**
* This config strips out as many dependencies as possible. It is suitable for * 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 * 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. * own policies for components that even the core config includes.
* *
* NOTE: this config stubs out enough that it cannot be used directly. You must * 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 * supply at least a transport policy and a cryptographically secure random
* number generation policy for a config based on `minimal_client` to do * number generation policy for a config based on `minimal_client` to do
* anything useful. * anything useful.
* *
* Present dependency list for minimal_server config: * Present dependency list for minimal_server config:
* *
* C++98 STL: * C++98 STL:
* <algorithm> * <algorithm>
* <map> * <map>
* <sstream> * <sstream>
* <string> * <string>
* <vector> * <vector>
* *
* C++11 STL or Boost * C++11 STL or Boost
* <memory> * <memory>
* <functional> * <functional>
* <system_error> * <system_error>
* *
* Operating System: * Operating System:
* <stdint.h> or <boost/cstdint.hpp> * <stdint.h> or <boost/cstdint.hpp>
* <netinet/in.h> or <winsock2.h> (for ntohl.. could potentially bundle this) * <netinet/in.h> or <winsock2.h> (for ntohl.. could potentially bundle this)
* *
* @since 0.4.0-dev * @since 0.4.0-dev
*/ */
typedef minimal_server minimal_client; typedef minimal_server minimal_client;
} // namespace config } // namespace config
} // namespace websocketpp } // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP #endif // WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP

View File

@@ -1,312 +1,312 @@
/* /*
* Copyright (c) 2014, Peter Thorson. All rights reserved. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef WEBSOCKETPP_CONFIG_MINIMAL_HPP #ifndef WEBSOCKETPP_CONFIG_MINIMAL_HPP
#define WEBSOCKETPP_CONFIG_MINIMAL_HPP #define WEBSOCKETPP_CONFIG_MINIMAL_HPP
// Non-Policy common stuff // Non-Policy common stuff
#include <websocketpp/common/platforms.hpp> #include <websocketpp/common/platforms.hpp>
#include <websocketpp/common/cpp11.hpp> #include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp> #include <websocketpp/common/stdint.hpp>
// Concurrency // Concurrency
#include <websocketpp/concurrency/none.hpp> #include <websocketpp/concurrency/none.hpp>
// Transport // Transport
#include <websocketpp/transport/stub/endpoint.hpp> #include <websocketpp/transport/stub/endpoint.hpp>
// HTTP // HTTP
#include <websocketpp/http/request.hpp> #include <websocketpp/http/request.hpp>
#include <websocketpp/http/response.hpp> #include <websocketpp/http/response.hpp>
// Messages // Messages
#include <websocketpp/message_buffer/message.hpp> #include <websocketpp/message_buffer/message.hpp>
#include <websocketpp/message_buffer/alloc.hpp> #include <websocketpp/message_buffer/alloc.hpp>
// Loggers // Loggers
#include <websocketpp/logger/stub.hpp> #include <websocketpp/logger/stub.hpp>
// RNG // RNG
#include <websocketpp/random/none.hpp> #include <websocketpp/random/none.hpp>
// User stub base classes // User stub base classes
#include <websocketpp/endpoint_base.hpp> #include <websocketpp/endpoint_base.hpp>
#include <websocketpp/connection_base.hpp> #include <websocketpp/connection_base.hpp>
// Extensions // Extensions
#include <websocketpp/extensions/permessage_deflate/disabled.hpp> #include <websocketpp/extensions/permessage_deflate/disabled.hpp>
namespace websocketpp { namespace websocketpp {
namespace config { namespace config {
/// Server config with minimal dependencies /// Server config with minimal dependencies
/** /**
* This config strips out as many dependencies as possible. It is suitable for * 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 * 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. * own policies for components that even the core config includes.
* *
* NOTE: this config stubs out enough that it cannot be used directly. You must * 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 * supply at least a transport policy for a config based on `minimal_server` to
* do anything useful. * do anything useful.
* *
* Present dependency list for minimal_server config: * Present dependency list for minimal_server config:
* *
* C++98 STL: * C++98 STL:
* <algorithm> * <algorithm>
* <map> * <map>
* <sstream> * <sstream>
* <string> * <string>
* <vector> * <vector>
* *
* C++11 STL or Boost * C++11 STL or Boost
* <memory> * <memory>
* <functional> * <functional>
* <system_error> * <system_error>
* *
* Operating System: * Operating System:
* <stdint.h> or <boost/cstdint.hpp> * <stdint.h> or <boost/cstdint.hpp>
* <netinet/in.h> or <winsock2.h> (for ntohl.. could potentially bundle this) * <netinet/in.h> or <winsock2.h> (for ntohl.. could potentially bundle this)
* *
* @since 0.4.0-dev * @since 0.4.0-dev
*/ */
struct minimal_server { struct minimal_server {
typedef minimal_server type; typedef minimal_server type;
// Concurrency policy // Concurrency policy
typedef websocketpp::concurrency::none concurrency_type; typedef websocketpp::concurrency::none concurrency_type;
// HTTP Parser Policies // HTTP Parser Policies
typedef http::parser::request request_type; typedef http::parser::request request_type;
typedef http::parser::response response_type; typedef http::parser::response response_type;
// Message Policies // Message Policies
typedef message_buffer::message<message_buffer::alloc::con_msg_manager> typedef message_buffer::message<message_buffer::alloc::con_msg_manager>
message_type; message_type;
typedef message_buffer::alloc::con_msg_manager<message_type> typedef message_buffer::alloc::con_msg_manager<message_type>
con_msg_manager_type; con_msg_manager_type;
typedef message_buffer::alloc::endpoint_msg_manager<con_msg_manager_type> typedef message_buffer::alloc::endpoint_msg_manager<con_msg_manager_type>
endpoint_msg_manager_type; endpoint_msg_manager_type;
/// Logging policies /// Logging policies
typedef websocketpp::log::stub elog_type; typedef websocketpp::log::stub elog_type;
typedef websocketpp::log::stub alog_type; typedef websocketpp::log::stub alog_type;
/// RNG policies /// RNG policies
typedef websocketpp::random::none::int_generator<uint32_t> rng_type; typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
/// Controls compile time enabling/disabling of thread syncronization /// Controls compile time enabling/disabling of thread syncronization
/// code Disabling can provide a minor performance improvement to single /// code Disabling can provide a minor performance improvement to single
/// threaded applications /// threaded applications
static bool const enable_multithreading = true; static bool const enable_multithreading = true;
struct transport_config { struct transport_config {
typedef type::concurrency_type concurrency_type; typedef type::concurrency_type concurrency_type;
typedef type::elog_type elog_type; typedef type::elog_type elog_type;
typedef type::alog_type alog_type; typedef type::alog_type alog_type;
typedef type::request_type request_type; typedef type::request_type request_type;
typedef type::response_type response_type; typedef type::response_type response_type;
/// Controls compile time enabling/disabling of thread syncronization /// Controls compile time enabling/disabling of thread syncronization
/// code Disabling can provide a minor performance improvement to single /// code Disabling can provide a minor performance improvement to single
/// threaded applications /// threaded applications
static bool const enable_multithreading = true; static bool const enable_multithreading = true;
/// Default timer values (in ms) /// Default timer values (in ms)
/// Length of time to wait for socket pre-initialization /// Length of time to wait for socket pre-initialization
/** /**
* Exactly what this includes depends on the socket policy in use * Exactly what this includes depends on the socket policy in use
*/ */
static const long timeout_socket_pre_init = 5000; static const long timeout_socket_pre_init = 5000;
/// Length of time to wait before a proxy handshake is aborted /// Length of time to wait before a proxy handshake is aborted
static const long timeout_proxy = 5000; static const long timeout_proxy = 5000;
/// Length of time to wait for socket post-initialization /// Length of time to wait for socket post-initialization
/** /**
* Exactly what this includes depends on the socket policy in use. * Exactly what this includes depends on the socket policy in use.
* Often this means the TLS handshake * Often this means the TLS handshake
*/ */
static const long timeout_socket_post_init = 5000; static const long timeout_socket_post_init = 5000;
/// Length of time to wait for dns resolution /// Length of time to wait for dns resolution
static const long timeout_dns_resolve = 5000; static const long timeout_dns_resolve = 5000;
/// Length of time to wait for TCP connect /// Length of time to wait for TCP connect
static const long timeout_connect = 5000; static const long timeout_connect = 5000;
/// Length of time to wait for socket shutdown /// Length of time to wait for socket shutdown
static const long timeout_socket_shutdown = 5000; static const long timeout_socket_shutdown = 5000;
}; };
/// Transport Endpoint Component /// Transport Endpoint Component
typedef websocketpp::transport::stub::endpoint<transport_config> typedef websocketpp::transport::stub::endpoint<transport_config>
transport_type; transport_type;
/// User overridable Endpoint base class /// User overridable Endpoint base class
typedef websocketpp::endpoint_base endpoint_base; typedef websocketpp::endpoint_base endpoint_base;
/// User overridable Connection base class /// User overridable Connection base class
typedef websocketpp::connection_base connection_base; typedef websocketpp::connection_base connection_base;
/// Default timer values (in ms) /// Default timer values (in ms)
/// Length of time before an opening handshake is aborted /// Length of time before an opening handshake is aborted
static const long timeout_open_handshake = 5000; static const long timeout_open_handshake = 5000;
/// Length of time before a closing handshake is aborted /// Length of time before a closing handshake is aborted
static const long timeout_close_handshake = 5000; static const long timeout_close_handshake = 5000;
/// Length of time to wait for a pong after a ping /// Length of time to wait for a pong after a ping
static const long timeout_pong = 5000; static const long timeout_pong = 5000;
/// WebSocket Protocol version to use as a client /// WebSocket Protocol version to use as a client
/** /**
* What version of the WebSocket Protocol to use for outgoing client * What version of the WebSocket Protocol to use for outgoing client
* connections. Setting this to a value other than 13 (RFC6455) is not * connections. Setting this to a value other than 13 (RFC6455) is not
* recommended. * recommended.
*/ */
static const int client_version = 13; // RFC6455 static const int client_version = 13; // RFC6455
/// Default static error logging channels /// Default static error logging channels
/** /**
* Which error logging channels to enable at compile time. Channels not * Which error logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library. * enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely * 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 * code to test whether or not to print out log messages on a certain
* channel * channel
* *
* Default is all except for development/debug level errors * Default is all except for development/debug level errors
*/ */
static const websocketpp::log::level elog_level = static const websocketpp::log::level elog_level =
websocketpp::log::elevel::none; websocketpp::log::elevel::none;
/// Default static access logging channels /// Default static access logging channels
/** /**
* Which access logging channels to enable at compile time. Channels not * Which access logging channels to enable at compile time. Channels not
* enabled here will be unable to be selected by programs using the library. * enabled here will be unable to be selected by programs using the library.
* This option gives an optimizing compiler the ability to remove entirely * 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 * code to test whether or not to print out log messages on a certain
* channel * channel
* *
* Default is all except for development/debug level access messages * Default is all except for development/debug level access messages
*/ */
static const websocketpp::log::level alog_level = static const websocketpp::log::level alog_level =
websocketpp::log::alevel::none; websocketpp::log::alevel::none;
/// ///
static const size_t connection_read_buffer_size = 16384; static const size_t connection_read_buffer_size = 16384;
/// Drop connections immediately on protocol error. /// Drop connections immediately on protocol error.
/** /**
* Drop connections on protocol error rather than sending a close frame. * Drop connections on protocol error rather than sending a close frame.
* Off by default. This may result in legit messages near the error being * 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 * dropped as well. It may free up resources otherwise spent dealing with
* misbehaving clients. * misbehaving clients.
*/ */
static const bool drop_on_protocol_error = false; static const bool drop_on_protocol_error = false;
/// Suppresses the return of detailed connection close information /// Suppresses the return of detailed connection close information
/** /**
* Silence close suppresses the return of detailed connection close * Silence close suppresses the return of detailed connection close
* information during the closing handshake. This information is useful * information during the closing handshake. This information is useful
* for debugging and presenting useful errors to end users but may be * for debugging and presenting useful errors to end users but may be
* undesirable for security reasons in some production environments. * undesirable for security reasons in some production environments.
* Close reasons could be used by an attacker to confirm that the endpoint * 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 * is out of resources or be used to identify the WebSocket implementation
* in use. * in use.
* *
* Note: this will suppress *all* close codes, including those explicitly * Note: this will suppress *all* close codes, including those explicitly
* sent by local applications. * sent by local applications.
*/ */
static const bool silent_close = false; static const bool silent_close = false;
/// Default maximum message size /// Default maximum message size
/** /**
* Default value for the processor's maximum message size. 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 * determines the point at which the library will fail a connection with the
* message_too_big protocol error. * message_too_big protocol error.
* *
* The default is 32MB * The default is 32MB
* *
* @since 0.4.0-alpha1 * @since 0.4.0-alpha1
*/ */
static const size_t max_message_size = 32000000; static const size_t max_message_size = 32000000;
/// Default maximum http body size /// Default maximum http body size
/** /**
* Default value for the http parser's maximum body size. Maximum 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 * determines the point at which the library will abort reading an HTTP
* connection with the 413/request entity too large error. * connection with the 413/request entity too large error.
* *
* The default is 32MB * The default is 32MB
* *
* @since 0.5.0 * @since 0.5.0
*/ */
static const size_t max_http_body_size = 32000000; static const size_t max_http_body_size = 32000000;
/// Global flag for enabling/disabling extensions /// Global flag for enabling/disabling extensions
static const bool enable_extensions = true; static const bool enable_extensions = true;
/// Extension specific settings: /// Extension specific settings:
/// permessage_compress extension /// permessage_compress extension
struct permessage_deflate_config { struct permessage_deflate_config {
typedef core::request_type request_type; typedef core::request_type request_type;
/// If the remote endpoint requests that we reset the compression /// If the remote endpoint requests that we reset the compression
/// context after each message should we honor the request? /// context after each message should we honor the request?
static const bool allow_disabling_context_takeover = true; static const bool allow_disabling_context_takeover = true;
/// If the remote endpoint requests that we reduce the size of the /// If the remote endpoint requests that we reduce the size of the
/// LZ77 sliding window size this is the lowest value that will be /// 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 /// 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 /// allow any possible window size. A value of 15 means do not allow
/// negotiation of the window size (ie require the default). /// negotiation of the window size (ie require the default).
static const uint8_t minimum_outgoing_window_bits = 8; static const uint8_t minimum_outgoing_window_bits = 8;
}; };
typedef websocketpp::extensions::permessage_deflate::disabled typedef websocketpp::extensions::permessage_deflate::disabled
<permessage_deflate_config> permessage_deflate_type; <permessage_deflate_config> permessage_deflate_type;
/// Autonegotiate permessage-deflate /// Autonegotiate permessage-deflate
/** /**
* Automatically enables the permessage-deflate extension. * Automatically enables the permessage-deflate extension.
* *
* For clients this results in a permessage-deflate extension request being * For clients this results in a permessage-deflate extension request being
* sent with every request rather than requiring it to be requested manually * sent with every request rather than requiring it to be requested manually
* *
* For servers this results in accepting the first set of extension settings * For servers this results in accepting the first set of extension settings
* requested by the client that we understand being used. The alternative is * requested by the client that we understand being used. The alternative is
* requiring the extension to be manually negotiated in `validate`. With * requiring the extension to be manually negotiated in `validate`. With
* auto-negotiate on, you may still override the auto-negotiate manually if * auto-negotiate on, you may still override the auto-negotiate manually if
* needed. * needed.
*/ */
//static const bool autonegotiate_compression = false; //static const bool autonegotiate_compression = false;
}; };
} // namespace config } // namespace config
} // namespace websocketpp } // namespace websocketpp
#endif // WEBSOCKETPP_CONFIG_MINIMAL_HPP #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. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef WEBSOCKETPP_CONNECTION_BASE_HPP #ifndef WEBSOCKETPP_CONNECTION_BASE_HPP
#define WEBSOCKETPP_CONNECTION_BASE_HPP #define WEBSOCKETPP_CONNECTION_BASE_HPP
namespace websocketpp { namespace websocketpp {
/// Stub for user supplied base class. /// Stub for user supplied base class.
class connection_base {}; class connection_base {};
} // namespace websocketpp } // namespace websocketpp
#endif // WEBSOCKETPP_CONNECTION_BASE_HPP #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. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef WEBSOCKETPP_ENDPOINT_BASE_HPP #ifndef WEBSOCKETPP_ENDPOINT_BASE_HPP
#define WEBSOCKETPP_ENDPOINT_BASE_HPP #define WEBSOCKETPP_ENDPOINT_BASE_HPP
namespace websocketpp { namespace websocketpp {
/// Stub for user supplied base class. /// Stub for user supplied base class.
class endpoint_base {}; class endpoint_base {};
} // namespace websocketpp } // namespace websocketpp
#endif // WEBSOCKETPP_ENDPOINT_BASE_HPP #endif // WEBSOCKETPP_ENDPOINT_BASE_HPP

View File

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

View File

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

View File

@@ -1,129 +1,129 @@
/* /*
* Copyright (c) 2014, Peter Thorson. All rights reserved. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP #ifndef WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP
#define WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP #define WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP
#include <websocketpp/common/cpp11.hpp> #include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp> #include <websocketpp/common/stdint.hpp>
#include <websocketpp/common/system_error.hpp> #include <websocketpp/common/system_error.hpp>
#include <websocketpp/http/constants.hpp> #include <websocketpp/http/constants.hpp>
#include <websocketpp/extensions/extension.hpp> #include <websocketpp/extensions/extension.hpp>
#include <map> #include <map>
#include <string> #include <string>
#include <utility> #include <utility>
namespace websocketpp { namespace websocketpp {
namespace extensions { namespace extensions {
namespace permessage_deflate { namespace permessage_deflate {
/// Stub class for use when disabling permessage_deflate extension /// Stub class for use when disabling permessage_deflate extension
/** /**
* This class is a stub that implements the permessage_deflate interface * This class is a stub that implements the permessage_deflate interface
* with minimal dependencies. It is used to disable permessage_deflate * with minimal dependencies. It is used to disable permessage_deflate
* functionality at compile time without loading any unnecessary code. * functionality at compile time without loading any unnecessary code.
*/ */
template <typename config> template <typename config>
class disabled { class disabled {
typedef std::pair<lib::error_code,std::string> err_str_pair; typedef std::pair<lib::error_code,std::string> err_str_pair;
public: public:
/// Negotiate extension /// Negotiate extension
/** /**
* The disabled extension always fails the negotiation with a disabled * The disabled extension always fails the negotiation with a disabled
* error. * error.
* *
* @param offer Attribute from client's offer * @param offer Attribute from client's offer
* @return Status code and value to return to remote endpoint * @return Status code and value to return to remote endpoint
*/ */
err_str_pair negotiate(http::attribute_list const &) { err_str_pair negotiate(http::attribute_list const &) {
return make_pair(make_error_code(error::disabled),std::string()); return make_pair(make_error_code(error::disabled),std::string());
} }
/// Initialize state /// Initialize state
/** /**
* For the disabled extension state initialization is a no-op. * For the disabled extension state initialization is a no-op.
* *
* @param is_server True to initialize as a server, false for a client. * @param is_server True to initialize as a server, false for a client.
* @return A code representing the error that occurred, if any * @return A code representing the error that occurred, if any
*/ */
lib::error_code init(bool) { lib::error_code init(bool) {
return lib::error_code(); return lib::error_code();
} }
/// Returns true if the extension is capable of providing /// Returns true if the extension is capable of providing
/// permessage_deflate functionality /// permessage_deflate functionality
bool is_implemented() const { bool is_implemented() const {
return false; return false;
} }
/// Returns true if permessage_deflate functionality is active for this /// Returns true if permessage_deflate functionality is active for this
/// connection /// connection
bool is_enabled() const { bool is_enabled() const {
return false; return false;
} }
/// Generate extension offer /// Generate extension offer
/** /**
* Creates an offer string to include in the Sec-WebSocket-Extensions * Creates an offer string to include in the Sec-WebSocket-Extensions
* header of outgoing client requests. * header of outgoing client requests.
* *
* @return A WebSocket extension offer string for this extension * @return A WebSocket extension offer string for this extension
*/ */
std::string generate_offer() const { std::string generate_offer() const {
return ""; return "";
} }
/// Compress bytes /// Compress bytes
/** /**
* @param [in] in String to compress * @param [in] in String to compress
* @param [out] out String to append compressed bytes to * @param [out] out String to append compressed bytes to
* @return Error or status code * @return Error or status code
*/ */
lib::error_code compress(std::string const &, std::string &) { lib::error_code compress(std::string const &, std::string &) {
return make_error_code(error::disabled); return make_error_code(error::disabled);
} }
/// Decompress bytes /// Decompress bytes
/** /**
* @param buf Byte buffer to decompress * @param buf Byte buffer to decompress
* @param len Length of buf * @param len Length of buf
* @param out String to append decompressed bytes to * @param out String to append decompressed bytes to
* @return Error or status code * @return Error or status code
*/ */
lib::error_code decompress(uint8_t const *, size_t, std::string &) { lib::error_code decompress(uint8_t const *, size_t, std::string &) {
return make_error_code(error::disabled); return make_error_code(error::disabled);
} }
}; };
} // namespace permessage_deflate } // namespace permessage_deflate
} // namespace extensions } // namespace extensions
} // namespace websocketpp } // namespace websocketpp
#endif // WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP #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. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef HTTP_CONSTANTS_HPP #ifndef HTTP_CONSTANTS_HPP
#define HTTP_CONSTANTS_HPP #define HTTP_CONSTANTS_HPP
#include <exception> #include <exception>
#include <map> #include <map>
#include <string> #include <string>
#include <vector> #include <vector>
#include <utility> #include <utility>
namespace websocketpp { namespace websocketpp {
/// HTTP handling support /// HTTP handling support
namespace http { namespace http {
/// The type of an HTTP attribute list /// The type of an HTTP attribute list
/** /**
* The attribute list is an unordered key/value map. Encoded attribute * The attribute list is an unordered key/value map. Encoded attribute
* values are delimited by semicolons. * values are delimited by semicolons.
*/ */
typedef std::map<std::string,std::string> attribute_list; typedef std::map<std::string,std::string> attribute_list;
/// The type of an HTTP parameter list /// The type of an HTTP parameter list
/** /**
* The parameter list is an ordered pairing of a parameter and its * The parameter list is an ordered pairing of a parameter and its
* associated attribute list. Encoded parameter values are delimited by * associated attribute list. Encoded parameter values are delimited by
* commas. * commas.
*/ */
typedef std::vector< std::pair<std::string,attribute_list> > parameter_list; typedef std::vector< std::pair<std::string,attribute_list> > parameter_list;
/// Literal value of the HTTP header delimiter /// Literal value of the HTTP header delimiter
static char const header_delimiter[] = "\r\n"; static char const header_delimiter[] = "\r\n";
/// Literal value of the HTTP header separator /// Literal value of the HTTP header separator
static char const header_separator[] = ":"; static char const header_separator[] = ":";
/// Literal value of an empty header /// Literal value of an empty header
static std::string const empty_header; static std::string const empty_header;
/// Maximum size in bytes before rejecting an HTTP header as too big. /// Maximum size in bytes before rejecting an HTTP header as too big.
size_t const max_header_size = 16000; size_t const max_header_size = 16000;
/// Default Maximum size in bytes for HTTP message bodies. /// Default Maximum size in bytes for HTTP message bodies.
size_t const max_body_size = 32000000; size_t const max_body_size = 32000000;
/// Number of bytes to use for temporary istream read buffers /// Number of bytes to use for temporary istream read buffers
size_t const istream_buffer = 512; size_t const istream_buffer = 512;
/// invalid HTTP token characters /// invalid HTTP token characters
/** /**
* 0x00 - 0x32, 0x7f-0xff * 0x00 - 0x32, 0x7f-0xff
* ( ) < > @ , ; : \ " / [ ] ? = { } * ( ) < > @ , ; : \ " / [ ] ? = { }
*/ */
static char const header_token[] = { 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, // 00..0f
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10..1f 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 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 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 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,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,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 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, // 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, // 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, // 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, // 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, // 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, // 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, // e0..ef
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff
}; };
/// Is the character a token /// Is the character a token
inline bool is_token_char(unsigned char c) { inline bool is_token_char(unsigned char c) {
return (header_token[c] == 1); return (header_token[c] == 1);
} }
/// Is the character a non-token /// Is the character a non-token
inline bool is_not_token_char(unsigned char c) { inline bool is_not_token_char(unsigned char c) {
return !header_token[c]; return !header_token[c];
} }
/// Is the character whitespace /// Is the character whitespace
/** /**
* whitespace is space (32) or horizontal tab (9) * whitespace is space (32) or horizontal tab (9)
*/ */
inline bool is_whitespace_char(unsigned char c) { inline bool is_whitespace_char(unsigned char c) {
return (c == 9 || c == 32); return (c == 9 || c == 32);
} }
/// Is the character non-whitespace /// Is the character non-whitespace
inline bool is_not_whitespace_char(unsigned char c) { inline bool is_not_whitespace_char(unsigned char c) {
return (c != 9 && c != 32); return (c != 9 && c != 32);
} }
/// HTTP Status codes /// HTTP Status codes
namespace status_code { namespace status_code {
enum value { enum value {
uninitialized = 0, uninitialized = 0,
continue_code = 100, continue_code = 100,
switching_protocols = 101, switching_protocols = 101,
ok = 200, ok = 200,
created = 201, created = 201,
accepted = 202, accepted = 202,
non_authoritative_information = 203, non_authoritative_information = 203,
no_content = 204, no_content = 204,
reset_content = 205, reset_content = 205,
partial_content = 206, partial_content = 206,
multiple_choices = 300, multiple_choices = 300,
moved_permanently = 301, moved_permanently = 301,
found = 302, found = 302,
see_other = 303, see_other = 303,
not_modified = 304, not_modified = 304,
use_proxy = 305, use_proxy = 305,
temporary_redirect = 307, temporary_redirect = 307,
bad_request = 400, bad_request = 400,
unauthorized = 401, unauthorized = 401,
payment_required = 402, payment_required = 402,
forbidden = 403, forbidden = 403,
not_found = 404, not_found = 404,
method_not_allowed = 405, method_not_allowed = 405,
not_acceptable = 406, not_acceptable = 406,
proxy_authentication_required = 407, proxy_authentication_required = 407,
request_timeout = 408, request_timeout = 408,
conflict = 409, conflict = 409,
gone = 410, gone = 410,
length_required = 411, length_required = 411,
precondition_failed = 412, precondition_failed = 412,
request_entity_too_large = 413, request_entity_too_large = 413,
request_uri_too_long = 414, request_uri_too_long = 414,
unsupported_media_type = 415, unsupported_media_type = 415,
request_range_not_satisfiable = 416, request_range_not_satisfiable = 416,
expectation_failed = 417, expectation_failed = 417,
im_a_teapot = 418, im_a_teapot = 418,
upgrade_required = 426, upgrade_required = 426,
precondition_required = 428, precondition_required = 428,
too_many_requests = 429, too_many_requests = 429,
request_header_fields_too_large = 431, request_header_fields_too_large = 431,
internal_server_error = 500, internal_server_error = 500,
not_implemented = 501, not_implemented = 501,
bad_gateway = 502, bad_gateway = 502,
service_unavailable = 503, service_unavailable = 503,
gateway_timeout = 504, gateway_timeout = 504,
http_version_not_supported = 505, http_version_not_supported = 505,
not_extended = 510, not_extended = 510,
network_authentication_required = 511 network_authentication_required = 511
}; };
// TODO: should this be inline? // TODO: should this be inline?
inline std::string get_string(value c) { inline std::string get_string(value c) {
switch (c) { switch (c) {
case uninitialized: case uninitialized:
return "Uninitialized"; return "Uninitialized";
case continue_code: case continue_code:
return "Continue"; return "Continue";
case switching_protocols: case switching_protocols:
return "Switching Protocols"; return "Switching Protocols";
case ok: case ok:
return "OK"; return "OK";
case created: case created:
return "Created"; return "Created";
case accepted: case accepted:
return "Accepted"; return "Accepted";
case non_authoritative_information: case non_authoritative_information:
return "Non Authoritative Information"; return "Non Authoritative Information";
case no_content: case no_content:
return "No Content"; return "No Content";
case reset_content: case reset_content:
return "Reset Content"; return "Reset Content";
case partial_content: case partial_content:
return "Partial Content"; return "Partial Content";
case multiple_choices: case multiple_choices:
return "Multiple Choices"; return "Multiple Choices";
case moved_permanently: case moved_permanently:
return "Moved Permanently"; return "Moved Permanently";
case found: case found:
return "Found"; return "Found";
case see_other: case see_other:
return "See Other"; return "See Other";
case not_modified: case not_modified:
return "Not Modified"; return "Not Modified";
case use_proxy: case use_proxy:
return "Use Proxy"; return "Use Proxy";
case temporary_redirect: case temporary_redirect:
return "Temporary Redirect"; return "Temporary Redirect";
case bad_request: case bad_request:
return "Bad Request"; return "Bad Request";
case unauthorized: case unauthorized:
return "Unauthorized"; return "Unauthorized";
case payment_required: case payment_required:
return "Payment Required"; return "Payment Required";
case forbidden: case forbidden:
return "Forbidden"; return "Forbidden";
case not_found: case not_found:
return "Not Found"; return "Not Found";
case method_not_allowed: case method_not_allowed:
return "Method Not Allowed"; return "Method Not Allowed";
case not_acceptable: case not_acceptable:
return "Not Acceptable"; return "Not Acceptable";
case proxy_authentication_required: case proxy_authentication_required:
return "Proxy Authentication Required"; return "Proxy Authentication Required";
case request_timeout: case request_timeout:
return "Request Timeout"; return "Request Timeout";
case conflict: case conflict:
return "Conflict"; return "Conflict";
case gone: case gone:
return "Gone"; return "Gone";
case length_required: case length_required:
return "Length Required"; return "Length Required";
case precondition_failed: case precondition_failed:
return "Precondition Failed"; return "Precondition Failed";
case request_entity_too_large: case request_entity_too_large:
return "Request Entity Too Large"; return "Request Entity Too Large";
case request_uri_too_long: case request_uri_too_long:
return "Request-URI Too Long"; return "Request-URI Too Long";
case unsupported_media_type: case unsupported_media_type:
return "Unsupported Media Type"; return "Unsupported Media Type";
case request_range_not_satisfiable: case request_range_not_satisfiable:
return "Requested Range Not Satisfiable"; return "Requested Range Not Satisfiable";
case expectation_failed: case expectation_failed:
return "Expectation Failed"; return "Expectation Failed";
case im_a_teapot: case im_a_teapot:
return "I'm a teapot"; return "I'm a teapot";
case upgrade_required: case upgrade_required:
return "Upgrade Required"; return "Upgrade Required";
case precondition_required: case precondition_required:
return "Precondition Required"; return "Precondition Required";
case too_many_requests: case too_many_requests:
return "Too Many Requests"; return "Too Many Requests";
case request_header_fields_too_large: case request_header_fields_too_large:
return "Request Header Fields Too Large"; return "Request Header Fields Too Large";
case internal_server_error: case internal_server_error:
return "Internal Server Error"; return "Internal Server Error";
case not_implemented: case not_implemented:
return "Not Implemented"; return "Not Implemented";
case bad_gateway: case bad_gateway:
return "Bad Gateway"; return "Bad Gateway";
case service_unavailable: case service_unavailable:
return "Service Unavailable"; return "Service Unavailable";
case gateway_timeout: case gateway_timeout:
return "Gateway Timeout"; return "Gateway Timeout";
case http_version_not_supported: case http_version_not_supported:
return "HTTP Version Not Supported"; return "HTTP Version Not Supported";
case not_extended: case not_extended:
return "Not Extended"; return "Not Extended";
case network_authentication_required: case network_authentication_required:
return "Network Authentication Required"; return "Network Authentication Required";
default: default:
return "Unknown"; return "Unknown";
} }
} }
} }
class exception : public std::exception { class exception : public std::exception {
public: public:
exception(const std::string& log_msg, exception(const std::string& log_msg,
status_code::value error_code, status_code::value error_code,
const std::string& error_msg = std::string(), const std::string& error_msg = std::string(),
const std::string& body = std::string()) const std::string& body = std::string())
: m_msg(log_msg) : m_msg(log_msg)
, m_error_msg(error_msg) , m_error_msg(error_msg)
, m_body(body) , m_body(body)
, m_error_code(error_code) {} , m_error_code(error_code) {}
~exception() throw() {} ~exception() throw() {}
virtual const char* what() const throw() { virtual const char* what() const throw() {
return m_msg.c_str(); return m_msg.c_str();
} }
std::string m_msg; std::string m_msg;
std::string m_error_msg; std::string m_error_msg;
std::string m_body; std::string m_body;
status_code::value m_error_code; status_code::value m_error_code;
}; };
} }
} }
#endif // HTTP_CONSTANTS_HPP #endif // HTTP_CONSTANTS_HPP

View File

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

View File

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

View File

@@ -1,266 +1,266 @@
/* /*
* Copyright (c) 2014, Peter Thorson. All rights reserved. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef HTTP_PARSER_RESPONSE_IMPL_HPP #ifndef HTTP_PARSER_RESPONSE_IMPL_HPP
#define HTTP_PARSER_RESPONSE_IMPL_HPP #define HTTP_PARSER_RESPONSE_IMPL_HPP
#include <algorithm> #include <algorithm>
#include <istream> #include <istream>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <websocketpp/http/parser.hpp> #include <websocketpp/http/parser.hpp>
namespace websocketpp { namespace websocketpp {
namespace http { namespace http {
namespace parser { namespace parser {
inline size_t response::consume(char const * buf, size_t len) { inline size_t response::consume(char const * buf, size_t len) {
if (m_state == DONE) {return 0;} if (m_state == DONE) {return 0;}
if (m_state == BODY) { if (m_state == BODY) {
return this->process_body(buf,len); return this->process_body(buf,len);
} }
// copy new header bytes into buffer // copy new header bytes into buffer
m_buf->append(buf,len); m_buf->append(buf,len);
// Search for delimiter in buf. If found read until then. If not read all // Search for delimiter in buf. If found read until then. If not read all
std::string::iterator begin = m_buf->begin(); std::string::iterator begin = m_buf->begin();
std::string::iterator end = begin; std::string::iterator end = begin;
for (;;) { for (;;) {
// search for delimiter // search for delimiter
end = std::search( end = std::search(
begin, begin,
m_buf->end(), m_buf->end(),
header_delimiter, header_delimiter,
header_delimiter + sizeof(header_delimiter) - 1 header_delimiter + sizeof(header_delimiter) - 1
); );
m_header_bytes += (end-begin+sizeof(header_delimiter)); m_header_bytes += (end-begin+sizeof(header_delimiter));
if (m_header_bytes > max_header_size) { if (m_header_bytes > max_header_size) {
// exceeded max header size // exceeded max header size
throw exception("Maximum header size exceeded.", throw exception("Maximum header size exceeded.",
status_code::request_header_fields_too_large); status_code::request_header_fields_too_large);
} }
if (end == m_buf->end()) { if (end == m_buf->end()) {
// we are out of bytes. Discard the processed bytes and copy the // we are out of bytes. Discard the processed bytes and copy the
// remaining unprecessed bytes to the beginning of the buffer // remaining unprecessed bytes to the beginning of the buffer
std::copy(begin,end,m_buf->begin()); std::copy(begin,end,m_buf->begin());
m_buf->resize(static_cast<std::string::size_type>(end-begin)); m_buf->resize(static_cast<std::string::size_type>(end-begin));
m_read += len; m_read += len;
m_header_bytes -= m_buf->size(); m_header_bytes -= m_buf->size();
return len; return len;
} }
//the range [begin,end) now represents a line to be processed. //the range [begin,end) now represents a line to be processed.
if (end-begin == 0) { if (end-begin == 0) {
// we got a blank line // we got a blank line
if (m_state == RESPONSE_LINE) { if (m_state == RESPONSE_LINE) {
throw exception("Incomplete Request",status_code::bad_request); throw exception("Incomplete Request",status_code::bad_request);
} }
// TODO: grab content-length // TODO: grab content-length
std::string length = get_header("Content-Length"); std::string length = get_header("Content-Length");
if (length.empty()) { if (length.empty()) {
// no content length found, read indefinitely // no content length found, read indefinitely
m_read = 0; m_read = 0;
} else { } else {
std::istringstream ss(length); std::istringstream ss(length);
if ((ss >> m_read).fail()) { if ((ss >> m_read).fail()) {
throw exception("Unable to parse Content-Length header", throw exception("Unable to parse Content-Length header",
status_code::bad_request); status_code::bad_request);
} }
} }
m_state = BODY; m_state = BODY;
// calc header bytes processed (starting bytes - bytes left) // calc header bytes processed (starting bytes - bytes left)
size_t read = ( size_t read = (
len - static_cast<std::string::size_type>(m_buf->end() - end) len - static_cast<std::string::size_type>(m_buf->end() - end)
+ sizeof(header_delimiter) - 1 + sizeof(header_delimiter) - 1
); );
// if there were bytes left process them as body bytes // if there were bytes left process them as body bytes
if (read < len) { if (read < len) {
read += this->process_body(buf+read,(len-read)); read += this->process_body(buf+read,(len-read));
} }
// frees memory used temporarily during header parsing // frees memory used temporarily during header parsing
m_buf.reset(); m_buf.reset();
return read; return read;
} else { } else {
if (m_state == RESPONSE_LINE) { if (m_state == RESPONSE_LINE) {
this->process(begin,end); this->process(begin,end);
m_state = HEADERS; m_state = HEADERS;
} else { } else {
this->process_header(begin,end); this->process_header(begin,end);
} }
} }
begin = end+(sizeof(header_delimiter) - 1); begin = end+(sizeof(header_delimiter) - 1);
} }
} }
inline size_t response::consume(std::istream & s) { inline size_t response::consume(std::istream & s) {
char buf[istream_buffer]; char buf[istream_buffer];
size_t bytes_read; size_t bytes_read;
size_t bytes_processed; size_t bytes_processed;
size_t total = 0; size_t total = 0;
while (s.good()) { while (s.good()) {
s.getline(buf,istream_buffer); s.getline(buf,istream_buffer);
bytes_read = static_cast<size_t>(s.gcount()); bytes_read = static_cast<size_t>(s.gcount());
if (s.fail() || s.eof()) { if (s.fail() || s.eof()) {
bytes_processed = this->consume(buf,bytes_read); bytes_processed = this->consume(buf,bytes_read);
total += bytes_processed; total += bytes_processed;
if (bytes_processed != bytes_read) { if (bytes_processed != bytes_read) {
// problem // problem
break; break;
} }
} else if (s.bad()) { } else if (s.bad()) {
// problem // problem
break; break;
} else { } else {
// the delimiting newline was found. Replace the trailing null with // the delimiting newline was found. Replace the trailing null with
// the newline that was discarded, since our raw consume function // the newline that was discarded, since our raw consume function
// expects the newline to be be there. // expects the newline to be be there.
buf[bytes_read-1] = '\n'; buf[bytes_read-1] = '\n';
bytes_processed = this->consume(buf,bytes_read); bytes_processed = this->consume(buf,bytes_read);
total += bytes_processed; total += bytes_processed;
if (bytes_processed != bytes_read) { if (bytes_processed != bytes_read) {
// problem // problem
break; break;
} }
} }
} }
return total; return total;
} }
inline std::string response::raw() const { inline std::string response::raw() const {
// TODO: validation. Make sure all required fields have been set? // TODO: validation. Make sure all required fields have been set?
std::stringstream ret; std::stringstream ret;
ret << get_version() << " " << m_status_code << " " << m_status_msg; ret << get_version() << " " << m_status_code << " " << m_status_msg;
ret << "\r\n" << raw_headers() << "\r\n"; ret << "\r\n" << raw_headers() << "\r\n";
ret << m_body; ret << m_body;
return ret.str(); return ret.str();
} }
inline void response::set_status(status_code::value code) { inline void response::set_status(status_code::value code) {
// TODO: validation? // TODO: validation?
m_status_code = code; m_status_code = code;
m_status_msg = get_string(code); m_status_msg = get_string(code);
} }
inline void response::set_status(status_code::value code, std::string const & inline void response::set_status(status_code::value code, std::string const &
msg) msg)
{ {
// TODO: validation? // TODO: validation?
m_status_code = code; m_status_code = code;
m_status_msg = msg; m_status_msg = msg;
} }
inline void response::process(std::string::iterator begin, inline void response::process(std::string::iterator begin,
std::string::iterator end) std::string::iterator end)
{ {
std::string::iterator cursor_start = begin; std::string::iterator cursor_start = begin;
std::string::iterator cursor_end = std::find(begin,end,' '); std::string::iterator cursor_end = std::find(begin,end,' ');
if (cursor_end == end) { if (cursor_end == end) {
throw exception("Invalid response line",status_code::bad_request); throw exception("Invalid response line",status_code::bad_request);
} }
set_version(std::string(cursor_start,cursor_end)); set_version(std::string(cursor_start,cursor_end));
cursor_start = cursor_end+1; cursor_start = cursor_end+1;
cursor_end = std::find(cursor_start,end,' '); cursor_end = std::find(cursor_start,end,' ');
if (cursor_end == end) { if (cursor_end == end) {
throw exception("Invalid request line",status_code::bad_request); throw exception("Invalid request line",status_code::bad_request);
} }
int code; int code;
std::istringstream ss(std::string(cursor_start,cursor_end)); std::istringstream ss(std::string(cursor_start,cursor_end));
if ((ss >> code).fail()) { if ((ss >> code).fail()) {
throw exception("Unable to parse response code",status_code::bad_request); throw exception("Unable to parse response code",status_code::bad_request);
} }
set_status(status_code::value(code),std::string(cursor_end+1,end)); set_status(status_code::value(code),std::string(cursor_end+1,end));
} }
inline size_t response::process_body(char const * buf, size_t len) { 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 no content length was set then we read forever and never set m_ready
if (m_read == 0) { if (m_read == 0) {
//m_body.append(buf,len); //m_body.append(buf,len);
//return len; //return len;
m_state = DONE; m_state = DONE;
return 0; return 0;
} }
// Otherwise m_read is the number of bytes left. // Otherwise m_read is the number of bytes left.
size_t to_read; size_t to_read;
if (len >= m_read) { if (len >= m_read) {
// if we have more bytes than we need read, read only the amount needed // if we have more bytes than we need read, read only the amount needed
// then set done state // then set done state
to_read = m_read; to_read = m_read;
m_state = DONE; m_state = DONE;
} else { } else {
// we need more bytes than are available, read them all // we need more bytes than are available, read them all
to_read = len; to_read = len;
} }
m_body.append(buf,to_read); m_body.append(buf,to_read);
m_read -= to_read; m_read -= to_read;
return to_read; return to_read;
} }
} // namespace parser } // namespace parser
} // namespace http } // namespace http
} // namespace websocketpp } // namespace websocketpp
#endif // HTTP_PARSER_RESPONSE_IMPL_HPP #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. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef HTTP_PARSER_REQUEST_HPP #ifndef HTTP_PARSER_REQUEST_HPP
#define HTTP_PARSER_REQUEST_HPP #define HTTP_PARSER_REQUEST_HPP
#include <string> #include <string>
#include <websocketpp/common/memory.hpp> #include <websocketpp/common/memory.hpp>
#include <websocketpp/http/parser.hpp> #include <websocketpp/http/parser.hpp>
namespace websocketpp { namespace websocketpp {
namespace http { namespace http {
namespace parser { namespace parser {
/// Stores, parses, and manipulates HTTP requests /// Stores, parses, and manipulates HTTP requests
/** /**
* http::request provides the following functionality for working with HTTP * http::request provides the following functionality for working with HTTP
* requests. * requests.
* *
* - Initialize request via manually setting each element * - Initialize request via manually setting each element
* - Initialize request via reading raw bytes and parsing * - Initialize request via reading raw bytes and parsing
* - Once initialized, access individual parsed elements * - Once initialized, access individual parsed elements
* - Once initialized, read entire request as raw bytes * - Once initialized, read entire request as raw bytes
*/ */
class request : public parser { class request : public parser {
public: public:
typedef request type; typedef request type;
typedef lib::shared_ptr<type> ptr; typedef lib::shared_ptr<type> ptr;
request() request()
: m_buf(lib::make_shared<std::string>()) : m_buf(lib::make_shared<std::string>())
, m_ready(false) {} , m_ready(false) {}
/// Process bytes in the input buffer /// Process bytes in the input buffer
/** /**
* Process up to len bytes from input buffer buf. Returns the number of * Process up to len bytes from input buffer buf. Returns the number of
* bytes processed. Bytes left unprocessed means bytes left over after the * bytes processed. Bytes left unprocessed means bytes left over after the
* final header delimiters. * final header delimiters.
* *
* Consume is a streaming processor. It may be called multiple times on one * 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 * 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 * 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 * the ready flag will be set. Further calls to consume once ready will be
* ignored. * ignored.
* *
* Consume will throw an http::exception in the case of an error. Typical * Consume will throw an http::exception in the case of an error. Typical
* error reasons include malformed requests, incomplete requests, and max * error reasons include malformed requests, incomplete requests, and max
* header size being reached. * header size being reached.
* *
* @param buf Pointer to byte buffer * @param buf Pointer to byte buffer
* @param len Size of byte buffer * @param len Size of byte buffer
* @return Number of bytes processed. * @return Number of bytes processed.
*/ */
size_t consume(char const * buf, size_t len); size_t consume(char const * buf, size_t len);
/// Returns whether or not the request is ready for reading. /// Returns whether or not the request is ready for reading.
bool ready() const { bool ready() const {
return m_ready; return m_ready;
} }
/// Returns the full raw request (including the body) /// Returns the full raw request (including the body)
std::string raw() const; std::string raw() const;
/// Returns the raw request headers only (similar to an HTTP HEAD request) /// Returns the raw request headers only (similar to an HTTP HEAD request)
std::string raw_head() const; std::string raw_head() const;
/// Set the HTTP method. Must be a valid HTTP token /// Set the HTTP method. Must be a valid HTTP token
void set_method(std::string const & method); void set_method(std::string const & method);
/// Return the request method /// Return the request method
std::string const & get_method() const { std::string const & get_method() const {
return m_method; return m_method;
} }
/// Set the HTTP uri. Must be a valid HTTP uri /// Set the HTTP uri. Must be a valid HTTP uri
void set_uri(std::string const & uri); void set_uri(std::string const & uri);
/// Return the requested URI /// Return the requested URI
std::string const & get_uri() const { std::string const & get_uri() const {
return m_uri; return m_uri;
} }
private: private:
/// Helper function for message::consume. Process request line /// Helper function for message::consume. Process request line
void process(std::string::iterator begin, std::string::iterator end); void process(std::string::iterator begin, std::string::iterator end);
lib::shared_ptr<std::string> m_buf; lib::shared_ptr<std::string> m_buf;
std::string m_method; std::string m_method;
std::string m_uri; std::string m_uri;
bool m_ready; bool m_ready;
}; };
} // namespace parser } // namespace parser
} // namespace http } // namespace http
} // namespace websocketpp } // namespace websocketpp
#include <websocketpp/http/impl/request.hpp> #include <websocketpp/http/impl/request.hpp>
#endif // HTTP_PARSER_REQUEST_HPP #endif // HTTP_PARSER_REQUEST_HPP

View File

@@ -1,188 +1,188 @@
/* /*
* Copyright (c) 2014, Peter Thorson. All rights reserved. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef HTTP_PARSER_RESPONSE_HPP #ifndef HTTP_PARSER_RESPONSE_HPP
#define HTTP_PARSER_RESPONSE_HPP #define HTTP_PARSER_RESPONSE_HPP
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <websocketpp/http/parser.hpp> #include <websocketpp/http/parser.hpp>
namespace websocketpp { namespace websocketpp {
namespace http { namespace http {
namespace parser { namespace parser {
/// Stores, parses, and manipulates HTTP responses /// Stores, parses, and manipulates HTTP responses
/** /**
* http::response provides the following functionality for working with HTTP * http::response provides the following functionality for working with HTTP
* responses. * responses.
* *
* - Initialize response via manually setting each element * - Initialize response via manually setting each element
* - Initialize response via reading raw bytes and parsing * - Initialize response via reading raw bytes and parsing
* - Once initialized, access individual parsed elements * - Once initialized, access individual parsed elements
* - Once initialized, read entire response as raw bytes * - Once initialized, read entire response as raw bytes
* *
* http::response checks for header completeness separately from the full * http::response checks for header completeness separately from the full
* response. Once the header is complete, the Content-Length header is read to * 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 * 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 * 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 * consume to determine when the response is complete (ie when the connection
* terminates, or some other metric). * terminates, or some other metric).
*/ */
class response : public parser { class response : public parser {
public: public:
typedef response type; typedef response type;
typedef lib::shared_ptr<type> ptr; typedef lib::shared_ptr<type> ptr;
response() response()
: m_read(0) : m_read(0)
, m_buf(lib::make_shared<std::string>()) , m_buf(lib::make_shared<std::string>())
, m_status_code(status_code::uninitialized) , m_status_code(status_code::uninitialized)
, m_state(RESPONSE_LINE) {} , m_state(RESPONSE_LINE) {}
/// Process bytes in the input buffer /// Process bytes in the input buffer
/** /**
* Process up to len bytes from input buffer buf. Returns the number of * Process up to len bytes from input buffer buf. Returns the number of
* bytes processed. Bytes left unprocessed means bytes left over after the * bytes processed. Bytes left unprocessed means bytes left over after the
* final header delimiters. * final header delimiters.
* *
* Consume is a streaming processor. It may be called multiple times on one * 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 * 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 * 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 * the ready flag will be set. Further calls to consume once ready will be
* ignored. * ignored.
* *
* Consume will throw an http::exception in the case of an error. Typical * Consume will throw an http::exception in the case of an error. Typical
* error reasons include malformed responses, incomplete responses, and max * error reasons include malformed responses, incomplete responses, and max
* header size being reached. * header size being reached.
* *
* @param buf Pointer to byte buffer * @param buf Pointer to byte buffer
* @param len Size of byte buffer * @param len Size of byte buffer
* @return Number of bytes processed. * @return Number of bytes processed.
*/ */
size_t consume(char const * buf, size_t len); size_t consume(char const * buf, size_t len);
/// Process bytes in the input buffer (istream version) /// Process bytes in the input buffer (istream version)
/** /**
* Process bytes from istream s. Returns the number of bytes processed. * Process bytes from istream s. Returns the number of bytes processed.
* Bytes left unprocessed means bytes left over after the final header * Bytes left unprocessed means bytes left over after the final header
* delimiters. * delimiters.
* *
* Consume is a streaming processor. It may be called multiple times on one * 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 * 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 * 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 * the ready flag will be set. Further calls to consume once ready will be
* ignored. * ignored.
* *
* Consume will throw an http::exception in the case of an error. Typical * Consume will throw an http::exception in the case of an error. Typical
* error reasons include malformed responses, incomplete responses, and max * error reasons include malformed responses, incomplete responses, and max
* header size being reached. * header size being reached.
* *
* @param buf Pointer to byte buffer * @param buf Pointer to byte buffer
* @param len Size of byte buffer * @param len Size of byte buffer
* @return Number of bytes processed. * @return Number of bytes processed.
*/ */
size_t consume(std::istream & s); size_t consume(std::istream & s);
/// Returns true if the response is ready. /// Returns true if the response is ready.
/** /**
* @note will never return true if the content length header is not present * @note will never return true if the content length header is not present
*/ */
bool ready() const { bool ready() const {
return m_state == DONE; return m_state == DONE;
} }
/// Returns true if the response headers are fully parsed. /// Returns true if the response headers are fully parsed.
bool headers_ready() const { bool headers_ready() const {
return (m_state == BODY || m_state == DONE); return (m_state == BODY || m_state == DONE);
} }
/// Returns the full raw response /// Returns the full raw response
std::string raw() const; std::string raw() const;
/// Set response status code and message /// Set response status code and message
/** /**
* Sets the response status code to `code` and looks up the corresponding * Sets the response status code to `code` and looks up the corresponding
* message for standard codes. Non-standard codes will be entered as Unknown * message for standard codes. Non-standard codes will be entered as Unknown
* use set_status(status_code::value,std::string) overload to set both * use set_status(status_code::value,std::string) overload to set both
* values explicitly. * values explicitly.
* *
* @param code Code to set * @param code Code to set
* @param msg Message to set * @param msg Message to set
*/ */
void set_status(status_code::value code); void set_status(status_code::value code);
/// Set response status code and message /// Set response status code and message
/** /**
* Sets the response status code and message to independent custom values. * 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 * use set_status(status_code::value) to set the code and have the standard
* message be automatically set. * message be automatically set.
* *
* @param code Code to set * @param code Code to set
* @param msg Message to set * @param msg Message to set
*/ */
void set_status(status_code::value code, std::string const & msg); void set_status(status_code::value code, std::string const & msg);
/// Return the response status code /// Return the response status code
status_code::value get_status_code() const { status_code::value get_status_code() const {
return m_status_code; return m_status_code;
} }
/// Return the response status message /// Return the response status message
const std::string& get_status_msg() const { const std::string& get_status_msg() const {
return m_status_msg; return m_status_msg;
} }
private: private:
/// Helper function for consume. Process response line /// Helper function for consume. Process response line
void process(std::string::iterator begin, std::string::iterator end); void process(std::string::iterator begin, std::string::iterator end);
/// Helper function for processing body bytes /// Helper function for processing body bytes
size_t process_body(char const * buf, size_t len); size_t process_body(char const * buf, size_t len);
enum state { enum state {
RESPONSE_LINE = 0, RESPONSE_LINE = 0,
HEADERS = 1, HEADERS = 1,
BODY = 2, BODY = 2,
DONE = 3 DONE = 3
}; };
std::string m_status_msg; std::string m_status_msg;
size_t m_read; size_t m_read;
lib::shared_ptr<std::string> m_buf; lib::shared_ptr<std::string> m_buf;
status_code::value m_status_code; status_code::value m_status_code;
state m_state; state m_state;
}; };
} // namespace parser } // namespace parser
} // namespace http } // namespace http
} // namespace websocketpp } // namespace websocketpp
#include <websocketpp/http/impl/response.hpp> #include <websocketpp/http/impl/response.hpp>
#endif // HTTP_PARSER_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. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef WEBSOCKETPP_ENDPOINT_IMPL_HPP #ifndef WEBSOCKETPP_ENDPOINT_IMPL_HPP
#define WEBSOCKETPP_ENDPOINT_IMPL_HPP #define WEBSOCKETPP_ENDPOINT_IMPL_HPP
#include <string> #include <string>
namespace websocketpp { namespace websocketpp {
template <typename connection, typename config> template <typename connection, typename config>
typename endpoint<connection,config>::connection_ptr typename endpoint<connection,config>::connection_ptr
endpoint<connection,config>::create_connection() { endpoint<connection,config>::create_connection() {
m_alog->write(log::alevel::devel,"create_connection"); m_alog->write(log::alevel::devel,"create_connection");
//scoped_lock_type lock(m_state_lock); //scoped_lock_type lock(m_state_lock);
/*if (m_state == STOPPING || m_state == STOPPED) { /*if (m_state == STOPPING || m_state == STOPPED) {
return connection_ptr(); return connection_ptr();
}*/ }*/
//scoped_lock_type guard(m_mutex); //scoped_lock_type guard(m_mutex);
// Create a connection on the heap and manage it using a shared pointer // Create a connection on the heap and manage it using a shared pointer
connection_ptr con = lib::make_shared<connection_type>(m_is_server, connection_ptr con = lib::make_shared<connection_type>(m_is_server,
m_user_agent, m_alog, m_elog, lib::ref(m_rng)); m_user_agent, m_alog, m_elog, lib::ref(m_rng));
connection_weak_ptr w(con); connection_weak_ptr w(con);
// Create a weak pointer on the heap using that shared_ptr. // Create a weak pointer on the heap using that shared_ptr.
// Cast that weak pointer to void* and manage it using another shared_ptr // Cast that weak pointer to void* and manage it using another shared_ptr
// connection_hdl hdl(reinterpret_cast<void*>(new connection_weak_ptr(con))); // connection_hdl hdl(reinterpret_cast<void*>(new connection_weak_ptr(con)));
con->set_handle(w); con->set_handle(w);
// Copy default handlers from the endpoint // Copy default handlers from the endpoint
con->set_open_handler(m_open_handler); con->set_open_handler(m_open_handler);
con->set_close_handler(m_close_handler); con->set_close_handler(m_close_handler);
con->set_fail_handler(m_fail_handler); con->set_fail_handler(m_fail_handler);
con->set_ping_handler(m_ping_handler); con->set_ping_handler(m_ping_handler);
con->set_pong_handler(m_pong_handler); con->set_pong_handler(m_pong_handler);
con->set_pong_timeout_handler(m_pong_timeout_handler); con->set_pong_timeout_handler(m_pong_timeout_handler);
con->set_interrupt_handler(m_interrupt_handler); con->set_interrupt_handler(m_interrupt_handler);
con->set_http_handler(m_http_handler); con->set_http_handler(m_http_handler);
con->set_validate_handler(m_validate_handler); con->set_validate_handler(m_validate_handler);
con->set_message_handler(m_message_handler); con->set_message_handler(m_message_handler);
if (m_open_handshake_timeout_dur != config::timeout_open_handshake) { if (m_open_handshake_timeout_dur != config::timeout_open_handshake) {
con->set_open_handshake_timeout(m_open_handshake_timeout_dur); con->set_open_handshake_timeout(m_open_handshake_timeout_dur);
} }
if (m_close_handshake_timeout_dur != config::timeout_close_handshake) { if (m_close_handshake_timeout_dur != config::timeout_close_handshake) {
con->set_close_handshake_timeout(m_close_handshake_timeout_dur); con->set_close_handshake_timeout(m_close_handshake_timeout_dur);
} }
if (m_pong_timeout_dur != config::timeout_pong) { if (m_pong_timeout_dur != config::timeout_pong) {
con->set_pong_timeout(m_pong_timeout_dur); con->set_pong_timeout(m_pong_timeout_dur);
} }
if (m_max_message_size != config::max_message_size) { if (m_max_message_size != config::max_message_size) {
con->set_max_message_size(m_max_message_size); con->set_max_message_size(m_max_message_size);
} }
con->set_max_http_body_size(m_max_http_body_size); con->set_max_http_body_size(m_max_http_body_size);
lib::error_code ec; lib::error_code ec;
ec = transport_type::init(con); ec = transport_type::init(con);
if (ec) { if (ec) {
m_elog->write(log::elevel::fatal,ec.message()); m_elog->write(log::elevel::fatal,ec.message());
return connection_ptr(); return connection_ptr();
} }
return con; return con;
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::interrupt(connection_hdl hdl, lib::error_code & ec) void endpoint<connection,config>::interrupt(connection_hdl hdl, lib::error_code & ec)
{ {
connection_ptr con = get_con_from_hdl(hdl,ec); connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;} if (ec) {return;}
m_alog->write(log::alevel::devel,"Interrupting connection"); m_alog->write(log::alevel::devel,"Interrupting connection");
ec = con->interrupt(); ec = con->interrupt();
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::interrupt(connection_hdl hdl) { void endpoint<connection,config>::interrupt(connection_hdl hdl) {
lib::error_code ec; lib::error_code ec;
interrupt(hdl,ec); interrupt(hdl,ec);
if (ec) { throw exception(ec); } if (ec) { throw exception(ec); }
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::pause_reading(connection_hdl hdl, lib::error_code & ec) void endpoint<connection,config>::pause_reading(connection_hdl hdl, lib::error_code & ec)
{ {
connection_ptr con = get_con_from_hdl(hdl,ec); connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;} if (ec) {return;}
ec = con->pause_reading(); ec = con->pause_reading();
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::pause_reading(connection_hdl hdl) { void endpoint<connection,config>::pause_reading(connection_hdl hdl) {
lib::error_code ec; lib::error_code ec;
pause_reading(hdl,ec); pause_reading(hdl,ec);
if (ec) { throw exception(ec); } if (ec) { throw exception(ec); }
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::resume_reading(connection_hdl hdl, lib::error_code & ec) void endpoint<connection,config>::resume_reading(connection_hdl hdl, lib::error_code & ec)
{ {
connection_ptr con = get_con_from_hdl(hdl,ec); connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;} if (ec) {return;}
ec = con->resume_reading(); ec = con->resume_reading();
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::resume_reading(connection_hdl hdl) { void endpoint<connection,config>::resume_reading(connection_hdl hdl) {
lib::error_code ec; lib::error_code ec;
resume_reading(hdl,ec); resume_reading(hdl,ec);
if (ec) { throw exception(ec); } if (ec) { throw exception(ec); }
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::send_http_response(connection_hdl hdl, void endpoint<connection,config>::send_http_response(connection_hdl hdl,
lib::error_code & ec) lib::error_code & ec)
{ {
connection_ptr con = get_con_from_hdl(hdl,ec); connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;} if (ec) {return;}
con->send_http_response(ec); con->send_http_response(ec);
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::send_http_response(connection_hdl hdl) { void endpoint<connection,config>::send_http_response(connection_hdl hdl) {
lib::error_code ec; lib::error_code ec;
send_http_response(hdl,ec); send_http_response(hdl,ec);
if (ec) { throw exception(ec); } if (ec) { throw exception(ec); }
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload, void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
frame::opcode::value op, lib::error_code & ec) frame::opcode::value op, lib::error_code & ec)
{ {
connection_ptr con = get_con_from_hdl(hdl,ec); connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;} if (ec) {return;}
ec = con->send(payload,op); ec = con->send(payload,op);
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload, void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
frame::opcode::value op) frame::opcode::value op)
{ {
lib::error_code ec; lib::error_code ec;
send(hdl,payload,op,ec); send(hdl,payload,op,ec);
if (ec) { throw exception(ec); } if (ec) { throw exception(ec); }
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, void const * payload, void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
size_t len, frame::opcode::value op, lib::error_code & ec) size_t len, frame::opcode::value op, lib::error_code & ec)
{ {
connection_ptr con = get_con_from_hdl(hdl,ec); connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;} if (ec) {return;}
ec = con->send(payload,len,op); ec = con->send(payload,len,op);
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, void const * payload, void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
size_t len, frame::opcode::value op) size_t len, frame::opcode::value op)
{ {
lib::error_code ec; lib::error_code ec;
send(hdl,payload,len,op,ec); send(hdl,payload,len,op,ec);
if (ec) { throw exception(ec); } if (ec) { throw exception(ec); }
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg, void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg,
lib::error_code & ec) lib::error_code & ec)
{ {
connection_ptr con = get_con_from_hdl(hdl,ec); connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;} if (ec) {return;}
ec = con->send(msg); ec = con->send(msg);
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg) { void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg) {
lib::error_code ec; lib::error_code ec;
send(hdl,msg,ec); send(hdl,msg,ec);
if (ec) { throw exception(ec); } if (ec) { throw exception(ec); }
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::close(connection_hdl hdl, close::status::value void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
const code, std::string const & reason, const code, std::string const & reason,
lib::error_code & ec) lib::error_code & ec)
{ {
connection_ptr con = get_con_from_hdl(hdl,ec); connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;} if (ec) {return;}
con->close(code,reason,ec); con->close(code,reason,ec);
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::close(connection_hdl hdl, close::status::value void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
const code, std::string const & reason) const code, std::string const & reason)
{ {
lib::error_code ec; lib::error_code ec;
close(hdl,code,reason,ec); close(hdl,code,reason,ec);
if (ec) { throw exception(ec); } if (ec) { throw exception(ec); }
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
payload, lib::error_code & ec) payload, lib::error_code & ec)
{ {
connection_ptr con = get_con_from_hdl(hdl,ec); connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;} if (ec) {return;}
con->ping(payload,ec); con->ping(payload,ec);
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload) void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload)
{ {
lib::error_code ec; lib::error_code ec;
ping(hdl,payload,ec); ping(hdl,payload,ec);
if (ec) { throw exception(ec); } if (ec) { throw exception(ec); }
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload, void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload,
lib::error_code & ec) lib::error_code & ec)
{ {
connection_ptr con = get_con_from_hdl(hdl,ec); connection_ptr con = get_con_from_hdl(hdl,ec);
if (ec) {return;} if (ec) {return;}
con->pong(payload,ec); con->pong(payload,ec);
} }
template <typename connection, typename config> template <typename connection, typename config>
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload) void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload)
{ {
lib::error_code ec; lib::error_code ec;
pong(hdl,payload,ec); pong(hdl,payload,ec);
if (ec) { throw exception(ec); } if (ec) { throw exception(ec); }
} }
} // namespace websocketpp } // namespace websocketpp
#endif // WEBSOCKETPP_ENDPOINT_IMPL_HPP #endif // WEBSOCKETPP_ENDPOINT_IMPL_HPP

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,33 +1,33 @@
/* /*
* Copyright (c) 2014, Peter Thorson. All rights reserved. * Copyright (c) 2014, Peter Thorson. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the * * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#ifndef WEBSOCKETPP_SERVER_HPP #ifndef WEBSOCKETPP_SERVER_HPP
#define WEBSOCKETPP_SERVER_HPP #define WEBSOCKETPP_SERVER_HPP
#include <websocketpp/roles/server_endpoint.hpp> #include <websocketpp/roles/server_endpoint.hpp>
#endif //WEBSOCKETPP_SERVER_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 sha1.hpp is a repackaging of the sha1.cpp and sha1.h files from the smallsha1
library (http://code.google.com/p/smallsha1/) into a single header suitable for library (http://code.google.com/p/smallsha1/) into a single header suitable for
use as a header only library. This conversion was done by Peter Thorson use as a header only library. This conversion was done by Peter Thorson
(webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed (webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed
under the same license as the original, which is listed below. under the same license as the original, which is listed below.
***** *****
Copyright (c) 2011, Micael Hildenborg Copyright (c) 2011, Micael Hildenborg
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright * Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
* Neither the name of Micael Hildenborg nor the * Neither the name of Micael Hildenborg nor the
names of its contributors may be used to endorse or promote products names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission. derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SHA1_DEFINED #ifndef SHA1_DEFINED
#define SHA1_DEFINED #define SHA1_DEFINED
namespace websocketpp { namespace websocketpp {
namespace sha1 { namespace sha1 {
namespace { // local namespace { // local
// Rotate an integer value to left. // Rotate an integer value to left.
inline unsigned int rol(unsigned int value, unsigned int steps) { inline unsigned int rol(unsigned int value, unsigned int steps) {
return ((value << steps) | (value >> (32 - steps))); return ((value << steps) | (value >> (32 - steps)));
} }
// Sets the first 16 integers in the buffert to zero. // Sets the first 16 integers in the buffert to zero.
// Used for clearing the W buffert. // Used for clearing the W buffert.
inline void clearWBuffert(unsigned int * buffert) inline void clearWBuffert(unsigned int * buffert)
{ {
for (int pos = 16; --pos >= 0;) for (int pos = 16; --pos >= 0;)
{ {
buffert[pos] = 0; buffert[pos] = 0;
} }
} }
inline void innerHash(unsigned int * result, unsigned int * w) inline void innerHash(unsigned int * result, unsigned int * w)
{ {
unsigned int a = result[0]; unsigned int a = result[0];
unsigned int b = result[1]; unsigned int b = result[1];
unsigned int c = result[2]; unsigned int c = result[2];
unsigned int d = result[3]; unsigned int d = result[3];
unsigned int e = result[4]; unsigned int e = result[4];
int round = 0; int round = 0;
#define sha1macro(func,val) \ #define sha1macro(func,val) \
{ \ { \
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \ const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
e = d; \ e = d; \
d = c; \ d = c; \
c = rol(b, 30); \ c = rol(b, 30); \
b = a; \ b = a; \
a = t; \ a = t; \
} }
while (round < 16) while (round < 16)
{ {
sha1macro((b & c) | (~b & d), 0x5a827999) sha1macro((b & c) | (~b & d), 0x5a827999)
++round; ++round;
} }
while (round < 20) while (round < 20)
{ {
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro((b & c) | (~b & d), 0x5a827999) sha1macro((b & c) | (~b & d), 0x5a827999)
++round; ++round;
} }
while (round < 40) while (round < 40)
{ {
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro(b ^ c ^ d, 0x6ed9eba1) sha1macro(b ^ c ^ d, 0x6ed9eba1)
++round; ++round;
} }
while (round < 60) while (round < 60)
{ {
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc) sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
++round; ++round;
} }
while (round < 80) while (round < 80)
{ {
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro(b ^ c ^ d, 0xca62c1d6) sha1macro(b ^ c ^ d, 0xca62c1d6)
++round; ++round;
} }
#undef sha1macro #undef sha1macro
result[0] += a; result[0] += a;
result[1] += b; result[1] += b;
result[2] += c; result[2] += c;
result[3] += d; result[3] += d;
result[4] += e; result[4] += e;
} }
} // namespace } // namespace
/// Calculate a SHA1 hash /// Calculate a SHA1 hash
/** /**
* @param src points to any kind of data to be hashed. * @param src points to any kind of data to be hashed.
* @param bytelength the number of bytes to hash from the src pointer. * @param bytelength the number of bytes to hash from the src pointer.
* @param hash should point to a buffer of at least 20 bytes of size for storing * @param hash should point to a buffer of at least 20 bytes of size for storing
* the sha1 result in. * the sha1 result in.
*/ */
inline void calc(void const * src, size_t bytelength, unsigned char * hash) { inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
// Init the result array. // Init the result array.
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe,
0x10325476, 0xc3d2e1f0 }; 0x10325476, 0xc3d2e1f0 };
// Cast the void src pointer to be the byte array we can work with. // Cast the void src pointer to be the byte array we can work with.
unsigned char const * sarray = (unsigned char const *) src; unsigned char const * sarray = (unsigned char const *) src;
// The reusable round buffer // The reusable round buffer
unsigned int w[80]; unsigned int w[80];
// Loop through all complete 64byte blocks. // Loop through all complete 64byte blocks.
size_t endCurrentBlock; size_t endCurrentBlock;
size_t currentBlock = 0; size_t currentBlock = 0;
if (bytelength >= 64) { if (bytelength >= 64) {
size_t const endOfFullBlocks = bytelength - 64; size_t const endOfFullBlocks = bytelength - 64;
while (currentBlock <= endOfFullBlocks) { while (currentBlock <= endOfFullBlocks) {
endCurrentBlock = currentBlock + 64; endCurrentBlock = currentBlock + 64;
// Init the round buffer with the 64 byte block data. // Init the round buffer with the 64 byte block data.
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4) for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
{ {
// This line will swap endian on big endian and keep endian on // This line will swap endian on big endian and keep endian on
// little endian. // little endian.
w[roundPos++] = (unsigned int) sarray[currentBlock + 3] w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
| (((unsigned int) sarray[currentBlock + 2]) << 8) | (((unsigned int) sarray[currentBlock + 2]) << 8)
| (((unsigned int) sarray[currentBlock + 1]) << 16) | (((unsigned int) sarray[currentBlock + 1]) << 16)
| (((unsigned int) sarray[currentBlock]) << 24); | (((unsigned int) sarray[currentBlock]) << 24);
} }
innerHash(result, w); innerHash(result, w);
} }
} }
// Handle the last and not full 64 byte block if existing. // Handle the last and not full 64 byte block if existing.
endCurrentBlock = bytelength - currentBlock; endCurrentBlock = bytelength - currentBlock;
clearWBuffert(w); clearWBuffert(w);
size_t lastBlockBytes = 0; size_t lastBlockBytes = 0;
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) { for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3); w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
} }
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3); w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
if (endCurrentBlock >= 56) { if (endCurrentBlock >= 56) {
innerHash(result, w); innerHash(result, w);
clearWBuffert(w); clearWBuffert(w);
} }
w[15] = bytelength << 3; w[15] = bytelength << 3;
innerHash(result, w); innerHash(result, w);
// Store hash in result pointer, and make sure we get in in the correct // Store hash in result pointer, and make sure we get in in the correct
// order on both endian models. // order on both endian models.
for (int hashByte = 20; --hashByte >= 0;) { for (int hashByte = 20; --hashByte >= 0;) {
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff; hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
} }
} }
} // namespace sha1 } // namespace sha1
} // namespace websocketpp } // namespace websocketpp
#endif // SHA1_DEFINED #endif // SHA1_DEFINED

View File

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

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