diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..23741ecc5d
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,18 @@
+# Lineendings
+*.sln eol=crlf
+*.vcproj eol=crlf
+*.vcxproj* eol=crfl
+
+# Whitespace rules
+# strict (no trailing, no tabs)
+*.cpp whitespace=trailing-space,space-before-tab,tab-in-indent,cr-at-eol
+*.hpp whitespace=trailing-space,space-before-tab,tab-in-indent,cr-at-eol
+*.c whitespace=trailing-space,space-before-tab,tab-in-indent,cr-at-eol
+*.h whitespace=trailing-space,space-before-tab,tab-in-indent,cr-at-eol
+
+# normal (no trailing)
+*.sql whitespace=trailing-space,space-before-tab,cr-at-eol
+*.txt whitespace=trailing-space,space-before-tab,cr-at-eol
+
+# special files which must ignore whitespace
+*.patch whitespace=-trailing-space
\ No newline at end of file
diff --git a/examples/broadcast_server_tls/broadcast_admin.html b/examples/broadcast_server_tls/broadcast_admin.html
index d36288521e..cb352b5f0f 100644
--- a/examples/broadcast_server_tls/broadcast_admin.html
+++ b/examples/broadcast_server_tls/broadcast_admin.html
@@ -1,11 +1,11 @@
-
- WebSocket++ Broadcast Admin
-
-
-
+
+ WebSocket++ Broadcast Admin
+
+
+
@@ -27,52 +27,52 @@ var client_history = [];
var msgs = {};
function connect() {
- url = document.getElementById("server_url").value;
-
- if ("WebSocket" in window) {
- ws_client = new WebSocket(url);
- ws_admin = new WebSocket(url+"/admin");
- } else if ("MozWebSocket" in window) {
- ws_client = new MozWebSocket(url);
- ws_admin = new MozWebSocket(url+"/admin");
- } else {
- $("#messages").innerHTML += "This Browser does not support WebSockets
";
- return;
- }
+ url = document.getElementById("server_url").value;
- ws_client.onopen = function(e) {
- $("#messages").append("Client: A client connection to "+url+" has been opened.
");
-
- $("#server_url").disabled = true;
- $("#toggle_connect").html("Disconnect");
- };
+ if ("WebSocket" in window) {
+ ws_client = new WebSocket(url);
+ ws_admin = new WebSocket(url+"/admin");
+ } else if ("MozWebSocket" in window) {
+ ws_client = new MozWebSocket(url);
+ ws_admin = new MozWebSocket(url+"/admin");
+ } else {
+ $("#messages").innerHTML += "This Browser does not support WebSockets
";
+ return;
+ }
+
+ ws_client.onopen = function(e) {
+ $("#messages").append("Client: A client connection to "+url+" has been opened.
");
+
+ $("#server_url").disabled = true;
+ $("#toggle_connect").html("Disconnect");
+ };
ws_admin.onopen = function(e) {
- $("#messages").append("Client: An admin connection to "+url+"/admin has been opened.
");
-
- $("#server_url").disabled = true;
- $("#toggle_connect").html("Disconnect");
- };
-
- ws_client.onerror = function(e) {
- $("#messages").append("Client: An error occured on the client channel, see console log for more details.
");
- console.log(e);
- };
+ $("#messages").append("Client: An admin connection to "+url+"/admin has been opened.
");
+
+ $("#server_url").disabled = true;
+ $("#toggle_connect").html("Disconnect");
+ };
+
+ ws_client.onerror = function(e) {
+ $("#messages").append("Client: An error occured on the client channel, see console log for more details.
");
+ console.log(e);
+ };
ws_admin.onerror = function(e) {
- $("#messages").append("Client: An error occured on the admin channel, see console log for more details.
");
- console.log(e);
- };
-
- ws_client.onclose = function(e) {
- $("#messages").append("Client: The client connection to "+url+" was closed.
");
- clear_hud();
- };
+ $("#messages").append("Client: An error occured on the admin channel, see console log for more details.
");
+ console.log(e);
+ };
+
+ ws_client.onclose = function(e) {
+ $("#messages").append("Client: The client connection to "+url+" was closed.
");
+ clear_hud();
+ };
ws_admin.onclose = function(e) {
- $("#messages").append("Client: The admin connection to "+url+"/admin was closed.
");
- clear_hud();
- };
-
+ $("#messages").append("Client: The admin connection to "+url+"/admin was closed.
");
+ clear_hud();
+ };
+
ws_client.onmessage = function(e) {
if (options.console_enabled) {
if (e.data.length <= 126) {
@@ -84,20 +84,20 @@ function connect() {
ws_client.send("ack:"+hex_md5(e.data)+"=1;");
}
- ws_admin.onmessage = function(e) {
+ ws_admin.onmessage = function(e) {
foo = JSON.parse(e.data);
-
- if (foo.type == "message") {
- if (options.console_enabled) {
+
+ if (foo.type == "message") {
+ if (options.console_enabled) {
document.getElementById("messages").innerHTML += "Broadcasted Message: "+foo.value+"
";
}
- } else if (foo.type == "error") {
- if (options.console_enabled) {
+ } else if (foo.type == "error") {
+ if (options.console_enabled) {
document.getElementById("messages").innerHTML += "Command Error: "+foo.value+"
";
}
- } else if (foo.type == "con") {
- document.getElementById("connected_clients").innerHTML = foo.value;
- } else if (foo.type == "stats") {
+ } else if (foo.type == "con") {
+ document.getElementById("connected_clients").innerHTML = foo.value;
+ } else if (foo.type == "stats") {
var msg_delta = 0;
var data_delta = 0;
@@ -131,10 +131,10 @@ function connect() {
$("#sent_messages").html(o);
/*document.getElementById("messages_per_sec").innerHTML = foo.messages+"/s";
- document.getElementById("bytes_per_sec").innerHTML = format_data(foo.bytes)+"/s";
- document.getElementById("messages_sent").innerHTML = foo.messages_sent;
+ document.getElementById("bytes_per_sec").innerHTML = format_data(foo.bytes)+"/s";
+ document.getElementById("messages_sent").innerHTML = foo.messages_sent;
document.getElementById("messages_acked").innerHTML = foo.messages_acked;
- document.getElementById("bytes_sent").innerHTML = format_data(foo.bytes_sent);*/
+ document.getElementById("bytes_sent").innerHTML = format_data(foo.bytes_sent);*/
document.getElementById("admin_connections").innerHTML = foo.admin_connections;
@@ -155,45 +155,45 @@ function connect() {
if (message_history.length > total_points) {
message_history = message_history.slice(message_history.length-total_points);
}
- } else {
- document.getElementById("messages").innerHTML += "Unrecognized Server Command.
";
- }
- }
+ } else {
+ document.getElementById("messages").innerHTML += "Unrecognized Server Command.
";
+ }
+ }
}
function clear_hud() {
- document.getElementById("server_url").disabled = false;
- document.getElementById("toggle_connect").innerHTML = "Connect";
- document.getElementById("connected_clients").innerHTML = "N/A";
+ document.getElementById("server_url").disabled = false;
+ document.getElementById("toggle_connect").innerHTML = "Connect";
+ document.getElementById("connected_clients").innerHTML = "N/A";
document.getElementById("admin_connections").innerHTML = "N/A";
- document.getElementById("messages_per_sec").innerHTML = "N/A";
- document.getElementById("bytes_per_sec").innerHTML = "N/A";
- document.getElementById("messages_sent").innerHTML = "N/A";
- document.getElementById("bytes_sent").innerHTML = "N/A";
+ document.getElementById("messages_per_sec").innerHTML = "N/A";
+ document.getElementById("bytes_per_sec").innerHTML = "N/A";
+ document.getElementById("messages_sent").innerHTML = "N/A";
+ document.getElementById("bytes_sent").innerHTML = "N/A";
document.getElementById("messages_acked").innerHTML = "N/A";
}
-
+
function disconnect() {
- ws_client.close();
+ ws_client.close();
ws_admin.close();
}
function toggle_connect() {
- if (document.getElementById("server_url").disabled === false) {
- connect();
- } else {
- disconnect();
- }
+ if (document.getElementById("server_url").disabled === false) {
+ connect();
+ } else {
+ disconnect();
+ }
}
function broadcast() {
- if (ws_client === undefined || ws_client.readyState != 1) {
- $("#messages").append("Client: Client websocket is not avaliable for writing
");
- return;
- }
-
- ws_client.send(document.getElementById("msg").value);
- document.getElementById("msg").value = "";
+ if (ws_client === undefined || ws_client.readyState != 1) {
+ $("#messages").append("Client: Client websocket is not avaliable for writing
");
+ return;
+ }
+
+ ws_client.send(document.getElementById("msg").value);
+ document.getElementById("msg").value = "";
}
function send_command(command,args) {
@@ -278,21 +278,21 @@ $(function () {
-
-
-
-
+
+
+
+
-
-
-
-
Stats
-
Server
+
+
+
+
Stats
+
Server
Connected Clients: N/A
Admin Clients: N/A
@@ -325,7 +325,7 @@ body,html {
Messages Sent: N/A
Messages Acked: N/A
Messages Rate: N/A
-
+
diff --git a/examples/broadcast_server_tls/broadcast_admin_handler.hpp b/examples/broadcast_server_tls/broadcast_admin_handler.hpp
index bf87c9d489..96518bd852 100644
--- a/examples/broadcast_server_tls/broadcast_admin_handler.hpp
+++ b/examples/broadcast_server_tls/broadcast_admin_handler.hpp
@@ -58,10 +58,10 @@ public:
void on_open(connection_ptr connection) {
if (!m_timer) {
- m_timer.reset(new boost::asio::deadline_timer(connection->get_io_service(),boost::posix_time::seconds(0)));
- m_timer->expires_from_now(boost::posix_time::milliseconds(250));
- m_timer->async_wait(boost::bind(&type::on_timer,this,boost::asio::placeholders::error));
- }
+ m_timer.reset(new boost::asio::deadline_timer(connection->get_io_service(),boost::posix_time::seconds(0)));
+ m_timer->expires_from_now(boost::posix_time::milliseconds(250));
+ m_timer->async_wait(boost::bind(&type::on_timer,this,boost::asio::placeholders::error));
+ }
m_connections.insert(connection);
}
@@ -177,7 +177,7 @@ public:
}
m_timer->expires_from_now(boost::posix_time::milliseconds(250));
- m_timer->async_wait(
+ m_timer->async_wait(
boost::bind(
&type::on_timer,
this,
@@ -190,7 +190,7 @@ private:
broadcast_handler_ptr m_broadcast_handler;
std::set m_connections;
- boost::posix_time::ptime m_epoch;
+ boost::posix_time::ptime m_epoch;
boost::shared_ptr m_timer;
};
diff --git a/examples/broadcast_server_tls/broadcast_handler.hpp b/examples/broadcast_server_tls/broadcast_handler.hpp
index 080b546ed5..d64bf5f58a 100644
--- a/examples/broadcast_server_tls/broadcast_handler.hpp
+++ b/examples/broadcast_server_tls/broadcast_handler.hpp
@@ -53,7 +53,7 @@ struct msg {
uint64_t time;
std::string hash;
- boost::posix_time::ptime time_sent;
+ boost::posix_time::ptime time_sent;
};
typedef std::map msg_map;
@@ -61,16 +61,16 @@ typedef std::map msg_map;
template
class handler : public endpoint_type::handler {
public:
- typedef handler type;
+ typedef handler type;
typedef boost::shared_ptr ptr;
- typedef typename endpoint_type::handler_ptr handler_ptr;
+ typedef typename endpoint_type::handler_ptr handler_ptr;
typedef typename endpoint_type::connection_ptr connection_ptr;
- handler() : m_nextid(0) {}
-
- void on_open(connection_ptr connection) {
+ handler() : m_nextid(0) {}
+
+ void on_open(connection_ptr connection) {
m_connections.insert(connection);
- }
+ }
// this dummy tls init function will cause all TLS connections to fail.
// TLS handling for broadcast::handler is usually done by a lobby handler.
@@ -83,14 +83,14 @@ public:
void on_load(connection_ptr connection, handler_ptr old_handler) {
this->on_open(connection);
m_lobby = old_handler;
- }
-
- void on_close(connection_ptr connection) {
- m_connections.erase(connection);
- }
-
- void on_message(connection_ptr connection,message::data_ptr msg) {
- wscmd::cmd command = wscmd::parse(msg->get_payload());
+ }
+
+ void on_close(connection_ptr connection) {
+ m_connections.erase(connection);
+ }
+
+ void on_message(connection_ptr connection,message::data_ptr msg) {
+ wscmd::cmd command = wscmd::parse(msg->get_payload());
std::cout << "msg: " << msg->get_payload() << std::endl;
@@ -189,7 +189,7 @@ public:
m_msgs.empty();
}
private:
- handler_ptr m_lobby;
+ handler_ptr m_lobby;
int m_nextid;
msg_map m_msgs;
diff --git a/examples/broadcast_server_tls/broadcast_server_tls.cpp b/examples/broadcast_server_tls/broadcast_server_tls.cpp
index e97a338fa8..df128810b8 100644
--- a/examples/broadcast_server_tls/broadcast_server_tls.cpp
+++ b/examples/broadcast_server_tls/broadcast_server_tls.cpp
@@ -45,13 +45,13 @@ typedef websocketpp::endpoint());
- tls_endpoint_type e(h);
-
- e.alog().unset_level(websocketpp::log::alevel::ALL);
- e.elog().set_level(websocketpp::log::elevel::ALL);
-
- std::cout << "Starting Secure WebSocket broadcast server on port " << port << std::endl;
- e.listen(port);
- } else {
- plain_handler_ptr h(new websocketpp::broadcast::server_handler());
- plain_endpoint_type e(h);
-
- e.alog().unset_level(websocketpp::log::alevel::ALL);
- e.elog().set_level(websocketpp::log::elevel::ALL);
-
+ if (argc == 2) {
+ // TODO: input validation?
+ port = atoi(argv[1]);
+ }
+
+ if (argc == 3) {
+ // TODO: input validation?
+ port = atoi(argv[1]);
+ tls = !strcmp(argv[2],"-tls");
+ }
+
+ try {
+ if (tls) {
+ tls_handler_ptr h(new websocketpp::broadcast::server_handler());
+ tls_endpoint_type e(h);
+
+ e.alog().unset_level(websocketpp::log::alevel::ALL);
+ e.elog().set_level(websocketpp::log::elevel::ALL);
+
+ std::cout << "Starting Secure WebSocket broadcast server on port " << port << std::endl;
+ e.listen(port);
+ } else {
+ plain_handler_ptr h(new websocketpp::broadcast::server_handler());
+ plain_endpoint_type e(h);
+
+ e.alog().unset_level(websocketpp::log::alevel::ALL);
+ e.elog().set_level(websocketpp::log::elevel::ALL);
+
//e.alog().set_level(websocketpp::log::alevel::DEVEL);
- std::cout << "Starting WebSocket broadcast server on port " << port << std::endl;
- e.listen(port);
- }
- } catch (std::exception& e) {
- std::cerr << "Exception: " << e.what() << std::endl;
-
- }
-
- return 0;
+ std::cout << "Starting WebSocket broadcast server on port " << port << std::endl;
+ e.listen(port);
+ }
+ } catch (std::exception& e) {
+ std::cerr << "Exception: " << e.what() << std::endl;
+
+ }
+
+ return 0;
}
diff --git a/examples/chat_client/chat_client.cpp b/examples/chat_client/chat_client.cpp
index 7223dad92a..a2b3952c54 100644
--- a/examples/chat_client/chat_client.cpp
+++ b/examples/chat_client/chat_client.cpp
@@ -38,41 +38,41 @@ using boost::asio::ip::tcp;
using namespace websocketchat;
int main(int argc, char* argv[]) {
- std::string uri;
-
- if (argc != 2) {
- std::cout << "Usage: `chat_client ws_uri`" << std::endl;
- } else {
- uri = argv[1];
- }
-
- chat_client_handler_ptr c(new chat_client_handler());
-
- try {
- boost::asio::io_service io_service;
-
- websocketpp::client_ptr client(new websocketpp::client(io_service,c));
-
- client->init();
+ std::string uri;
+
+ if (argc != 2) {
+ std::cout << "Usage: `chat_client ws_uri`" << std::endl;
+ } else {
+ uri = argv[1];
+ }
+
+ chat_client_handler_ptr c(new chat_client_handler());
+
+ try {
+ boost::asio::io_service io_service;
+
+ websocketpp::client_ptr client(new websocketpp::client(io_service,c));
+
+ client->init();
- client->set_header("User Agent","WebSocket++/2011-09-25");
- client->add_subprotocol("com.zaphoyd.websocketpp.chat");
-
- client->set_origin("http://zaphoyd.com");
+ client->set_header("User Agent","WebSocket++/2011-09-25");
+ client->add_subprotocol("com.zaphoyd.websocketpp.chat");
+
+ client->set_origin("http://zaphoyd.com");
- client->connect(uri);
-
- boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
-
- char line[512];
- while (std::cin.getline(line, 512)) {
- c->send(line);
- }
-
- t.join();
- } catch (std::exception& e) {
- std::cerr << "Exception: " << e.what() << std::endl;
- }
-
- return 0;
+ client->connect(uri);
+
+ boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
+
+ char line[512];
+ while (std::cin.getline(line, 512)) {
+ c->send(line);
+ }
+
+ t.join();
+ } catch (std::exception& e) {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+
+ return 0;
}
diff --git a/examples/chat_client/chat_client.html b/examples/chat_client/chat_client.html
index 3e7c08ad28..fe1e3584b5 100644
--- a/examples/chat_client/chat_client.html
+++ b/examples/chat_client/chat_client.html
@@ -12,102 +12,102 @@ var url;
$(document).ready(init);
function init() {
- $(document).keypress(function(event) {
- if ( event.which == 13 ) {
- event.preventDefault();
- send();
- }
- });
+ $(document).keypress(function(event) {
+ if ( event.which == 13 ) {
+ event.preventDefault();
+ send();
+ }
+ });
}
function connect() {
- url = $("#server_url").val();
- console.log(url);
-
- if ("WebSocket" in window) {
- ws = new WebSocket(url);
- } else if ("MozWebSocket" in window) {
- ws = new MozWebSocket(url);
- } else {
- chat_message("This Browser does not support WebSockets");
- return;
- }
- ws.onopen = function(e) {
- chat_message("A connection to "+url+" has been opened.");
-
- $("#server_url").attr("disabled",true);
- $("#toggle_connect").html("Disconnect");
- };
-
- ws.onerror = function(e) {
- chat_message("An error occured, see console log for more details.");
- console.log(e);
- };
-
- ws.onclose = function(e) {
- chat_message("The connection to "+url+" was closed.");
- };
-
- ws.onmessage = function(e) {
- var message = JSON.parse(e.data);
-
- if (message.type == "msg") {
- chat_message(message.value,message.sender);
- } else if (message.type == "participants") {
- var o = "";
- for (var p in message.value) {
- o += "- "+message.value[p]+"
";
- }
- o += "
";
- $("#participants").html(o);
- }
- };
+ url = $("#server_url").val();
+ console.log(url);
+
+ if ("WebSocket" in window) {
+ ws = new WebSocket(url);
+ } else if ("MozWebSocket" in window) {
+ ws = new MozWebSocket(url);
+ } else {
+ chat_message("This Browser does not support WebSockets");
+ return;
+ }
+ ws.onopen = function(e) {
+ chat_message("A connection to "+url+" has been opened.");
+
+ $("#server_url").attr("disabled",true);
+ $("#toggle_connect").html("Disconnect");
+ };
+
+ ws.onerror = function(e) {
+ chat_message("An error occured, see console log for more details.");
+ console.log(e);
+ };
+
+ ws.onclose = function(e) {
+ chat_message("The connection to "+url+" was closed.");
+ };
+
+ ws.onmessage = function(e) {
+ var message = JSON.parse(e.data);
+
+ if (message.type == "msg") {
+ chat_message(message.value,message.sender);
+ } else if (message.type == "participants") {
+ var o = "";
+ for (var p in message.value) {
+ o += "- "+message.value[p]+"
";
+ }
+ o += "
";
+ $("#participants").html(o);
+ }
+ };
}
function chat_message(message,sender) {
- if (arguments.length == 1) {
- sender = "";
- }
-
- var style;
-
- if (sender == "") {
- style = "client";
- } else if (sender == "server") {
- style = "server";
- sender = "["+sender+"]";
- } else {
- style = "message";
- sender = "["+sender+"]";
- }
-
- $("#messages").append(""+sender+" "+message+"
");
- $("#messages").prop({ scrollTop: $("#messages").prop("scrollHeight") });
+ if (arguments.length == 1) {
+ sender = "";
+ }
+
+ var style;
+
+ if (sender == "") {
+ style = "client";
+ } else if (sender == "server") {
+ style = "server";
+ sender = "["+sender+"]";
+ } else {
+ style = "message";
+ sender = "["+sender+"]";
+ }
+
+ $("#messages").append(""+sender+" "+message+"
");
+ $("#messages").prop({ scrollTop: $("#messages").prop("scrollHeight") });
}
function disconnect() {
- ws.close();
- $("#server_url").removeAttr("disabled");
- $("#toggle_connect").html("Connect");
- $("#participants").html("");
+ ws.close();
+ $("#server_url").removeAttr("disabled");
+ $("#toggle_connect").html("Connect");
+ $("#participants").html("");
}
function toggle_connect() {
- if ($("#server_url").attr("disabled") != "disabled") {
- connect();
- } else {
- disconnect();
- }
+ if ($("#server_url").attr("disabled") != "disabled") {
+ connect();
+ } else {
+ disconnect();
+ }
}
function send() {
- if (ws === undefined || ws.readyState != 1) {
- chat_message("Websocket is not avaliable for writing");
- return;
- }
-
- ws.send($("#msg").val());
- $("#msg").val("");
+ if (ws === undefined || ws.readyState != 1) {
+ chat_message("Websocket is not avaliable for writing");
+ return;
+ }
+
+ ws.send($("#msg").val());
+ $("#msg").val("");
}
@@ -117,12 +117,12 @@ function send() {
-
-
-
-
+
+
+
+
-
-
-
Chat Participants
-
+
+
+
Chat Participants
+
diff --git a/examples/chat_client/chat_client_handler.cpp b/examples/chat_client/chat_client_handler.cpp
index e16a5f4717..8b890a9a13 100644
--- a/examples/chat_client/chat_client_handler.cpp
+++ b/examples/chat_client/chat_client_handler.cpp
@@ -33,24 +33,24 @@ using websocketchat::chat_client_handler;
using websocketpp::client_session_ptr;
void chat_client_handler::on_open(session_ptr s) {
- // not sure if anything needs to happen here.
- m_session = s;
+ // not sure if anything needs to happen here.
+ m_session = s;
- std::cout << "Successfully connected" << std::endl;
+ std::cout << "Successfully connected" << std::endl;
}
void chat_client_handler::on_close(session_ptr s) {
- // not sure if anything needs to happen here either.
-
- m_session = client_session_ptr();
+ // not sure if anything needs to happen here either.
+
+ m_session = client_session_ptr();
- std::cout << "client was disconnected" << std::endl;
+ std::cout << "client was disconnected" << std::endl;
}
void chat_client_handler::on_message(session_ptr s,const std::string &msg) {
- //std::cout << "message from server: " << msg << std::endl;
+ //std::cout << "message from server: " << msg << std::endl;
- decode_server_msg(msg);
+ decode_server_msg(msg);
}
// CLIENT API
@@ -58,114 +58,114 @@ void chat_client_handler::on_message(session_ptr s,const std::string &msg) {
// they need to be careful to not touch unsyncronized member variables.
void chat_client_handler::send(const std::string &msg) {
- if (!m_session) {
- std::cerr << "Error: no connected session" << std::endl;
- return;
- }
- m_session->io_service().post(boost::bind(&chat_client_handler::do_send, this, msg));
+ if (!m_session) {
+ std::cerr << "Error: no connected session" << std::endl;
+ return;
+ }
+ m_session->io_service().post(boost::bind(&chat_client_handler::do_send, this, msg));
}
void chat_client_handler::close() {
- if (!m_session) {
- std::cerr << "Error: no connected session" << std::endl;
- return;
- }
- m_session->io_service().post(boost::bind(&chat_client_handler::do_close,this));
+ if (!m_session) {
+ std::cerr << "Error: no connected session" << std::endl;
+ return;
+ }
+ m_session->io_service().post(boost::bind(&chat_client_handler::do_close,this));
}
// END CLIENT API
void chat_client_handler::do_send(const std::string &msg) {
- if (!m_session) {
- std::cerr << "Error: no connected session" << std::endl;
- return;
- }
-
- // check for local commands
- if (msg == "/list") {
- std::cout << "list all participants" << std::endl;
- } else if (msg == "/close") {
- do_close();
- } else {
- m_session->send(msg);
- }
+ if (!m_session) {
+ std::cerr << "Error: no connected session" << std::endl;
+ return;
+ }
+
+ // check for local commands
+ if (msg == "/list") {
+ std::cout << "list all participants" << std::endl;
+ } else if (msg == "/close") {
+ do_close();
+ } else {
+ m_session->send(msg);
+ }
}
void chat_client_handler::do_close() {
- if (!m_session) {
- std::cerr << "Error: no connected session" << std::endl;
- return;
- }
- m_session->close(websocketpp::session::CLOSE_STATUS_GOING_AWAY,"");
+ if (!m_session) {
+ std::cerr << "Error: no connected session" << std::endl;
+ return;
+ }
+ m_session->close(websocketpp::session::CLOSE_STATUS_GOING_AWAY,"");
}
// {"type":"participants","value":[,...]}
// {"type":"msg","sender":"","value":"" }
void chat_client_handler::decode_server_msg(const std::string &msg) {
- // for messages of type participants, erase and rebuild m_participants
- // for messages of type msg, print out message
-
- // NOTE: The chat server was written with the intention of the client having a built in
- // JSON parser. To keep external dependencies low for this demonstration chat client I am
- // parsing the server messages by hand.
-
- std::string::size_type start = 9;
- std::string::size_type end;
-
- if (msg.substr(0,start) != "{\"type\":\"") {
- // ignore
- std::cout << "invalid message" << std::endl;
- return;
- }
-
-
+ // for messages of type participants, erase and rebuild m_participants
+ // for messages of type msg, print out message
+
+ // NOTE: The chat server was written with the intention of the client having a built in
+ // JSON parser. To keep external dependencies low for this demonstration chat client I am
+ // parsing the server messages by hand.
+
+ std::string::size_type start = 9;
+ std::string::size_type end;
+
+ if (msg.substr(0,start) != "{\"type\":\"") {
+ // ignore
+ std::cout << "invalid message" << std::endl;
+ return;
+ }
+
+
- if (msg.substr(start,15) == "msg\",\"sender\":\"") {
- // parse message
- std::string sender;
- std::string message;
-
- start += 15;
+ if (msg.substr(start,15) == "msg\",\"sender\":\"") {
+ // parse message
+ std::string sender;
+ std::string message;
+
+ start += 15;
- end = msg.find("\"",start);
- while (end != std::string::npos) {
- if (msg[end-1] == '\\') {
- sender += msg.substr(start,end-start-1) + "\"";
- start = end+1;
- end = msg.find("\"",start);
- } else {
- sender += msg.substr(start,end-start);
- start = end;
- break;
- }
- }
-
- if (msg.substr(start,11) != "\",\"value\":\"") {
- std::cout << "invalid message" << std::endl;
- return;
- }
+ end = msg.find("\"",start);
+ while (end != std::string::npos) {
+ if (msg[end-1] == '\\') {
+ sender += msg.substr(start,end-start-1) + "\"";
+ start = end+1;
+ end = msg.find("\"",start);
+ } else {
+ sender += msg.substr(start,end-start);
+ start = end;
+ break;
+ }
+ }
+
+ if (msg.substr(start,11) != "\",\"value\":\"") {
+ std::cout << "invalid message" << std::endl;
+ return;
+ }
- start += 11;
+ start += 11;
- end = msg.find("\"",start);
- while (end != std::string::npos) {
- if (msg[end-1] == '\\') {
- message += msg.substr(start,end-start-1) + "\"";
- start = end+1;
- end = msg.find("\"",start);
- } else {
- message += msg.substr(start,end-start);
- start = end;
- break;
- }
- }
+ end = msg.find("\"",start);
+ while (end != std::string::npos) {
+ if (msg[end-1] == '\\') {
+ message += msg.substr(start,end-start-1) + "\"";
+ start = end+1;
+ end = msg.find("\"",start);
+ } else {
+ message += msg.substr(start,end-start);
+ start = end;
+ break;
+ }
+ }
- std::cout << "[" << sender << "] " << message << std::endl;
- } else if (msg.substr(start,23) == "participants\",\"value\":[") {
- // parse participants
- std::cout << "participants message" << std::endl;
- } else {
- // unknown message type
- std::cout << "unknown message" << std::endl;
- }
+ std::cout << "[" << sender << "] " << message << std::endl;
+ } else if (msg.substr(start,23) == "participants\",\"value\":[") {
+ // parse participants
+ std::cout << "participants message" << std::endl;
+ } else {
+ // unknown message type
+ std::cout << "unknown message" << std::endl;
+ }
}
diff --git a/examples/chat_client/chat_client_handler.hpp b/examples/chat_client/chat_client_handler.hpp
index 0b1f0e0676..e9e966afec 100644
--- a/examples/chat_client/chat_client_handler.hpp
+++ b/examples/chat_client/chat_client_handler.hpp
@@ -53,39 +53,39 @@ namespace websocketchat {
class chat_client_handler : public websocketpp::connection_handler {
public:
- chat_client_handler() {}
- virtual ~chat_client_handler() {}
-
- // ignored for clients?
- void validate(session_ptr s) {}
-
- // connection to chat room complete
- void on_open(session_ptr s);
+ chat_client_handler() {}
+ virtual ~chat_client_handler() {}
+
+ // ignored for clients?
+ void validate(session_ptr s) {}
+
+ // connection to chat room complete
+ void on_open(session_ptr s);
- // connection to chat room closed
- void on_close(session_ptr s);
-
- // got a new message from server
- void on_message(session_ptr s,const std::string &msg);
-
- // ignore messages
- void on_message(session_ptr s,const std::vector &data) {}
-
- // CLIENT API
- void send(const std::string &msg);
- void close();
+ // connection to chat room closed
+ void on_close(session_ptr s);
+
+ // got a new message from server
+ void on_message(session_ptr s,const std::string &msg);
+
+ // ignore messages
+ void on_message(session_ptr s,const std::vector &data) {}
+
+ // CLIENT API
+ void send(const std::string &msg);
+ void close();
private:
- // Client API internal
- void do_send(const std::string &msg);
- void do_close();
+ // Client API internal
+ void do_send(const std::string &msg);
+ void do_close();
- void decode_server_msg(const std::string &msg);
-
- // list of other chat participants
- std::set m_participants;
- std::queue m_msg_queue;
- session_ptr m_session;
+ void decode_server_msg(const std::string &msg);
+
+ // list of other chat participants
+ std::set m_participants;
+ std::queue m_msg_queue;
+ session_ptr m_session;
};
typedef boost::shared_ptr chat_client_handler_ptr;
diff --git a/examples/chat_server/chat.cpp b/examples/chat_server/chat.cpp
index 52d3e72eb6..fdc9c78f2b 100644
--- a/examples/chat_server/chat.cpp
+++ b/examples/chat_server/chat.cpp
@@ -34,160 +34,160 @@ using websocketpp::session::server_session_ptr;
void chat_server_handler::validate(server_session_ptr session) {
- std::stringstream err;
-
- // We only know about the chat resource
- if (session->get_resource() != "/chat") {
- err << "Request for unknown resource " << session->get_resource();
- throw(websocketpp::http::exception(err.str(),websocketpp::http::status_code::NOT_FOUND));
- }
-
- // Require specific origin example
- if (session->get_origin() != "http://zaphoyd.com") {
- err << "Request from unrecognized origin: " << session->get_origin();
- throw(websocketpp::http::exception(err.str(),websocketpp::http::status_code::FORBIDDEN));
- }
+ std::stringstream err;
+
+ // We only know about the chat resource
+ if (session->get_resource() != "/chat") {
+ err << "Request for unknown resource " << session->get_resource();
+ throw(websocketpp::http::exception(err.str(),websocketpp::http::status_code::NOT_FOUND));
+ }
+
+ // Require specific origin example
+ if (session->get_origin() != "http://zaphoyd.com") {
+ err << "Request from unrecognized origin: " << session->get_origin();
+ throw(websocketpp::http::exception(err.str(),websocketpp::http::status_code::FORBIDDEN));
+ }
}
void chat_server_handler::on_open(server_session_ptr session) {
- std::cout << "client " << session << " joined the lobby." << std::endl;
- m_connections.insert(std::pair(session,get_con_id(session)));
+ std::cout << "client " << session << " joined the lobby." << std::endl;
+ m_connections.insert(std::pair(session,get_con_id(session)));
- // send user list and signon message to all clients
- send_to_all(serialize_state());
- session->send(encode_message("server","Welcome, use the /alias command to set a name, /help for a list of other commands."));
- send_to_all(encode_message("server",m_connections[session]+" has joined the chat."));
+ // send user list and signon message to all clients
+ send_to_all(serialize_state());
+ session->send(encode_message("server","Welcome, use the /alias command to set a name, /help for a list of other commands."));
+ send_to_all(encode_message("server",m_connections[session]+" has joined the chat."));
}
void chat_server_handler::on_close(server_session_ptr session) {
- std::map::iterator it = m_connections.find(session);
-
- if (it == m_connections.end()) {
- // this client has already disconnected, we can ignore this.
- // this happens during certain types of disconnect where there is a
- // deliberate "soft" disconnection preceeding the "hard" socket read
- // fail or disconnect ack message.
- return;
- }
-
- std::cout << "client " << session << " left the lobby." << std::endl;
-
- const std::string alias = it->second;
- m_connections.erase(it);
+ std::map::iterator it = m_connections.find(session);
+
+ if (it == m_connections.end()) {
+ // this client has already disconnected, we can ignore this.
+ // this happens during certain types of disconnect where there is a
+ // deliberate "soft" disconnection preceeding the "hard" socket read
+ // fail or disconnect ack message.
+ return;
+ }
+
+ std::cout << "client " << session << " left the lobby." << std::endl;
+
+ const std::string alias = it->second;
+ m_connections.erase(it);
- // send user list and signoff message to all clients
- send_to_all(serialize_state());
- send_to_all(encode_message("server",alias+" has left the chat."));
+ // send user list and signoff message to all clients
+ send_to_all(serialize_state());
+ send_to_all(encode_message("server",alias+" has left the chat."));
}
void chat_server_handler::on_message(server_session_ptr session,websocketpp::utf8_string_ptr msg) {
- std::cout << "message from client " << session << ": " << *msg << std::endl;
-
-
-
- // check for special command messages
- if (*msg == "/help") {
- // print command list
- session->send(encode_message("server","avaliable commands:
/help - show this help
/alias foo - set alias to foo",false));
- return;
- }
-
- if (msg->substr(0,7) == "/alias ") {
- std::string response;
- std::string alias;
-
- if (msg->size() == 7) {
- response = "You must enter an alias.";
- session->send(encode_message("server",response));
- return;
- } else {
- alias = msg->substr(7);
- }
-
- response = m_connections[session] + " is now known as "+alias;
+ std::cout << "message from client " << session << ": " << *msg << std::endl;
+
+
+
+ // check for special command messages
+ if (*msg == "/help") {
+ // print command list
+ session->send(encode_message("server","avaliable commands:
/help - show this help
/alias foo - set alias to foo",false));
+ return;
+ }
+
+ if (msg->substr(0,7) == "/alias ") {
+ std::string response;
+ std::string alias;
+
+ if (msg->size() == 7) {
+ response = "You must enter an alias.";
+ session->send(encode_message("server",response));
+ return;
+ } else {
+ alias = msg->substr(7);
+ }
+
+ response = m_connections[session] + " is now known as "+alias;
- // store alias pre-escaped so we don't have to do this replacing every time this
- // user sends a message
-
- // escape JSON characters
- boost::algorithm::replace_all(alias,"\\","\\\\");
- boost::algorithm::replace_all(alias,"\"","\\\"");
-
- // escape HTML characters
- boost::algorithm::replace_all(alias,"&","&");
- boost::algorithm::replace_all(alias,"<","<");
- boost::algorithm::replace_all(alias,">",">");
-
- m_connections[session] = alias;
-
- // set alias
- send_to_all(serialize_state());
- send_to_all(encode_message("server",response));
- return;
- }
-
- // catch other slash commands
- if ((*msg)[0] == '/') {
- session->send(encode_message("server","unrecognized command"));
- return;
- }
-
- // create JSON message to send based on msg
- send_to_all(encode_message(m_connections[session],*msg));
+ // store alias pre-escaped so we don't have to do this replacing every time this
+ // user sends a message
+
+ // escape JSON characters
+ boost::algorithm::replace_all(alias,"\\","\\\\");
+ boost::algorithm::replace_all(alias,"\"","\\\"");
+
+ // escape HTML characters
+ boost::algorithm::replace_all(alias,"&","&");
+ boost::algorithm::replace_all(alias,"<","<");
+ boost::algorithm::replace_all(alias,">",">");
+
+ m_connections[session] = alias;
+
+ // set alias
+ send_to_all(serialize_state());
+ send_to_all(encode_message("server",response));
+ return;
+ }
+
+ // catch other slash commands
+ if ((*msg)[0] == '/') {
+ session->send(encode_message("server","unrecognized command"));
+ return;
+ }
+
+ // create JSON message to send based on msg
+ send_to_all(encode_message(m_connections[session],*msg));
}
// {"type":"participants","value":[,...]}
std::string chat_server_handler::serialize_state() {
- std::stringstream s;
-
- s << "{\"type\":\"participants\",\"value\":[";
-
- std::map::iterator it;
-
- for (it = m_connections.begin(); it != m_connections.end(); it++) {
- s << "\"" << (*it).second << "\"";
- if (++it != m_connections.end()) {
- s << ",";
- }
- it--;
- }
-
- s << "]}";
-
- return s.str();
+ std::stringstream s;
+
+ s << "{\"type\":\"participants\",\"value\":[";
+
+ std::map::iterator it;
+
+ for (it = m_connections.begin(); it != m_connections.end(); it++) {
+ s << "\"" << (*it).second << "\"";
+ if (++it != m_connections.end()) {
+ s << ",";
+ }
+ it--;
+ }
+
+ s << "]}";
+
+ return s.str();
}
// {"type":"msg","sender":"","value":"" }
std::string chat_server_handler::encode_message(std::string sender,std::string msg,bool escape) {
- std::stringstream s;
-
- // escape JSON characters
- boost::algorithm::replace_all(msg,"\\","\\\\");
- boost::algorithm::replace_all(msg,"\"","\\\"");
-
- // escape HTML characters
- if (escape) {
- boost::algorithm::replace_all(msg,"&","&");
- boost::algorithm::replace_all(msg,"<","<");
- boost::algorithm::replace_all(msg,">",">");
- }
-
- s << "{\"type\":\"msg\",\"sender\":\"" << sender
- << "\",\"value\":\"" << msg << "\"}";
-
- return s.str();
+ std::stringstream s;
+
+ // escape JSON characters
+ boost::algorithm::replace_all(msg,"\\","\\\\");
+ boost::algorithm::replace_all(msg,"\"","\\\"");
+
+ // escape HTML characters
+ if (escape) {
+ boost::algorithm::replace_all(msg,"&","&");
+ boost::algorithm::replace_all(msg,"<","<");
+ boost::algorithm::replace_all(msg,">",">");
+ }
+
+ s << "{\"type\":\"msg\",\"sender\":\"" << sender
+ << "\",\"value\":\"" << msg << "\"}";
+
+ return s.str();
}
std::string chat_server_handler::get_con_id(server_session_ptr s) {
- std::stringstream endpoint;
- endpoint << s->get_endpoint();
- return endpoint.str();
+ std::stringstream endpoint;
+ endpoint << s->get_endpoint();
+ return endpoint.str();
}
void chat_server_handler::send_to_all(std::string data) {
- std::map::iterator it;
- for (it = m_connections.begin(); it != m_connections.end(); it++) {
- (*it).first->send(data);
- }
+ std::map::iterator it;
+ for (it = m_connections.begin(); it != m_connections.end(); it++) {
+ (*it).first->send(data);
+ }
}
diff --git a/examples/chat_server/chat.hpp b/examples/chat_server/chat.hpp
index 7c32020d4e..7d6571feb1 100644
--- a/examples/chat_server/chat.hpp
+++ b/examples/chat_server/chat.hpp
@@ -53,27 +53,27 @@ namespace websocketchat {
class chat_server_handler : public server_handler {
public:
- void validate(server_session_ptr session);
-
- // add new connection to the lobby
- void on_open(server_session_ptr session);
-
- // someone disconnected from the lobby, remove them
- void on_close(server_session_ptr session);
-
- void on_message(server_session_ptr session,websocketpp::utf8_string_ptr msg);
-
- // lobby will ignore binary messages
- void on_message(server_session_ptr session,websocketpp::binary_string_ptr data) {}
+ void validate(server_session_ptr session);
+
+ // add new connection to the lobby
+ void on_open(server_session_ptr session);
+
+ // someone disconnected from the lobby, remove them
+ void on_close(server_session_ptr session);
+
+ void on_message(server_session_ptr session,websocketpp::utf8_string_ptr msg);
+
+ // lobby will ignore binary messages
+ void on_message(server_session_ptr session,websocketpp::binary_string_ptr data) {}
private:
- std::string serialize_state();
- std::string encode_message(std::string sender,std::string msg,bool escape = true);
- std::string get_con_id(server_session_ptr s);
-
- void send_to_all(std::string data);
-
- // list of outstanding connections
- std::map m_connections;
+ std::string serialize_state();
+ std::string encode_message(std::string sender,std::string msg,bool escape = true);
+ std::string get_con_id(server_session_ptr s);
+
+ void send_to_all(std::string data);
+
+ // list of outstanding connections
+ std::map m_connections;
};
typedef boost::shared_ptr chat_server_handler_ptr;
diff --git a/examples/chat_server/chat_server.cpp b/examples/chat_server/chat_server.cpp
index 474197bda5..a2409b4f86 100644
--- a/examples/chat_server/chat_server.cpp
+++ b/examples/chat_server/chat_server.cpp
@@ -36,36 +36,36 @@ using boost::asio::ip::tcp;
using namespace websocketchat;
int main(int argc, char* argv[]) {
- short port = 9003;
-
- if (argc == 2) {
- // TODO: input validation?
- port = atoi(argv[2]);
- }
-
- try {
- // create an instance of our handler
- server_handler_ptr default_handler(new chat_server_handler());
-
- // create a server that listens on port `port` and uses our handler
- websocketpp::basic_server_ptr server(new websocketpp::basic_server(port,default_handler));
-
- server->elog().set_levels(websocketpp::log::elevel::DEVEL,websocketpp::log::elevel::FATAL);
-
- server->alog().set_level(websocketpp::log::alevel::ALL);
-
- // setup server settings
- // Chat server should only be receiving small text messages, reduce max
- // message size limit slightly to save memory, improve performance, and
- // guard against DoS attacks.
- //server->set_max_message_size(0xFFFF); // 64KiB
-
- std::cout << "Starting chat server on port " << port << std::endl;
-
- server->run();
- } catch (std::exception& e) {
- std::cerr << "Exception: " << e.what() << std::endl;
- }
-
- return 0;
+ short port = 9003;
+
+ if (argc == 2) {
+ // TODO: input validation?
+ port = atoi(argv[2]);
+ }
+
+ try {
+ // create an instance of our handler
+ server_handler_ptr default_handler(new chat_server_handler());
+
+ // create a server that listens on port `port` and uses our handler
+ websocketpp::basic_server_ptr server(new websocketpp::basic_server(port,default_handler));
+
+ server->elog().set_levels(websocketpp::log::elevel::DEVEL,websocketpp::log::elevel::FATAL);
+
+ server->alog().set_level(websocketpp::log::alevel::ALL);
+
+ // setup server settings
+ // Chat server should only be receiving small text messages, reduce max
+ // message size limit slightly to save memory, improve performance, and
+ // guard against DoS attacks.
+ //server->set_max_message_size(0xFFFF); // 64KiB
+
+ std::cout << "Starting chat server on port " << port << std::endl;
+
+ server->run();
+ } catch (std::exception& e) {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+
+ return 0;
}
diff --git a/examples/echo_client/echo_client.cpp b/examples/echo_client/echo_client.cpp
index a9aad73028..84f5ecf978 100644
--- a/examples/echo_client/echo_client.cpp
+++ b/examples/echo_client/echo_client.cpp
@@ -36,72 +36,72 @@ typedef plain_endpoint_type::connection_ptr connection_ptr;
class echo_client_handler : public plain_endpoint_type::handler {
public:
- typedef echo_client_handler type;
- typedef plain_endpoint_type::connection_ptr connection_ptr;
-
- void on_message(connection_ptr connection,websocketpp::message::data::ptr msg) {
- if (connection->get_resource() == "/getCaseCount") {
- std::cout << "Detected " << msg->get_payload() << " test cases." << std::endl;
- m_case_count = atoi(msg->get_payload().c_str());
- } else {
- connection->send(msg->get_payload(),msg->get_opcode());
- }
- }
-
- void http(connection_ptr connection) {
- //connection->set_body("HTTP Response!!");
- }
-
- void on_fail(connection_ptr connection) {
- std::cout << "connection failed" << std::endl;
- }
-
- int m_case_count;
+ typedef echo_client_handler type;
+ typedef plain_endpoint_type::connection_ptr connection_ptr;
+
+ void on_message(connection_ptr connection,websocketpp::message::data::ptr msg) {
+ if (connection->get_resource() == "/getCaseCount") {
+ std::cout << "Detected " << msg->get_payload() << " test cases." << std::endl;
+ m_case_count = atoi(msg->get_payload().c_str());
+ } else {
+ connection->send(msg->get_payload(),msg->get_opcode());
+ }
+ }
+
+ void http(connection_ptr connection) {
+ //connection->set_body("HTTP Response!!");
+ }
+
+ void on_fail(connection_ptr connection) {
+ std::cout << "connection failed" << std::endl;
+ }
+
+ int m_case_count;
};
int main(int argc, char* argv[]) {
- std::string uri = "ws://localhost:9001/";
-
- if (argc > 2) {
- std::cout << "Usage: `echo_client test_url`" << std::endl;
- } else {
- uri = argv[1];
- }
-
- try {
- plain_handler_ptr handler(new echo_client_handler());
+ std::string uri = "ws://localhost:9001/";
+
+ if (argc > 2) {
+ std::cout << "Usage: `echo_client test_url`" << std::endl;
+ } else {
+ uri = argv[1];
+ }
+
+ try {
+ plain_handler_ptr handler(new echo_client_handler());
connection_ptr connection;
- plain_endpoint_type endpoint(handler);
-
- endpoint.alog().unset_level(websocketpp::log::alevel::ALL);
- endpoint.elog().unset_level(websocketpp::log::elevel::ALL);
-
- connection = endpoint.connect(uri+"getCaseCount");
-
+ plain_endpoint_type endpoint(handler);
+
+ endpoint.alog().unset_level(websocketpp::log::alevel::ALL);
+ endpoint.elog().unset_level(websocketpp::log::elevel::ALL);
+
+ connection = endpoint.connect(uri+"getCaseCount");
+
connection->add_request_header("User Agent","WebSocket++/0.2.0");
endpoint.run();
-
- std::cout << "case count: " << boost::dynamic_pointer_cast(handler)->m_case_count << std::endl;
-
- for (int i = 1; i <= boost::dynamic_pointer_cast(handler)->m_case_count; i++) {
- endpoint.reset();
-
- std::stringstream url;
-
- url << uri << "/runCase?case=" << i << "&agent=\"WebSocket++/0.2.0\"";
-
+
+ std::cout << "case count: " << boost::dynamic_pointer_cast(handler)->m_case_count << std::endl;
+
+ for (int i = 1; i <= boost::dynamic_pointer_cast(handler)->m_case_count; i++) {
+ endpoint.reset();
+
+ std::stringstream url;
+
+ url << uri << "/runCase?case=" << i << "&agent=\"WebSocket++/0.2.0\"";
+
connection = endpoint.connect(url.str());
-
- endpoint.run();
- }
-
- std::cout << "done" << std::endl;
-
- } catch (std::exception& e) {
- std::cerr << "Exception: " << e.what() << std::endl;
- }
-
- return 0;
+
+ endpoint.run();
+ }
+
+ std::cout << "done" << std::endl;
+
+ } catch (std::exception& e) {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+
+ return 0;
}
diff --git a/examples/echo_client/echo_client_handler.cpp b/examples/echo_client/echo_client_handler.cpp
index b91b4d69f1..4b0055ceea 100644
--- a/examples/echo_client/echo_client_handler.cpp
+++ b/examples/echo_client/echo_client_handler.cpp
@@ -34,23 +34,23 @@ using websocketecho::echo_client_handler;
using websocketpp::client_session_ptr;
void echo_client_handler::on_open(session_ptr s) {
- std::cout << " Successfully connected (handshake complete): " << s->get_resource() << std::endl;
+ std::cout << " Successfully connected (handshake complete): " << s->get_resource() << std::endl;
}
void echo_client_handler::on_close(session_ptr s) {
- std::cout << " client was disconnected (WS state is now CLOSED)" << std::endl;
+ std::cout << " client was disconnected (WS state is now CLOSED)" << std::endl;
}
void echo_client_handler::on_message(session_ptr s,const std::string &msg) {
- if (s->get_resource() == "/getCaseCount") {
- std::cout << "Detected " << msg << " test cases." << std::endl;
- m_case_count = atoi(msg.c_str());
- } else {
- s->send(msg);
- }
+ if (s->get_resource() == "/getCaseCount") {
+ std::cout << "Detected " << msg << " test cases." << std::endl;
+ m_case_count = atoi(msg.c_str());
+ } else {
+ s->send(msg);
+ }
}
void echo_client_handler::on_message(session_ptr s,
- const std::vector &data) {
- s->send(data);
+ const std::vector &data) {
+ s->send(data);
}
\ No newline at end of file
diff --git a/examples/echo_client/echo_client_handler.hpp b/examples/echo_client/echo_client_handler.hpp
index 5610e08c31..05425f2b50 100644
--- a/examples/echo_client/echo_client_handler.hpp
+++ b/examples/echo_client/echo_client_handler.hpp
@@ -51,22 +51,22 @@ namespace websocketecho {
class echo_client_handler : public websocketpp::connection_handler {
public:
- echo_client_handler() : m_case_count(0) {}
- virtual ~echo_client_handler() {}
-
- // connection to chat room complete
- void on_open(session_ptr s);
+ echo_client_handler() : m_case_count(0) {}
+ virtual ~echo_client_handler() {}
+
+ // connection to chat room complete
+ void on_open(session_ptr s);
- // connection to chat room closed
- void on_close(session_ptr sn);
-
- // got a new message from server
- void on_message(session_ptr s,const std::string &msg);
-
- // ignore messages
- void on_message(session_ptr s,const std::vector &data);
-
- int m_case_count;
+ // connection to chat room closed
+ void on_close(session_ptr sn);
+
+ // got a new message from server
+ void on_message(session_ptr s,const std::string &msg);
+
+ // ignore messages
+ void on_message(session_ptr s,const std::vector &data);
+
+ int m_case_count;
};
typedef boost::shared_ptr echo_client_handler_ptr;
diff --git a/examples/echo_server/echo.hpp b/examples/echo_server/echo.hpp
index 48e8948d6c..a6aac7a373 100644
--- a/examples/echo_server/echo.hpp
+++ b/examples/echo_server/echo.hpp
@@ -42,23 +42,23 @@ namespace websocketecho {
class echo_server_handler : public server_handler {
public:
- // The echo server allows all domains is protocol free.
- void validate(server_ptr session) {}
-
- // an echo server is stateless.
- // The handler has no need to keep track of connected clients.
- void on_fail(server_ptr session) {}
- void on_open(server_ptr session) {}
- void on_close(server_ptr session) {}
-
- // both text and binary messages are echoed back to the sending client.
- void on_message(server_ptr session,websocketpp::utf8_string_ptr msg) {
- std::cout << *msg << std::endl;
- session->send(*msg);
- }
- void on_message(server_ptr session,websocketpp::binary_string_ptr data) {
- session->send(*data);
- }
+ // The echo server allows all domains is protocol free.
+ void validate(server_ptr session) {}
+
+ // an echo server is stateless.
+ // The handler has no need to keep track of connected clients.
+ void on_fail(server_ptr session) {}
+ void on_open(server_ptr session) {}
+ void on_close(server_ptr session) {}
+
+ // both text and binary messages are echoed back to the sending client.
+ void on_message(server_ptr session,websocketpp::utf8_string_ptr msg) {
+ std::cout << *msg << std::endl;
+ session->send(*msg);
+ }
+ void on_message(server_ptr session,websocketpp::binary_string_ptr data) {
+ session->send(*data);
+ }
};
}
diff --git a/examples/echo_server/echo_client.html b/examples/echo_server/echo_client.html
index cd46a17a72..dc36396a24 100644
--- a/examples/echo_server/echo_client.html
+++ b/examples/echo_server/echo_client.html
@@ -9,84 +9,84 @@ var ws;
var url;
function connect() {
- url = document.getElementById("server_url").value;
- console.log(url);
-
- if ("WebSocket" in window) {
- ws = new WebSocket(url);
- } else if ("MozWebSocket" in window) {
- ws = new MozWebSocket(url);
- } else {
- document.getElementById("messages").innerHTML += "This Browser does not support WebSockets
";
- return;
- }
- ws.onopen = function(e) {
- document.getElementById("messages").innerHTML += "Client: A connection to "+ws.URL+" has been opened.
";
-
- document.getElementById("server_url").disabled = true;
- document.getElementById("toggle_connect").innerHTML = "Disconnect";
- };
-
- ws.onerror = function(e) {
- document.getElementById("messages").innerHTML += "Client: An error occured, see console log for more details.
";
- console.log(e);
- };
-
- ws.onclose = function(e) {
- document.getElementById("messages").innerHTML += "Client: The connection to "+url+" was closed.
";
- };
-
- ws.onmessage = function(e) {
- document.getElementById("messages").innerHTML += "Server: "+e.data+"
";
- };
+ url = document.getElementById("server_url").value;
+ console.log(url);
+
+ if ("WebSocket" in window) {
+ ws = new WebSocket(url);
+ } else if ("MozWebSocket" in window) {
+ ws = new MozWebSocket(url);
+ } else {
+ document.getElementById("messages").innerHTML += "This Browser does not support WebSockets
";
+ return;
+ }
+ ws.onopen = function(e) {
+ document.getElementById("messages").innerHTML += "Client: A connection to "+ws.URL+" has been opened.
";
+
+ document.getElementById("server_url").disabled = true;
+ document.getElementById("toggle_connect").innerHTML = "Disconnect";
+ };
+
+ ws.onerror = function(e) {
+ document.getElementById("messages").innerHTML += "Client: An error occured, see console log for more details.
";
+ console.log(e);
+ };
+
+ ws.onclose = function(e) {
+ document.getElementById("messages").innerHTML += "Client: The connection to "+url+" was closed.
";
+ };
+
+ ws.onmessage = function(e) {
+ document.getElementById("messages").innerHTML += "Server: "+e.data+"
";
+ };
}
function disconnect() {
- ws.close();
- document.getElementById("server_url").disabled = false;
- document.getElementById("toggle_connect").innerHTML = "Connect";
+ ws.close();
+ document.getElementById("server_url").disabled = false;
+ document.getElementById("toggle_connect").innerHTML = "Connect";
}
function toggle_connect() {
- if (document.getElementById("server_url").disabled === false) {
- connect();
- } else {
- disconnect();
- }
+ if (document.getElementById("server_url").disabled === false) {
+ connect();
+ } else {
+ disconnect();
+ }
}
function send() {
- if (ws === undefined || ws.readyState != 1) {
- document.getElementById("messages").innerHTML += "Client: Websocket is not avaliable for writing
";
- return;
- }
-
- ws.send(document.getElementById("msg").value);
- document.getElementById("msg").value = "";
+ if (ws === undefined || ws.readyState != 1) {
+ document.getElementById("messages").innerHTML += "Client: Websocket is not avaliable for writing
";
+ return;
+ }
+
+ ws.send(document.getElementById("msg").value);
+ document.getElementById("msg").value = "";
}
diff --git a/examples/echo_server/echo_server.cpp b/examples/echo_server/echo_server.cpp
index 779a113400..4da19ce3c3 100644
--- a/examples/echo_server/echo_server.cpp
+++ b/examples/echo_server/echo_server.cpp
@@ -35,37 +35,37 @@ typedef endpoint_type::handler_ptr handler_ptr;
class echo_server_handler : public endpoint_type::handler {
public:
- typedef endpoint_type::connection_ptr connection_ptr;
-
- void on_message(connection_ptr connection,websocketpp::message::data_ptr msg) {
- connection->send(msg->get_payload(),msg->get_opcode());
- }
+ typedef endpoint_type::connection_ptr connection_ptr;
+
+ void on_message(connection_ptr connection,websocketpp::message::data_ptr msg) {
+ connection->send(msg->get_payload(),msg->get_opcode());
+ }
};
int main(int argc, char* argv[]) {
- unsigned short port = 9002;
-
- if (argc == 2) {
- port = atoi(argv[1]);
+ unsigned short port = 9002;
+
+ if (argc == 2) {
+ port = atoi(argv[1]);
if (port == 0) {
std::cout << "Unable to parse port input " << argv[1] << std::endl;
return 1;
}
- }
-
- try {
- handler_ptr h(new echo_server_handler());
- endpoint_type e(h);
-
- e.alog().unset_level(websocketpp::log::alevel::ALL);
- e.elog().unset_level(websocketpp::log::elevel::ALL);
-
- std::cout << "Starting WebSocket echo server on port " << port << std::endl;
- e.listen(port);
- } catch (std::exception& e) {
- std::cerr << "Exception: " << e.what() << std::endl;
- }
-
- return 0;
+ }
+
+ try {
+ handler_ptr h(new echo_server_handler());
+ endpoint_type e(h);
+
+ e.alog().unset_level(websocketpp::log::alevel::ALL);
+ e.elog().unset_level(websocketpp::log::elevel::ALL);
+
+ std::cout << "Starting WebSocket echo server on port " << port << std::endl;
+ e.listen(port);
+ } catch (std::exception& e) {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+
+ return 0;
}
diff --git a/examples/echo_server_tls/echo.hpp b/examples/echo_server_tls/echo.hpp
index 48e8948d6c..a6aac7a373 100644
--- a/examples/echo_server_tls/echo.hpp
+++ b/examples/echo_server_tls/echo.hpp
@@ -42,23 +42,23 @@ namespace websocketecho {
class echo_server_handler : public server_handler {
public:
- // The echo server allows all domains is protocol free.
- void validate(server_ptr session) {}
-
- // an echo server is stateless.
- // The handler has no need to keep track of connected clients.
- void on_fail(server_ptr session) {}
- void on_open(server_ptr session) {}
- void on_close(server_ptr session) {}
-
- // both text and binary messages are echoed back to the sending client.
- void on_message(server_ptr session,websocketpp::utf8_string_ptr msg) {
- std::cout << *msg << std::endl;
- session->send(*msg);
- }
- void on_message(server_ptr session,websocketpp::binary_string_ptr data) {
- session->send(*data);
- }
+ // The echo server allows all domains is protocol free.
+ void validate(server_ptr session) {}
+
+ // an echo server is stateless.
+ // The handler has no need to keep track of connected clients.
+ void on_fail(server_ptr session) {}
+ void on_open(server_ptr session) {}
+ void on_close(server_ptr session) {}
+
+ // both text and binary messages are echoed back to the sending client.
+ void on_message(server_ptr session,websocketpp::utf8_string_ptr msg) {
+ std::cout << *msg << std::endl;
+ session->send(*msg);
+ }
+ void on_message(server_ptr session,websocketpp::binary_string_ptr data) {
+ session->send(*data);
+ }
};
}
diff --git a/examples/echo_server_tls/echo_client.html b/examples/echo_server_tls/echo_client.html
index cd46a17a72..dc36396a24 100644
--- a/examples/echo_server_tls/echo_client.html
+++ b/examples/echo_server_tls/echo_client.html
@@ -9,84 +9,84 @@ var ws;
var url;
function connect() {
- url = document.getElementById("server_url").value;
- console.log(url);
-
- if ("WebSocket" in window) {
- ws = new WebSocket(url);
- } else if ("MozWebSocket" in window) {
- ws = new MozWebSocket(url);
- } else {
- document.getElementById("messages").innerHTML += "This Browser does not support WebSockets
";
- return;
- }
- ws.onopen = function(e) {
- document.getElementById("messages").innerHTML += "Client: A connection to "+ws.URL+" has been opened.
";
-
- document.getElementById("server_url").disabled = true;
- document.getElementById("toggle_connect").innerHTML = "Disconnect";
- };
-
- ws.onerror = function(e) {
- document.getElementById("messages").innerHTML += "Client: An error occured, see console log for more details.
";
- console.log(e);
- };
-
- ws.onclose = function(e) {
- document.getElementById("messages").innerHTML += "Client: The connection to "+url+" was closed.
";
- };
-
- ws.onmessage = function(e) {
- document.getElementById("messages").innerHTML += "Server: "+e.data+"
";
- };
+ url = document.getElementById("server_url").value;
+ console.log(url);
+
+ if ("WebSocket" in window) {
+ ws = new WebSocket(url);
+ } else if ("MozWebSocket" in window) {
+ ws = new MozWebSocket(url);
+ } else {
+ document.getElementById("messages").innerHTML += "This Browser does not support WebSockets
";
+ return;
+ }
+ ws.onopen = function(e) {
+ document.getElementById("messages").innerHTML += "Client: A connection to "+ws.URL+" has been opened.
";
+
+ document.getElementById("server_url").disabled = true;
+ document.getElementById("toggle_connect").innerHTML = "Disconnect";
+ };
+
+ ws.onerror = function(e) {
+ document.getElementById("messages").innerHTML += "Client: An error occured, see console log for more details.
";
+ console.log(e);
+ };
+
+ ws.onclose = function(e) {
+ document.getElementById("messages").innerHTML += "Client: The connection to "+url+" was closed.
";
+ };
+
+ ws.onmessage = function(e) {
+ document.getElementById("messages").innerHTML += "Server: "+e.data+"
";
+ };
}
function disconnect() {
- ws.close();
- document.getElementById("server_url").disabled = false;
- document.getElementById("toggle_connect").innerHTML = "Connect";
+ ws.close();
+ document.getElementById("server_url").disabled = false;
+ document.getElementById("toggle_connect").innerHTML = "Connect";
}
function toggle_connect() {
- if (document.getElementById("server_url").disabled === false) {
- connect();
- } else {
- disconnect();
- }
+ if (document.getElementById("server_url").disabled === false) {
+ connect();
+ } else {
+ disconnect();
+ }
}
function send() {
- if (ws === undefined || ws.readyState != 1) {
- document.getElementById("messages").innerHTML += "Client: Websocket is not avaliable for writing
";
- return;
- }
-
- ws.send(document.getElementById("msg").value);
- document.getElementById("msg").value = "";
+ if (ws === undefined || ws.readyState != 1) {
+ document.getElementById("messages").innerHTML += "Client: Websocket is not avaliable for writing
";
+ return;
+ }
+
+ ws.send(document.getElementById("msg").value);
+ document.getElementById("msg").value = "";
}
diff --git a/examples/echo_server_tls/echo_server_tls.cpp b/examples/echo_server_tls/echo_server_tls.cpp
index 9d87014af0..0001d643a3 100644
--- a/examples/echo_server_tls/echo_server_tls.cpp
+++ b/examples/echo_server_tls/echo_server_tls.cpp
@@ -39,83 +39,83 @@ typedef tls_endpoint_type::handler_ptr tls_handler_ptr;
template
class echo_server_handler : public endpoint_type::handler {
public:
- typedef echo_server_handler type;
- typedef typename endpoint_type::connection_ptr connection_ptr;
-
- std::string get_password() const {
- return "test";
- }
-
- boost::shared_ptr on_tls_init() {
- // create a tls context, init, and return.
- boost::shared_ptr context(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
- try {
- context->set_options(boost::asio::ssl::context::default_workarounds |
- boost::asio::ssl::context::no_sslv2 |
- boost::asio::ssl::context::single_dh_use);
- context->set_password_callback(boost::bind(&type::get_password, this));
- context->use_certificate_chain_file("/Users/zaphoyd/Documents/ZS/websocketpp/src/ssl/server.pem");
- context->use_private_key_file("/Users/zaphoyd/Documents/ZS/websocketpp/src/ssl/server.pem", boost::asio::ssl::context::pem);
- context->use_tmp_dh_file("/Users/zaphoyd/Documents/ZS/websocketpp/src/ssl/dh512.pem");
- } catch (std::exception& e) {
- std::cout << e.what() << std::endl;
- }
- return context;
- }
-
- void on_message(connection_ptr connection,websocketpp::message::data_ptr msg) {
- connection->send(msg->get_payload(),msg->get_opcode());
- }
-
- void http(connection_ptr connection) {
- connection->set_body("HTTP Response!!");
- }
+ typedef echo_server_handler type;
+ typedef typename endpoint_type::connection_ptr connection_ptr;
+
+ std::string get_password() const {
+ return "test";
+ }
+
+ boost::shared_ptr on_tls_init() {
+ // create a tls context, init, and return.
+ boost::shared_ptr context(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
+ try {
+ context->set_options(boost::asio::ssl::context::default_workarounds |
+ boost::asio::ssl::context::no_sslv2 |
+ boost::asio::ssl::context::single_dh_use);
+ context->set_password_callback(boost::bind(&type::get_password, this));
+ context->use_certificate_chain_file("/Users/zaphoyd/Documents/ZS/websocketpp/src/ssl/server.pem");
+ context->use_private_key_file("/Users/zaphoyd/Documents/ZS/websocketpp/src/ssl/server.pem", boost::asio::ssl::context::pem);
+ context->use_tmp_dh_file("/Users/zaphoyd/Documents/ZS/websocketpp/src/ssl/dh512.pem");
+ } catch (std::exception& e) {
+ std::cout << e.what() << std::endl;
+ }
+ return context;
+ }
+
+ void on_message(connection_ptr connection,websocketpp::message::data_ptr msg) {
+ connection->send(msg->get_payload(),msg->get_opcode());
+ }
+
+ void http(connection_ptr connection) {
+ connection->set_body("HTTP Response!!");
+ }
};
int main(int argc, char* argv[]) {
- unsigned short port = 9002;
- bool tls = false;
-
- if (argc >= 2) {
- port = atoi(argv[1]);
+ unsigned short port = 9002;
+ bool tls = false;
+
+ if (argc >= 2) {
+ port = atoi(argv[1]);
if (port == 0) {
std::cout << "Unable to parse port input " << argv[1] << std::endl;
return 1;
}
- }
-
- if (argc == 3) {
- tls = !strcmp(argv[2],"-tls");
- }
-
- try {
- if (tls) {
- tls_handler_ptr h(new echo_server_handler());
- tls_endpoint_type e(h);
-
- e.alog().unset_level(websocketpp::log::alevel::ALL);
- e.elog().unset_level(websocketpp::log::elevel::ALL);
-
- std::cout << "Starting Secure WebSocket echo server on port "
+ }
+
+ if (argc == 3) {
+ tls = !strcmp(argv[2],"-tls");
+ }
+
+ try {
+ if (tls) {
+ tls_handler_ptr h(new echo_server_handler());
+ tls_endpoint_type e(h);
+
+ e.alog().unset_level(websocketpp::log::alevel::ALL);
+ e.elog().unset_level(websocketpp::log::elevel::ALL);
+
+ std::cout << "Starting Secure WebSocket echo server on port "
<< port << std::endl;
- e.listen(port);
- } else {
- plain_handler_ptr h(new echo_server_handler());
- plain_endpoint_type e(h);
-
- e.alog().unset_level(websocketpp::log::alevel::ALL);
- e.elog().unset_level(websocketpp::log::elevel::ALL);
-
- std::cout << "Starting WebSocket echo server on port "
+ e.listen(port);
+ } else {
+ plain_handler_ptr h(new echo_server_handler());
+ plain_endpoint_type e(h);
+
+ e.alog().unset_level(websocketpp::log::alevel::ALL);
+ e.elog().unset_level(websocketpp::log::elevel::ALL);
+
+ std::cout << "Starting WebSocket echo server on port "
<< port << std::endl;
- e.listen(port);
- }
-
-
- } catch (std::exception& e) {
- std::cerr << "Exception: " << e.what() << std::endl;
- }
-
- return 0;
+ e.listen(port);
+ }
+
+
+ } catch (std::exception& e) {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+
+ return 0;
}
diff --git a/examples/fuzzing_client/fuzzing_client.cpp b/examples/fuzzing_client/fuzzing_client.cpp
index 407424cd39..f44821a56d 100644
--- a/examples/fuzzing_client/fuzzing_client.cpp
+++ b/examples/fuzzing_client/fuzzing_client.cpp
@@ -37,229 +37,229 @@ typedef plain_endpoint_type::connection_ptr connection_ptr;
// base test case handler
class test_case_handler : public plain_endpoint_type::handler {
public:
- typedef test_case_handler type;
- typedef plain_endpoint_type::connection_ptr connection_ptr;
-
- virtual void end(connection_ptr connection) {
- // test is over, give control back to controlling handler
- boost::posix_time::time_period len(m_start_time,m_end_time);
-
- if (m_pass) {
- std::cout << " passes in " << len.length() << std::endl;
- } else {
- std::cout << " fails in " << len.length() << std::endl;
- }
-
- connection->close(websocketpp::close::status::NORMAL,"");
- }
+ typedef test_case_handler type;
+ typedef plain_endpoint_type::connection_ptr connection_ptr;
+
+ virtual void end(connection_ptr connection) {
+ // test is over, give control back to controlling handler
+ boost::posix_time::time_period len(m_start_time,m_end_time);
+
+ if (m_pass) {
+ std::cout << " passes in " << len.length() << std::endl;
+ } else {
+ std::cout << " fails in " << len.length() << std::endl;
+ }
+
+ connection->close(websocketpp::close::status::NORMAL,"");
+ }
protected:
- bool m_pass;
- boost::posix_time::ptime m_start_time;
- boost::posix_time::ptime m_end_time;
+ bool m_pass;
+ boost::posix_time::ptime m_start_time;
+ boost::posix_time::ptime m_end_time;
};
// test class for 9.1.* and 9.2.*
class test_9_1_X : public test_case_handler {
-public:
- test_9_1_X(int minor, int subtest) : m_minor(minor),m_subtest(subtest){
- // needs more C++11 intializer lists =(
- m_test_sizes[0] = 65536;
- m_test_sizes[1] = 262144;
- m_test_sizes[2] = 1048576;
- m_test_sizes[3] = 4194304;
- m_test_sizes[4] = 8388608;
- m_test_sizes[5] = 16777216;
- }
-
- void on_open(connection_ptr connection) {
- std::cout << "Test 9." << m_minor << "." << m_subtest;
-
-
-
- m_data.reserve(m_test_sizes[m_subtest-1]);
-
- if (m_minor == 1) {
- fill_utf8(connection,true);
- m_start_time = boost::posix_time::microsec_clock::local_time();
- connection->send(m_data,false);
- } else if (m_minor == 2) {
- fill_binary(connection,true);
- m_start_time = boost::posix_time::microsec_clock::local_time();
- connection->send(m_data,true);
- } else {
- std::cout << " has unknown definition." << std::endl;
- }
- }
-
- // Just does random ascii right now. True random UTF8 with multi-byte stuff
- // would probably be better
- void fill_utf8(connection_ptr connection,bool random = true) {
- if (random) {
- uint32_t data;
- for (int i = 0; i < m_test_sizes[m_subtest-1]; i++) {
- if (i%4 == 0) {
- data = uint32_t(connection->rand());
- }
-
- m_data.push_back(char(((reinterpret_cast(&data)[i%4])%95)+32));
- }
- } else {
- m_data.assign(m_test_sizes[m_subtest-1],'*');
- }
- }
-
- void fill_binary(connection_ptr connection, bool random = true) {
- if (random) {
- int32_t data;
- for (int i = 0; i < m_test_sizes[m_subtest-1]; i++) {
- if (i%4 == 0) {
- data = connection->rand();
- }
-
- m_data.push_back((reinterpret_cast(&data))[i%4]);
- }
- } else {
- m_data.assign(m_test_sizes[m_subtest-1],'*');
- }
- }
-
- void on_message(connection_ptr connection,websocketpp::message::data_ptr msg) {
- m_end_time = boost::posix_time::microsec_clock::local_time();
-
- // Check whether the echoed data matches exactly
- m_pass = (msg->get_payload() == m_data);
-
- connection->recycle(msg);
- this->end(connection);
- }
+public:
+ test_9_1_X(int minor, int subtest) : m_minor(minor),m_subtest(subtest){
+ // needs more C++11 intializer lists =(
+ m_test_sizes[0] = 65536;
+ m_test_sizes[1] = 262144;
+ m_test_sizes[2] = 1048576;
+ m_test_sizes[3] = 4194304;
+ m_test_sizes[4] = 8388608;
+ m_test_sizes[5] = 16777216;
+ }
+
+ void on_open(connection_ptr connection) {
+ std::cout << "Test 9." << m_minor << "." << m_subtest;
+
+
+
+ m_data.reserve(m_test_sizes[m_subtest-1]);
+
+ if (m_minor == 1) {
+ fill_utf8(connection,true);
+ m_start_time = boost::posix_time::microsec_clock::local_time();
+ connection->send(m_data,false);
+ } else if (m_minor == 2) {
+ fill_binary(connection,true);
+ m_start_time = boost::posix_time::microsec_clock::local_time();
+ connection->send(m_data,true);
+ } else {
+ std::cout << " has unknown definition." << std::endl;
+ }
+ }
+
+ // Just does random ascii right now. True random UTF8 with multi-byte stuff
+ // would probably be better
+ void fill_utf8(connection_ptr connection,bool random = true) {
+ if (random) {
+ uint32_t data;
+ for (int i = 0; i < m_test_sizes[m_subtest-1]; i++) {
+ if (i%4 == 0) {
+ data = uint32_t(connection->rand());
+ }
+
+ m_data.push_back(char(((reinterpret_cast(&data)[i%4])%95)+32));
+ }
+ } else {
+ m_data.assign(m_test_sizes[m_subtest-1],'*');
+ }
+ }
+
+ void fill_binary(connection_ptr connection, bool random = true) {
+ if (random) {
+ int32_t data;
+ for (int i = 0; i < m_test_sizes[m_subtest-1]; i++) {
+ if (i%4 == 0) {
+ data = connection->rand();
+ }
+
+ m_data.push_back((reinterpret_cast(&data))[i%4]);
+ }
+ } else {
+ m_data.assign(m_test_sizes[m_subtest-1],'*');
+ }
+ }
+
+ void on_message(connection_ptr connection,websocketpp::message::data_ptr msg) {
+ m_end_time = boost::posix_time::microsec_clock::local_time();
+
+ // Check whether the echoed data matches exactly
+ m_pass = (msg->get_payload() == m_data);
+
+ connection->recycle(msg);
+ this->end(connection);
+ }
private:
- int m_minor;
- int m_subtest;
- size_t m_test_sizes[6];
- std::string m_data;
+ int m_minor;
+ int m_subtest;
+ size_t m_test_sizes[6];
+ std::string m_data;
};
// test class for 9.7.* and 9.8.*
/*class test_9_7_X : public test_case_handler {
-public:
- test_9_1_X(int minor, int subtest) : m_minor(minor),m_subtest(subtest){
- // needs more C++11 intializer lists =(
- m_test_sizes[0] = 65536;
- m_test_sizes[1] = 262144;
- m_test_sizes[2] = 1048576;
- m_test_sizes[3] = 4194304;
- m_test_sizes[4] = 8388608;
- m_test_sizes[5] = 16777216;
- }
-
- void on_open(connection_ptr connection) {
- std::cout << "Test 9." << m_minor << "." << m_subtest;
-
-
-
- m_data.reserve(m_test_sizes[m_subtest-1]);
-
- if (m_minor == 1) {
- fill_utf8(connection,true);
- m_start_time = boost::posix_time::microsec_clock::local_time();
- connection->send(m_data,false);
- } else if (m_minor == 2) {
- fill_binary(connection,true);
- m_start_time = boost::posix_time::microsec_clock::local_time();
- connection->send(m_data,true);
- } else {
- std::cout << " has unknown definition." << std::endl;
- }
- }
-
- // Just does random ascii right now. True random UTF8 with multi-byte stuff
- // would probably be better
- void fill_utf8(connection_ptr connection,bool random = true) {
- if (random) {
- uint32_t data;
- for (int i = 0; i < m_test_sizes[m_subtest-1]; i++) {
- if (i%4 == 0) {
- data = uint32_t(connection->rand());
- }
-
- m_data.push_back(char(((reinterpret_cast(&data)[i%4])%95)+32));
- }
- } else {
- m_data.assign(m_test_sizes[m_subtest-1],'*');
- }
- }
-
- void fill_binary(connection_ptr connection, bool random = true) {
- if (random) {
- int32_t data;
- for (int i = 0; i < m_test_sizes[m_subtest-1]; i++) {
- if (i%4 == 0) {
- data = connection->rand();
- }
-
- m_data.push_back((reinterpret_cast(&data))[i%4]);
- }
- } else {
- m_data.assign(m_test_sizes[m_subtest-1],'*');
- }
- }
-
- void on_message(connection_ptr connection,websocketpp::message::data_ptr msg) {
- m_end_time = boost::posix_time::microsec_clock::local_time();
-
- // Check whether the echoed data matches exactly
- m_pass = (msg->get_payload() == m_data);
-
- connection->recycle(msg);
- this->end(connection);
- }
+public:
+ test_9_1_X(int minor, int subtest) : m_minor(minor),m_subtest(subtest){
+ // needs more C++11 intializer lists =(
+ m_test_sizes[0] = 65536;
+ m_test_sizes[1] = 262144;
+ m_test_sizes[2] = 1048576;
+ m_test_sizes[3] = 4194304;
+ m_test_sizes[4] = 8388608;
+ m_test_sizes[5] = 16777216;
+ }
+
+ void on_open(connection_ptr connection) {
+ std::cout << "Test 9." << m_minor << "." << m_subtest;
+
+
+
+ m_data.reserve(m_test_sizes[m_subtest-1]);
+
+ if (m_minor == 1) {
+ fill_utf8(connection,true);
+ m_start_time = boost::posix_time::microsec_clock::local_time();
+ connection->send(m_data,false);
+ } else if (m_minor == 2) {
+ fill_binary(connection,true);
+ m_start_time = boost::posix_time::microsec_clock::local_time();
+ connection->send(m_data,true);
+ } else {
+ std::cout << " has unknown definition." << std::endl;
+ }
+ }
+
+ // Just does random ascii right now. True random UTF8 with multi-byte stuff
+ // would probably be better
+ void fill_utf8(connection_ptr connection,bool random = true) {
+ if (random) {
+ uint32_t data;
+ for (int i = 0; i < m_test_sizes[m_subtest-1]; i++) {
+ if (i%4 == 0) {
+ data = uint32_t(connection->rand());
+ }
+
+ m_data.push_back(char(((reinterpret_cast(&data)[i%4])%95)+32));
+ }
+ } else {
+ m_data.assign(m_test_sizes[m_subtest-1],'*');
+ }
+ }
+
+ void fill_binary(connection_ptr connection, bool random = true) {
+ if (random) {
+ int32_t data;
+ for (int i = 0; i < m_test_sizes[m_subtest-1]; i++) {
+ if (i%4 == 0) {
+ data = connection->rand();
+ }
+
+ m_data.push_back((reinterpret_cast(&data))[i%4]);
+ }
+ } else {
+ m_data.assign(m_test_sizes[m_subtest-1],'*');
+ }
+ }
+
+ void on_message(connection_ptr connection,websocketpp::message::data_ptr msg) {
+ m_end_time = boost::posix_time::microsec_clock::local_time();
+
+ // Check whether the echoed data matches exactly
+ m_pass = (msg->get_payload() == m_data);
+
+ connection->recycle(msg);
+ this->end(connection);
+ }
private:
- int m_minor;
- int m_subtest;
- size_t m_test_sizes[6];
- std::string m_data;
+ int m_minor;
+ int m_subtest;
+ size_t m_test_sizes[6];
+ std::string m_data;
};*/
int main(int argc, char* argv[]) {
- std::string uri;
-
-
-
- if (argc != 2) {
- uri = "ws://localhost:9002/";
- } else {
- uri = argv[1];
- }
-
- std::vector tests;
-
- for (int i = 1; i <= 2; i++) {
- for (int j = 1; j <= 6; j++) {
- tests.push_back(plain_handler_ptr(new test_9_1_X(i,j)));
- }
- }
-
- try {
- plain_endpoint_type endpoint(tests[0]);
-
- endpoint.alog().unset_level(websocketpp::log::alevel::ALL);
- endpoint.elog().unset_level(websocketpp::log::elevel::ALL);
-
- for (int i = 0; i < tests.size(); i++) {
- if (i > 0) {
- endpoint.reset();
- endpoint.set_handler(tests[i]);
- }
-
- endpoint.connect(uri);
- endpoint.run();
- }
+ std::string uri;
+
+
+
+ if (argc != 2) {
+ uri = "ws://localhost:9002/";
+ } else {
+ uri = argv[1];
+ }
+
+ std::vector tests;
+
+ for (int i = 1; i <= 2; i++) {
+ for (int j = 1; j <= 6; j++) {
+ tests.push_back(plain_handler_ptr(new test_9_1_X(i,j)));
+ }
+ }
+
+ try {
+ plain_endpoint_type endpoint(tests[0]);
- std::cout << "done" << std::endl;
-
- } catch (std::exception& e) {
- std::cerr << "Exception: " << e.what() << std::endl;
- }
-
- return 0;
+ endpoint.alog().unset_level(websocketpp::log::alevel::ALL);
+ endpoint.elog().unset_level(websocketpp::log::elevel::ALL);
+
+ for (int i = 0; i < tests.size(); i++) {
+ if (i > 0) {
+ endpoint.reset();
+ endpoint.set_handler(tests[i]);
+ }
+
+ endpoint.connect(uri);
+ endpoint.run();
+ }
+
+ std::cout << "done" << std::endl;
+
+ } catch (std::exception& e) {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+
+ return 0;
}
diff --git a/examples/fuzzing_server_tls/echo_client.html b/examples/fuzzing_server_tls/echo_client.html
index cd46a17a72..dc36396a24 100644
--- a/examples/fuzzing_server_tls/echo_client.html
+++ b/examples/fuzzing_server_tls/echo_client.html
@@ -9,84 +9,84 @@ var ws;
var url;
function connect() {
- url = document.getElementById("server_url").value;
- console.log(url);
-
- if ("WebSocket" in window) {
- ws = new WebSocket(url);
- } else if ("MozWebSocket" in window) {
- ws = new MozWebSocket(url);
- } else {
- document.getElementById("messages").innerHTML += "This Browser does not support WebSockets
";
- return;
- }
- ws.onopen = function(e) {
- document.getElementById("messages").innerHTML += "Client: A connection to "+ws.URL+" has been opened.
";
-
- document.getElementById("server_url").disabled = true;
- document.getElementById("toggle_connect").innerHTML = "Disconnect";
- };
-
- ws.onerror = function(e) {
- document.getElementById("messages").innerHTML += "Client: An error occured, see console log for more details.
";
- console.log(e);
- };
-
- ws.onclose = function(e) {
- document.getElementById("messages").innerHTML += "Client: The connection to "+url+" was closed.
";
- };
-
- ws.onmessage = function(e) {
- document.getElementById("messages").innerHTML += "Server: "+e.data+"
";
- };
+ url = document.getElementById("server_url").value;
+ console.log(url);
+
+ if ("WebSocket" in window) {
+ ws = new WebSocket(url);
+ } else if ("MozWebSocket" in window) {
+ ws = new MozWebSocket(url);
+ } else {
+ document.getElementById("messages").innerHTML += "This Browser does not support WebSockets
";
+ return;
+ }
+ ws.onopen = function(e) {
+ document.getElementById("messages").innerHTML += "Client: A connection to "+ws.URL+" has been opened.
";
+
+ document.getElementById("server_url").disabled = true;
+ document.getElementById("toggle_connect").innerHTML = "Disconnect";
+ };
+
+ ws.onerror = function(e) {
+ document.getElementById("messages").innerHTML += "Client: An error occured, see console log for more details.
";
+ console.log(e);
+ };
+
+ ws.onclose = function(e) {
+ document.getElementById("messages").innerHTML += "Client: The connection to "+url+" was closed.
";
+ };
+
+ ws.onmessage = function(e) {
+ document.getElementById("messages").innerHTML += "Server: "+e.data+"
";
+ };
}
function disconnect() {
- ws.close();
- document.getElementById("server_url").disabled = false;
- document.getElementById("toggle_connect").innerHTML = "Connect";
+ ws.close();
+ document.getElementById("server_url").disabled = false;
+ document.getElementById("toggle_connect").innerHTML = "Connect";
}
function toggle_connect() {
- if (document.getElementById("server_url").disabled === false) {
- connect();
- } else {
- disconnect();
- }
+ if (document.getElementById("server_url").disabled === false) {
+ connect();
+ } else {
+ disconnect();
+ }
}
function send() {
- if (ws === undefined || ws.readyState != 1) {
- document.getElementById("messages").innerHTML += "Client: Websocket is not avaliable for writing
";
- return;
- }
-
- ws.send(document.getElementById("msg").value);
- document.getElementById("msg").value = "";
+ if (ws === undefined || ws.readyState != 1) {
+ document.getElementById("messages").innerHTML += "Client: Websocket is not avaliable for writing
";
+ return;
+ }
+
+ ws.send(document.getElementById("msg").value);
+ document.getElementById("msg").value = "";
}
diff --git a/examples/fuzzing_server_tls/fuzzing_server_tls.cpp b/examples/fuzzing_server_tls/fuzzing_server_tls.cpp
index 96377cc5ee..8377d0cf60 100644
--- a/examples/fuzzing_server_tls/fuzzing_server_tls.cpp
+++ b/examples/fuzzing_server_tls/fuzzing_server_tls.cpp
@@ -41,142 +41,142 @@ typedef tls_endpoint_type::handler_ptr tls_handler_ptr;
template
class echo_server_handler : public endpoint_type::handler {
public:
- typedef echo_server_handler type;
- typedef typename endpoint_type::connection_ptr connection_ptr;
-
- std::string get_password() const {
- return "test";
- }
-
- boost::shared_ptr on_tls_init() {
- // create a tls context, init, and return.
- boost::shared_ptr context(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
- try {
- context->set_options(boost::asio::ssl::context::default_workarounds |
- boost::asio::ssl::context::no_sslv2 |
- boost::asio::ssl::context::single_dh_use);
- context->set_password_callback(boost::bind(&type::get_password, this));
- context->use_certificate_chain_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/server.pem");
- context->use_private_key_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/server.pem", boost::asio::ssl::context::pem);
- context->use_tmp_dh_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/dh512.pem");
- } catch (std::exception& e) {
- std::cout << e.what() << std::endl;
- }
- return context;
- }
-
- void validate(connection_ptr connection) {
- //std::cout << "state: " << connection->get_state() << std::endl;
-
-
-
-
- }
-
- void on_open(connection_ptr connection) {
- //std::cout << "connection opened" << std::endl;
- // extract user agent
- // start timer
- start_time = boost::posix_time::microsec_clock::local_time();
- // send message
- connection->send("abcd",true);
- // stop
- }
-
- void on_close(connection_ptr connection) {
- //std::cout << "connection closed" << std::endl;
- }
-
- void on_message(connection_ptr connection,websocketpp::message::data_ptr msg) {
- //std::cout << "got message: " << *msg << std::endl;
- //connection->send(msg->get_payload(),(msg->get_opcode() == websocketpp::frame::opcode::BINARY));
-
- end_time = boost::posix_time::microsec_clock::local_time();
-
- boost::posix_time::time_period len(start_time,end_time);
-
- if (msg->get_payload() == "abcd") {
- std::cout << "Pass in " << len.length() << std::endl;
- } else {
- std::cout << "Fail in " << len.length() << std::endl;
- }
-
- // stop timer
- // check if message was valid
-
- connection->recycle(msg);
- }
-
- void http(connection_ptr connection) {
- connection->set_body("HTTP Response!!");
- }
-
- void on_fail(connection_ptr connection) {
- std::cout << "connection failed" << std::endl;
- }
-
- boost::posix_time::ptime start_time;
- boost::posix_time::ptime end_time;
+ typedef echo_server_handler type;
+ typedef typename endpoint_type::connection_ptr connection_ptr;
+
+ std::string get_password() const {
+ return "test";
+ }
+
+ boost::shared_ptr on_tls_init() {
+ // create a tls context, init, and return.
+ boost::shared_ptr context(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
+ try {
+ context->set_options(boost::asio::ssl::context::default_workarounds |
+ boost::asio::ssl::context::no_sslv2 |
+ boost::asio::ssl::context::single_dh_use);
+ context->set_password_callback(boost::bind(&type::get_password, this));
+ context->use_certificate_chain_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/server.pem");
+ context->use_private_key_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/server.pem", boost::asio::ssl::context::pem);
+ context->use_tmp_dh_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/dh512.pem");
+ } catch (std::exception& e) {
+ std::cout << e.what() << std::endl;
+ }
+ return context;
+ }
+
+ void validate(connection_ptr connection) {
+ //std::cout << "state: " << connection->get_state() << std::endl;
+
+
+
+
+ }
+
+ void on_open(connection_ptr connection) {
+ //std::cout << "connection opened" << std::endl;
+ // extract user agent
+ // start timer
+ start_time = boost::posix_time::microsec_clock::local_time();
+ // send message
+ connection->send("abcd",true);
+ // stop
+ }
+
+ void on_close(connection_ptr connection) {
+ //std::cout << "connection closed" << std::endl;
+ }
+
+ void on_message(connection_ptr connection,websocketpp::message::data_ptr msg) {
+ //std::cout << "got message: " << *msg << std::endl;
+ //connection->send(msg->get_payload(),(msg->get_opcode() == websocketpp::frame::opcode::BINARY));
+
+ end_time = boost::posix_time::microsec_clock::local_time();
+
+ boost::posix_time::time_period len(start_time,end_time);
+
+ if (msg->get_payload() == "abcd") {
+ std::cout << "Pass in " << len.length() << std::endl;
+ } else {
+ std::cout << "Fail in " << len.length() << std::endl;
+ }
+
+ // stop timer
+ // check if message was valid
+
+ connection->recycle(msg);
+ }
+
+ void http(connection_ptr connection) {
+ connection->set_body("HTTP Response!!");
+ }
+
+ void on_fail(connection_ptr connection) {
+ std::cout << "connection failed" << std::endl;
+ }
+
+ boost::posix_time::ptime start_time;
+ boost::posix_time::ptime end_time;
};
int main(int argc, char* argv[]) {
- unsigned short port = 9002;
- bool tls = false;
-
- if (argc == 2) {
- // TODO: input validation?
- port = atoi(argv[1]);
- }
-
- if (argc == 3) {
- // TODO: input validation?
- port = atoi(argv[1]);
- tls = !strcmp(argv[2],"-tls");
- }
-
- try {
- if (tls) {
- tls_handler_ptr h(new echo_server_handler());
- tls_endpoint_type e(h);
-
- e.alog().unset_level(websocketpp::log::alevel::ALL);
- //e.alog().set_level(websocketpp::log::alevel::CONNECT);
- //e.alog().set_level(websocketpp::log::alevel::DISCONNECT);
- //e.alog().set_level(websocketpp::log::alevel::DEVEL);
- //e.alog().set_level(websocketpp::log::alevel::DEBUG_CLOSE);
- //e.alog().unset_level(websocketpp::log::alevel::DEBUG_HANDSHAKE);
-
- e.elog().unset_level(websocketpp::log::elevel::ALL);
- //e.elog().set_level(websocketpp::log::elevel::ERROR);
- //e.elog().set_level(websocketpp::log::elevel::FATAL);
-
- std::cout << "Starting Secure WebSocket echo server on port " << port << std::endl;
- e.listen(port);
- } else {
- plain_handler_ptr h(new echo_server_handler());
- plain_endpoint_type e(h);
-
- e.alog().unset_level(websocketpp::log::alevel::ALL);
- //e.alog().set_level(websocketpp::log::alevel::CONNECT);
- //e.alog().set_level(websocketpp::log::alevel::DISCONNECT);
- //e.alog().unset_level(websocketpp::log::alevel::DEBUG_HANDSHAKE);
-
- e.elog().unset_level(websocketpp::log::elevel::ALL);
- //e.elog().set_level(websocketpp::log::elevel::ERROR);
- //e.elog().set_level(websocketpp::log::elevel::FATAL);
-
- // TODO: fix
- //e.alog().set_level(websocketpp::log::alevel::CONNECT & websocketpp::log::alevel::DISCONNECT);
- //e.elog().set_levels(websocketpp::log::elevel::ERROR,websocketpp::log::elevel::FATAL);
-
- std::cout << "Starting WebSocket echo server on port " << port << std::endl;
- e.listen(port);
- }
-
-
- } catch (std::exception& e) {
- std::cerr << "Exception: " << e.what() << std::endl;
- }
-
- return 0;
+ unsigned short port = 9002;
+ bool tls = false;
+
+ if (argc == 2) {
+ // TODO: input validation?
+ port = atoi(argv[1]);
+ }
+
+ if (argc == 3) {
+ // TODO: input validation?
+ port = atoi(argv[1]);
+ tls = !strcmp(argv[2],"-tls");
+ }
+
+ try {
+ if (tls) {
+ tls_handler_ptr h(new echo_server_handler());
+ tls_endpoint_type e(h);
+
+ e.alog().unset_level(websocketpp::log::alevel::ALL);
+ //e.alog().set_level(websocketpp::log::alevel::CONNECT);
+ //e.alog().set_level(websocketpp::log::alevel::DISCONNECT);
+ //e.alog().set_level(websocketpp::log::alevel::DEVEL);
+ //e.alog().set_level(websocketpp::log::alevel::DEBUG_CLOSE);
+ //e.alog().unset_level(websocketpp::log::alevel::DEBUG_HANDSHAKE);
+
+ e.elog().unset_level(websocketpp::log::elevel::ALL);
+ //e.elog().set_level(websocketpp::log::elevel::ERROR);
+ //e.elog().set_level(websocketpp::log::elevel::FATAL);
+
+ std::cout << "Starting Secure WebSocket echo server on port " << port << std::endl;
+ e.listen(port);
+ } else {
+ plain_handler_ptr h(new echo_server_handler());
+ plain_endpoint_type e(h);
+
+ e.alog().unset_level(websocketpp::log::alevel::ALL);
+ //e.alog().set_level(websocketpp::log::alevel::CONNECT);
+ //e.alog().set_level(websocketpp::log::alevel::DISCONNECT);
+ //e.alog().unset_level(websocketpp::log::alevel::DEBUG_HANDSHAKE);
+
+ e.elog().unset_level(websocketpp::log::elevel::ALL);
+ //e.elog().set_level(websocketpp::log::elevel::ERROR);
+ //e.elog().set_level(websocketpp::log::elevel::FATAL);
+
+ // TODO: fix
+ //e.alog().set_level(websocketpp::log::alevel::CONNECT & websocketpp::log::alevel::DISCONNECT);
+ //e.elog().set_levels(websocketpp::log::elevel::ERROR,websocketpp::log::elevel::FATAL);
+
+ std::cout << "Starting WebSocket echo server on port " << port << std::endl;
+ e.listen(port);
+ }
+
+
+ } catch (std::exception& e) {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+
+ return 0;
}
diff --git a/examples/stress_client/stress_client.cpp b/examples/stress_client/stress_client.cpp
index 3529f81529..95cf17eb15 100644
--- a/examples/stress_client/stress_client.cpp
+++ b/examples/stress_client/stress_client.cpp
@@ -60,9 +60,9 @@ typedef plain_endpoint_type::connection_ptr connection_ptr;
class stress_client_handler : public plain_endpoint_type::handler {
public:
- typedef stress_client_handler type;
- typedef plain_endpoint_type::connection_ptr connection_ptr;
-
+ typedef stress_client_handler type;
+ typedef plain_endpoint_type::connection_ptr connection_ptr;
+
stress_client_handler(int num_connections)
: m_connections_max(num_connections),
m_connections_cur(0) {
@@ -71,10 +71,10 @@ public:
void on_open(connection_ptr connection) {
if (!m_timer) {
- m_timer.reset(new boost::asio::deadline_timer(connection->get_io_service(),boost::posix_time::seconds(0)));
- m_timer->expires_from_now(boost::posix_time::milliseconds(250));
- m_timer->async_wait(boost::bind(&type::on_timer,this,connection,boost::asio::placeholders::error));
- }
+ m_timer.reset(new boost::asio::deadline_timer(connection->get_io_service(),boost::posix_time::seconds(0)));
+ m_timer->expires_from_now(boost::posix_time::milliseconds(250));
+ m_timer->async_wait(boost::bind(&type::on_timer,this,connection,boost::asio::placeholders::error));
+ }
m_connections_cur++;
@@ -87,19 +87,19 @@ public:
}
}
- void on_message(connection_ptr connection, websocketpp::message::data::ptr msg) {
+ void on_message(connection_ptr connection, websocketpp::message::data::ptr msg) {
//std::cout << "got message of size: " << msg->get_payload().size() << std::endl;
m_msg_stats[websocketpp::md5_hash_hex(msg->get_payload())]++;
if (m_msg_stats[websocketpp::md5_hash_hex(msg->get_payload())] == m_connections_max) {
send_stats_update(connection);
}
- }
-
- void on_fail(connection_ptr connection) {
- std::cout << "connection failed" << std::endl;
- }
-
+ }
+
+ void on_fail(connection_ptr connection) {
+ std::cout << "connection failed" << std::endl;
+ }
+
void on_timer(connection_ptr connection,const boost::system::error_code& error) {
if (error) {
std::cout << "on_timer error" << std::endl;
@@ -109,14 +109,14 @@ public:
send_stats_update(connection);
m_timer->expires_from_now(boost::posix_time::milliseconds(250));
- m_timer->async_wait(boost::bind(&type::on_timer,this,connection,boost::asio::placeholders::error));
+ m_timer->async_wait(boost::bind(&type::on_timer,this,connection,boost::asio::placeholders::error));
}
void on_close(connection_ptr connection) {
m_timer->cancel();
}
- boost::posix_time::ptime m_start_time;
+ boost::posix_time::ptime m_start_time;
private:
void send_stats_update(connection_ptr connection) {
if (m_msg_stats.empty()) {
@@ -146,24 +146,24 @@ private:
int main(int argc, char* argv[]) {
- std::string uri = "ws://localhost:9002/";
- int num_connections = 100;
- int batch_size = 25;
+ std::string uri = "ws://localhost:9002/";
+ int num_connections = 100;
+ int batch_size = 25;
int delay_ms = 16;
-
- if (argc != 5) {
- std::cout << "Usage: `echo_client test_url num_connections batch_size delay_ms`" << std::endl;
- } else {
- uri = argv[1];
- num_connections = atoi(argv[2]);
- batch_size = atoi(argv[3]);
+
+ if (argc != 5) {
+ std::cout << "Usage: `echo_client test_url num_connections batch_size delay_ms`" << std::endl;
+ } else {
+ uri = argv[1];
+ num_connections = atoi(argv[2]);
+ batch_size = atoi(argv[3]);
delay_ms = atoi(argv[4]);
- }
-
- // 12288 is max OS X limit without changing kernal settings
+ }
+
+ // 12288 is max OS X limit without changing kernal settings
const rlim_t ideal_size = 200+num_connections;
rlim_t old_size;
- rlim_t old_max;
+ rlim_t old_max;
struct rlimit rl;
int result;
@@ -174,63 +174,63 @@ int main(int argc, char* argv[]) {
old_size = rl.rlim_cur;
old_max = rl.rlim_max;
-
+
if (rl.rlim_cur < ideal_size) {
std::cout << "Attempting to raise system file descriptor limit from " << rl.rlim_cur << " to " << ideal_size << std::endl;
- rl.rlim_cur = ideal_size;
+ rl.rlim_cur = ideal_size;
- if (rl.rlim_max < ideal_size) {
- rl.rlim_max = ideal_size;
- }
-
- result = setrlimit(RLIMIT_NOFILE, &rl);
+ if (rl.rlim_max < ideal_size) {
+ rl.rlim_max = ideal_size;
+ }
+
+ result = setrlimit(RLIMIT_NOFILE, &rl);
if (result == 0) {
std::cout << "Success" << std::endl;
- } else if (result == EPERM) {
- std::cout << "Failed. This server will be limited to " << old_size << " concurrent connections. Error code: Insufficient permissions. Try running process as root. system max: " << old_max << std::endl;
- } else {
- std::cout << "Failed. This server will be limited to " << old_size << " concurrent connections. Error code: " << errno << " system max: " << old_max << std::endl;
- }
+ } else if (result == EPERM) {
+ std::cout << "Failed. This server will be limited to " << old_size << " concurrent connections. Error code: Insufficient permissions. Try running process as root. system max: " << old_max << std::endl;
+ } else {
+ std::cout << "Failed. This server will be limited to " << old_size << " concurrent connections. Error code: " << errno << " system max: " << old_max << std::endl;
+ }
}
}
-
- try {
- plain_handler_ptr handler(new stress_client_handler(num_connections));
- plain_endpoint_type endpoint(handler);
-
- endpoint.alog().unset_level(websocketpp::log::alevel::ALL);
- endpoint.elog().set_level(websocketpp::log::elevel::ALL);
-
+
+ try {
+ plain_handler_ptr handler(new stress_client_handler(num_connections));
+ plain_endpoint_type endpoint(handler);
+
+ endpoint.alog().unset_level(websocketpp::log::alevel::ALL);
+ endpoint.elog().set_level(websocketpp::log::elevel::ALL);
+
//endpoint.alog().set_level(websocketpp::log::alevel::DEVEL);
//endpoint.alog().set_level(websocketpp::log::alevel::DEBUG_CLOSE);
- std::set connections;
-
- connections.insert(endpoint.connect(uri));
-
- boost::thread t(boost::bind(&plain_endpoint_type::run, &endpoint));
-
- std::cout << "launching " << num_connections << " connections to " << uri << " in batches of " << batch_size << std::endl;
-
+ std::set connections;
+
+ connections.insert(endpoint.connect(uri));
+
+ boost::thread t(boost::bind(&plain_endpoint_type::run, &endpoint));
+
+ std::cout << "launching " << num_connections << " connections to " << uri << " in batches of " << batch_size << std::endl;
+
boost::dynamic_pointer_cast(handler)->m_start_time = boost::posix_time::microsec_clock::local_time();
- for (int i = 0; i < num_connections-1; i++) {
- if (i % batch_size == 0) {
- //sleep(1);
+ for (int i = 0; i < num_connections-1; i++) {
+ if (i % batch_size == 0) {
+ //sleep(1);
msleep(delay_ms);
- }
- connections.insert(endpoint.connect(uri));
- }
-
- std::cout << "complete" << std::endl;
-
- t.join();
-
- std::cout << "done" << std::endl;
-
- } catch (std::exception& e) {
- std::cerr << "Exception: " << e.what() << std::endl;
- }
-
- return 0;
+ }
+ connections.insert(endpoint.connect(uri));
+ }
+
+ std::cout << "complete" << std::endl;
+
+ t.join();
+
+ std::cout << "done" << std::endl;
+
+ } catch (std::exception& e) {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ }
+
+ return 0;
}
diff --git a/src/common.hpp b/src/common.hpp
index d7f985cea4..ea7ab291dd 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -41,68 +41,68 @@
// Defaults
namespace websocketpp {
- typedef std::vector binary_string;
- typedef boost::shared_ptr binary_string_ptr;
-
- typedef std::string utf8_string;
- typedef boost::shared_ptr utf8_string_ptr;
-
- const uint64_t DEFAULT_MAX_MESSAGE_SIZE = 0xFFFFFF; // ~16MB
-
- const uint16_t DEFAULT_PORT = 80;
- const uint16_t DEFAULT_SECURE_PORT = 443;
-
- inline uint16_t default_port(bool secure) {
- return (secure ? DEFAULT_SECURE_PORT : DEFAULT_PORT);
- }
-
- namespace session {
- namespace state {
- enum value {
- CONNECTING = 0,
- OPEN = 1,
- CLOSING = 2,
- CLOSED = 3
- };
- }
- }
-
- namespace close {
- namespace status {
- enum value {
- INVALID_END = 999,
- NORMAL = 1000,
- GOING_AWAY = 1001,
- PROTOCOL_ERROR = 1002,
- UNSUPPORTED_DATA = 1003,
- RSV_ADHOC_1 = 1004,
- NO_STATUS = 1005,
- ABNORMAL_CLOSE = 1006,
- INVALID_PAYLOAD = 1007,
- POLICY_VIOLATION = 1008,
- MESSAGE_TOO_BIG = 1009,
- EXTENSION_REQUIRE = 1010,
- INTERNAL_ENDPOINT_ERROR = 1011,
- RSV_START = 1012,
- RSV_END = 2999,
- INVALID_START = 5000
- };
-
- inline bool reserved(value s) {
- return ((s >= RSV_START && s <= RSV_END) ||
- s == RSV_ADHOC_1);
- }
-
- inline bool invalid(value s) {
- return ((s <= INVALID_END || s >= INVALID_START) ||
- s == NO_STATUS ||
- s == ABNORMAL_CLOSE);
- }
-
- // TODO functions for application ranges?
- } // namespace status
- } // namespace close
-
+ typedef std::vector binary_string;
+ typedef boost::shared_ptr binary_string_ptr;
+
+ typedef std::string utf8_string;
+ typedef boost::shared_ptr utf8_string_ptr;
+
+ const uint64_t DEFAULT_MAX_MESSAGE_SIZE = 0xFFFFFF; // ~16MB
+
+ const uint16_t DEFAULT_PORT = 80;
+ const uint16_t DEFAULT_SECURE_PORT = 443;
+
+ inline uint16_t default_port(bool secure) {
+ return (secure ? DEFAULT_SECURE_PORT : DEFAULT_PORT);
+ }
+
+ namespace session {
+ namespace state {
+ enum value {
+ CONNECTING = 0,
+ OPEN = 1,
+ CLOSING = 2,
+ CLOSED = 3
+ };
+ }
+ }
+
+ namespace close {
+ namespace status {
+ enum value {
+ INVALID_END = 999,
+ NORMAL = 1000,
+ GOING_AWAY = 1001,
+ PROTOCOL_ERROR = 1002,
+ UNSUPPORTED_DATA = 1003,
+ RSV_ADHOC_1 = 1004,
+ NO_STATUS = 1005,
+ ABNORMAL_CLOSE = 1006,
+ INVALID_PAYLOAD = 1007,
+ POLICY_VIOLATION = 1008,
+ MESSAGE_TOO_BIG = 1009,
+ EXTENSION_REQUIRE = 1010,
+ INTERNAL_ENDPOINT_ERROR = 1011,
+ RSV_START = 1012,
+ RSV_END = 2999,
+ INVALID_START = 5000
+ };
+
+ inline bool reserved(value s) {
+ return ((s >= RSV_START && s <= RSV_END) ||
+ s == RSV_ADHOC_1);
+ }
+
+ inline bool invalid(value s) {
+ return ((s <= INVALID_END || s >= INVALID_START) ||
+ s == NO_STATUS ||
+ s == ABNORMAL_CLOSE);
+ }
+
+ // TODO functions for application ranges?
+ } // namespace status
+ } // namespace close
+
namespace frame {
// Opcodes are 4 bits
// See spec section 5.2
@@ -158,7 +158,7 @@ namespace websocketpp {
}
class exception : public std::exception {
- public:
+ public:
exception(const std::string& msg,
error::value code = error::GENERIC)
: m_msg(msg),m_code(code) {}
diff --git a/src/connection.hpp b/src/connection.hpp
index dc5bb0885a..91057b4ec0 100644
--- a/src/connection.hpp
+++ b/src/connection.hpp
@@ -55,88 +55,88 @@ class endpoint_base;
template
struct connection_traits;
-
+
template <
- typename endpoint,
- template class role,
- template class socket>
+ typename endpoint,
+ template class role,
+ template class socket>
class connection
: public role< connection >,
public socket< connection >,
public boost::enable_shared_from_this< connection >
{
public:
- typedef connection_traits< connection > traits;
-
- // get types that we need from our traits class
- typedef typename traits::type type;
- typedef typename traits::role_type role_type;
- typedef typename traits::socket_type socket_type;
-
- typedef endpoint endpoint_type;
-
- typedef typename endpoint_type::handler_ptr handler_ptr;
-
- // friends (would require C++11) this would enable connection::start to be
- // protected instead of public.
- //friend typename endpoint_traits::role_type;
- //friend typename endpoint_traits::socket_type;
- //friend class role;
- //friend class socket;
-
- friend class role< connection >;
- friend class socket< connection >;
-
- enum write_state {
- IDLE = 0,
- WRITING = 1,
- INTURRUPT = 2
- };
-
- enum read_state {
- READING = 0,
- WAITING = 1
- };
-
- connection(endpoint_type& e,handler_ptr h)
- : role_type(e),
- socket_type(e),
- m_endpoint(e),
- m_handler(h),
- m_timer(e.endpoint_base::m_io_service,boost::posix_time::seconds(0)),
- m_state(session::state::CONNECTING),
- m_write_buffer(0),
- m_write_state(IDLE),
- m_remote_close_code(close::status::ABNORMAL_CLOSE),
- m_read_state(READING)
- {
- socket_type::init();
-
- m_control_message = message::control_ptr(new message::control());
- }
-
- // SHOULD BE PROTECTED
- void start() {
- // initialize the socket.
- socket_type::async_init(
- boost::bind(
- &type::handle_socket_init,
- type::shared_from_this(),
- boost::asio::placeholders::error
- )
- );
- }
- // END PROTECTED
-
- // Valid always
- session::state::value get_state() const {
- return m_state;
- }
-
- // Valid for OPEN state
+ typedef connection_traits< connection > traits;
+
+ // get types that we need from our traits class
+ typedef typename traits::type type;
+ typedef typename traits::role_type role_type;
+ typedef typename traits::socket_type socket_type;
+
+ typedef endpoint endpoint_type;
+
+ typedef typename endpoint_type::handler_ptr handler_ptr;
+
+ // friends (would require C++11) this would enable connection::start to be
+ // protected instead of public.
+ //friend typename endpoint_traits::role_type;
+ //friend typename endpoint_traits::socket_type;
+ //friend class role;
+ //friend class socket;
+
+ friend class role< connection >;
+ friend class socket< connection >;
+
+ enum write_state {
+ IDLE = 0,
+ WRITING = 1,
+ INTURRUPT = 2
+ };
+
+ enum read_state {
+ READING = 0,
+ WAITING = 1
+ };
+
+ connection(endpoint_type& e,handler_ptr h)
+ : role_type(e),
+ socket_type(e),
+ m_endpoint(e),
+ m_handler(h),
+ m_timer(e.endpoint_base::m_io_service,boost::posix_time::seconds(0)),
+ m_state(session::state::CONNECTING),
+ m_write_buffer(0),
+ m_write_state(IDLE),
+ m_remote_close_code(close::status::ABNORMAL_CLOSE),
+ m_read_state(READING)
+ {
+ socket_type::init();
+
+ m_control_message = message::control_ptr(new message::control());
+ }
+
+ // SHOULD BE PROTECTED
+ void start() {
+ // initialize the socket.
+ socket_type::async_init(
+ boost::bind(
+ &type::handle_socket_init,
+ type::shared_from_this(),
+ boost::asio::placeholders::error
+ )
+ );
+ }
+ // END PROTECTED
+
+ // Valid always
+ session::state::value get_state() const {
+ return m_state;
+ }
+
+ // Valid for OPEN state
/// convenience overload for sending a one off text message.
- void send(const std::string& payload, frame::opcode::value op = frame::opcode::TEXT) {
- websocketpp::message::data::ptr msg = get_control_message2();
+ void send(const std::string& payload, frame::opcode::value op = frame::opcode::TEXT) {
+ websocketpp::message::data::ptr msg = get_control_message2();
if (!msg) {
throw exception("Endpoint send queue is full",error::SEND_QUEUE_FULL);
@@ -148,285 +148,285 @@ public:
msg->reset(op);
msg->set_payload(payload);
send(msg);
- }
+ }
void send(message::data_ptr msg) {
m_processor->prepare_frame(msg);
write_message(msg);
}
- void close(close::status::value code, const std::string& reason = "") {
- // TODO: overloads without code or reason?
- send_close(code, reason);
- }
- void ping(const std::string& payload) {
- send_ping(payload);
- }
- void pong(const std::string& payload) {
+ void close(close::status::value code, const std::string& reason = "") {
+ // TODO: overloads without code or reason?
+ send_close(code, reason);
+ }
+ void ping(const std::string& payload) {
+ send_ping(payload);
+ }
+ void pong(const std::string& payload) {
send_pong(payload);
- }
-
- uint64_t buffered_amount() const {
- return m_write_buffer;
- }
-
- // Valid for CLOSED state
- close::status::value get_local_close_code() const {
- return m_local_close_code;
- }
- utf8_string get_local_close_reason() const {
- return m_local_close_reason;
- }
- close::status::value get_remote_close_code() const {
- return m_remote_close_code;
- }
- utf8_string get_remote_close_reason() const {
- return m_remote_close_reason;
- }
- bool get_failed_by_me() const {
- return m_failed_by_me;
- }
- bool get_dropped_by_me() const {
- return m_dropped_by_me;
- }
- bool get_closed_by_me() const {
- return m_closed_by_me;
- }
-
- // flow control interface
- message::data_ptr get_data_message() {
- return m_endpoint.get_data_message();
- }
-
- message::data_ptr get_control_message2() {
- return m_endpoint.get_control_message();
- }
+ }
- message::control_ptr get_control_message() {
- return m_control_message;
- }
-
-
- // stuff about switching handlers on the fly
- // TODO: organize more
- void set_handler(handler_ptr new_handler) {
-
- if (!new_handler) {
+ uint64_t buffered_amount() const {
+ return m_write_buffer;
+ }
+
+ // Valid for CLOSED state
+ close::status::value get_local_close_code() const {
+ return m_local_close_code;
+ }
+ utf8_string get_local_close_reason() const {
+ return m_local_close_reason;
+ }
+ close::status::value get_remote_close_code() const {
+ return m_remote_close_code;
+ }
+ utf8_string get_remote_close_reason() const {
+ return m_remote_close_reason;
+ }
+ bool get_failed_by_me() const {
+ return m_failed_by_me;
+ }
+ bool get_dropped_by_me() const {
+ return m_dropped_by_me;
+ }
+ bool get_closed_by_me() const {
+ return m_closed_by_me;
+ }
+
+ // flow control interface
+ message::data_ptr get_data_message() {
+ return m_endpoint.get_data_message();
+ }
+
+ message::data_ptr get_control_message2() {
+ return m_endpoint.get_control_message();
+ }
+
+ message::control_ptr get_control_message() {
+ return m_control_message;
+ }
+
+
+ // stuff about switching handlers on the fly
+ // TODO: organize more
+ void set_handler(handler_ptr new_handler) {
+
+ if (!new_handler) {
m_endpoint.elog().at(log::elevel::FATAL)
<< "Tried to switch to a NULL handler." << log::endl;
- terminate(true);
+ terminate(true);
return;
- }
-
- handler_ptr old_handler = get_handler();
-
- old_handler->on_unload(type::shared_from_this(),new_handler);
- m_handler = new_handler;
- new_handler->on_load(type::shared_from_this(),old_handler);
- }
-
- // TODO: deprecated. will change to get_rng?
- int32_t gen() {
- return 0;
- }
-
- typename endpoint::alogger_type& alog() {
- return m_endpoint.alog();
- }
-protected:
- void handle_socket_init(const boost::system::error_code& error) {
- if (error) {
- m_endpoint.elog().at(log::elevel::ERROR) << "Connection initialization failed, error code: " << error << log::endl;
- this->terminate(false);
- return;
- }
-
- role_type::async_init();
- }
-public:
- void handle_read_frame(const boost::system::error_code& error) {
- // check if state changed while we were waiting for a read.
- if (m_state == session::state::CLOSED) { return; }
-
- if (error) {
- if (error == boost::asio::error::eof) {
- // got unexpected EOF
- // TODO: log error
+ }
+
+ handler_ptr old_handler = get_handler();
+
+ old_handler->on_unload(type::shared_from_this(),new_handler);
+ m_handler = new_handler;
+ new_handler->on_load(type::shared_from_this(),old_handler);
+ }
+
+ // TODO: deprecated. will change to get_rng?
+ int32_t gen() {
+ return 0;
+ }
+
+ typename endpoint::alogger_type& alog() {
+ return m_endpoint.alog();
+ }
+protected:
+ void handle_socket_init(const boost::system::error_code& error) {
+ if (error) {
+ m_endpoint.elog().at(log::elevel::ERROR) << "Connection initialization failed, error code: " << error << log::endl;
+ this->terminate(false);
+ return;
+ }
+
+ role_type::async_init();
+ }
+public:
+ void handle_read_frame(const boost::system::error_code& error) {
+ // check if state changed while we were waiting for a read.
+ if (m_state == session::state::CLOSED) { return; }
+
+ if (error) {
+ if (error == boost::asio::error::eof) {
+ // got unexpected EOF
+ // TODO: log error
m_endpoint.elog().at(log::elevel::ERROR) << "Remote connection dropped unexpectedly" << log::endl;
- terminate(false);
- } else if (error == boost::asio::error::operation_aborted) {
- // got unexpected abort (likely our server issued an abort on
- // all connections on this io_service)
-
- // TODO: log error
+ terminate(false);
+ } else if (error == boost::asio::error::operation_aborted) {
+ // got unexpected abort (likely our server issued an abort on
+ // all connections on this io_service)
+
+ // TODO: log error
m_endpoint.elog().at(log::elevel::ERROR) << "Terminating due to abort: " << error << log::endl;
- terminate(true);
- } else {
- // Other unexpected error
-
- // TODO: log error
+ terminate(true);
+ } else {
+ // Other unexpected error
+
+ // TODO: log error
m_endpoint.elog().at(log::elevel::ERROR) << "Terminating due to unknown error: " << error << log::endl;
- terminate(false);
- }
- }
-
- // process data from the buffer just read into
- std::istream s(&m_buf);
-
- while (m_state != session::state::CLOSED && m_buf.size() > 0) {
- try {
- m_processor->consume(s);
-
- if (m_processor->ready()) {
- if (m_processor->is_control()) {
- process_control(m_processor->get_control_message());
- } else {
- process_data(m_processor->get_data_message());
- }
- m_processor->reset();
- }
- } catch (const processor::exception& e) {
- if (m_processor->ready()) {
- m_processor->reset();
- }
-
- switch(e.code()) {
- case processor::error::PROTOCOL_VIOLATION:
- send_close(close::status::PROTOCOL_ERROR, e.what());
- break;
- case processor::error::PAYLOAD_VIOLATION:
- send_close(close::status::INVALID_PAYLOAD, e.what());
- break;
- case processor::error::INTERNAL_ENDPOINT_ERROR:
- send_close(close::status::INTERNAL_ENDPOINT_ERROR, e.what());
- break;
- case processor::error::SOFT_ERROR:
- continue;
- case processor::error::MESSAGE_TOO_BIG:
- send_close(close::status::MESSAGE_TOO_BIG, e.what());
- break;
- case processor::error::OUT_OF_MESSAGES:
- // we need to wait for a message to be returned by the
- // client. We exit the read loop. handle_read_frame
- // will be restarted by recycle()
- //m_read_state = WAITING;
+ terminate(false);
+ }
+ }
+
+ // process data from the buffer just read into
+ std::istream s(&m_buf);
+
+ while (m_state != session::state::CLOSED && m_buf.size() > 0) {
+ try {
+ m_processor->consume(s);
+
+ if (m_processor->ready()) {
+ if (m_processor->is_control()) {
+ process_control(m_processor->get_control_message());
+ } else {
+ process_data(m_processor->get_data_message());
+ }
+ m_processor->reset();
+ }
+ } catch (const processor::exception& e) {
+ if (m_processor->ready()) {
+ m_processor->reset();
+ }
+
+ switch(e.code()) {
+ case processor::error::PROTOCOL_VIOLATION:
+ send_close(close::status::PROTOCOL_ERROR, e.what());
+ break;
+ case processor::error::PAYLOAD_VIOLATION:
+ send_close(close::status::INVALID_PAYLOAD, e.what());
+ break;
+ case processor::error::INTERNAL_ENDPOINT_ERROR:
+ send_close(close::status::INTERNAL_ENDPOINT_ERROR, e.what());
+ break;
+ case processor::error::SOFT_ERROR:
+ continue;
+ case processor::error::MESSAGE_TOO_BIG:
+ send_close(close::status::MESSAGE_TOO_BIG, e.what());
+ break;
+ case processor::error::OUT_OF_MESSAGES:
+ // we need to wait for a message to be returned by the
+ // client. We exit the read loop. handle_read_frame
+ // will be restarted by recycle()
+ //m_read_state = WAITING;
m_endpoint.wait(type::shared_from_this());
- return;
- default:
- // Fatal error, forcibly end connection immediately.
- m_endpoint.elog().at(log::elevel::DEVEL)
- << "Dropping TCP due to unrecoverable exception"
- << log::endl;
- terminate(true);
- }
- break;
-
- }
- }
-
- // try and read more
- if (m_state != session::state::CLOSED &&
- m_processor->get_bytes_needed() > 0) {
- // TODO: read timeout timer?
-
- boost::asio::async_read(
- socket_type::get_socket(),
- m_buf,
- boost::asio::transfer_at_least(m_processor->get_bytes_needed()),
- boost::bind(
- &type::handle_read_frame,
- type::shared_from_this(),
- boost::asio::placeholders::error
- )
- );
- }
- }
-protected:
- void process_data(message::data_ptr msg) {
- get_handler()->on_message(type::shared_from_this(),msg);
- }
-
- void process_control(message::control_ptr msg) {
- bool response;
- switch (msg->get_opcode()) {
- case frame::opcode::PING:
- response = get_handler()->on_ping(type::shared_from_this(),
- msg->get_payload());
- if (response) {
+ return;
+ default:
+ // Fatal error, forcibly end connection immediately.
+ m_endpoint.elog().at(log::elevel::DEVEL)
+ << "Dropping TCP due to unrecoverable exception"
+ << log::endl;
+ terminate(true);
+ }
+ break;
+
+ }
+ }
+
+ // try and read more
+ if (m_state != session::state::CLOSED &&
+ m_processor->get_bytes_needed() > 0) {
+ // TODO: read timeout timer?
+
+ boost::asio::async_read(
+ socket_type::get_socket(),
+ m_buf,
+ boost::asio::transfer_at_least(m_processor->get_bytes_needed()),
+ boost::bind(
+ &type::handle_read_frame,
+ type::shared_from_this(),
+ boost::asio::placeholders::error
+ )
+ );
+ }
+ }
+protected:
+ void process_data(message::data_ptr msg) {
+ get_handler()->on_message(type::shared_from_this(),msg);
+ }
+
+ void process_control(message::control_ptr msg) {
+ bool response;
+ switch (msg->get_opcode()) {
+ case frame::opcode::PING:
+ response = get_handler()->on_ping(type::shared_from_this(),
+ msg->get_payload());
+ if (response) {
send_pong(msg->get_payload());
- }
- break;
- case frame::opcode::PONG:
- get_handler()->on_pong(type::shared_from_this(),
- msg->get_payload());
- // TODO: disable ping response timer
-
- break;
- case frame::opcode::CLOSE:
- m_remote_close_code = msg->get_close_code();
- m_remote_close_reason = msg->get_close_reason();
-
- // check that the codes we got over the wire are valid
-
- if (m_state == session::state::OPEN) {
- // other end is initiating
- m_endpoint.elog().at(log::elevel::DEVEL)
- << "sending close ack" << log::endl;
-
- // TODO:
- send_close_ack();
- } else if (m_state == session::state::CLOSING) {
- // ack of our close
- m_endpoint.elog().at(log::elevel::DEVEL)
- << "got close ack" << log::endl;
-
- terminate(false);
- // TODO: start terminate timer (if client)
- }
- break;
- default:
- throw processor::exception("Invalid Opcode",
- processor::error::PROTOCOL_VIOLATION);
- break;
- }
- }
-
- void send_close(close::status::value code, const std::string& reason) {
- if (m_state != session::state::OPEN) {
- m_endpoint.elog().at(log::elevel::WARN)
- << "Tried to disconnect a session that wasn't open"
- << log::endl;
- return;
- }
-
- if (close::status::invalid(code)) {
- m_endpoint.elog().at(log::elevel::WARN)
- << "Tried to close a connection with invalid close code: "
- << code << log::endl;
- return;
- } else if (close::status::reserved(code)) {
- m_endpoint.elog().at(log::elevel::WARN)
- << "Tried to close a connection with reserved close code: "
- << code << log::endl;
- return;
- }
-
- m_state = session::state::CLOSING;
-
- m_closed_by_me = true;
-
- m_timer.expires_from_now(boost::posix_time::milliseconds(1000));
- m_timer.async_wait(
- boost::bind(
- &type::fail_on_expire,
- type::shared_from_this(),
- boost::asio::placeholders::error
- )
- );
-
- m_local_close_code = code;
- m_local_close_reason = reason;
-
+ }
+ break;
+ case frame::opcode::PONG:
+ get_handler()->on_pong(type::shared_from_this(),
+ msg->get_payload());
+ // TODO: disable ping response timer
+
+ break;
+ case frame::opcode::CLOSE:
+ m_remote_close_code = msg->get_close_code();
+ m_remote_close_reason = msg->get_close_reason();
+
+ // check that the codes we got over the wire are valid
+
+ if (m_state == session::state::OPEN) {
+ // other end is initiating
+ m_endpoint.elog().at(log::elevel::DEVEL)
+ << "sending close ack" << log::endl;
+
+ // TODO:
+ send_close_ack();
+ } else if (m_state == session::state::CLOSING) {
+ // ack of our close
+ m_endpoint.elog().at(log::elevel::DEVEL)
+ << "got close ack" << log::endl;
+
+ terminate(false);
+ // TODO: start terminate timer (if client)
+ }
+ break;
+ default:
+ throw processor::exception("Invalid Opcode",
+ processor::error::PROTOCOL_VIOLATION);
+ break;
+ }
+ }
+
+ void send_close(close::status::value code, const std::string& reason) {
+ if (m_state != session::state::OPEN) {
+ m_endpoint.elog().at(log::elevel::WARN)
+ << "Tried to disconnect a session that wasn't open"
+ << log::endl;
+ return;
+ }
+
+ if (close::status::invalid(code)) {
+ m_endpoint.elog().at(log::elevel::WARN)
+ << "Tried to close a connection with invalid close code: "
+ << code << log::endl;
+ return;
+ } else if (close::status::reserved(code)) {
+ m_endpoint.elog().at(log::elevel::WARN)
+ << "Tried to close a connection with reserved close code: "
+ << code << log::endl;
+ return;
+ }
+
+ m_state = session::state::CLOSING;
+
+ m_closed_by_me = true;
+
+ m_timer.expires_from_now(boost::posix_time::milliseconds(1000));
+ m_timer.async_wait(
+ boost::bind(
+ &type::fail_on_expire,
+ type::shared_from_this(),
+ boost::asio::placeholders::error
+ )
+ );
+
+ m_local_close_code = code;
+ m_local_close_reason = reason;
+
// TODO: optimize control messages and handle case where endpoint is
// out of messages
message::data_ptr msg = get_control_message2();
@@ -441,43 +441,43 @@ protected:
}
msg->reset(frame::opcode::CLOSE);
- m_processor->prepare_close_frame(msg,code,reason);
- write_message(msg);
+ m_processor->prepare_close_frame(msg,code,reason);
+ write_message(msg);
+
+ m_write_state = INTURRUPT;
+ }
+
+ // send an acknowledgement close frame
+ void send_close_ack() {
+ // TODO: state should be OPEN
+
+ // echo close value unless there is a good reason not to.
+ if (m_remote_close_code == close::status::NO_STATUS) {
+ m_local_close_code = close::status::NORMAL;
+ m_local_close_reason = "";
+ } else if (m_remote_close_code == close::status::ABNORMAL_CLOSE) {
+ // TODO: can we possibly get here? This means send_close_ack was
+ // called after a connection ended without getting a close
+ // frame
+ throw "shouldn't be here";
+ } else if (close::status::invalid(m_remote_close_code)) {
+ // TODO: shouldn't be able to get here now either
+ m_local_close_code = close::status::PROTOCOL_ERROR;
+ m_local_close_reason = "Status code is invalid";
+ } else if (close::status::reserved(m_remote_close_code)) {
+ // TODO: shouldn't be able to get here now either
+ m_local_close_code = close::status::PROTOCOL_ERROR;
+ m_local_close_reason = "Status code is reserved";
+ } else {
+ m_local_close_code = m_remote_close_code;
+ m_local_close_reason = m_remote_close_reason;
+ }
+
+ // TODO: check whether we should cancel the current in flight write.
+ // if not canceled the close message will be sent as soon as the
+ // current write completes.
+
- m_write_state = INTURRUPT;
- }
-
- // send an acknowledgement close frame
- void send_close_ack() {
- // TODO: state should be OPEN
-
- // echo close value unless there is a good reason not to.
- if (m_remote_close_code == close::status::NO_STATUS) {
- m_local_close_code = close::status::NORMAL;
- m_local_close_reason = "";
- } else if (m_remote_close_code == close::status::ABNORMAL_CLOSE) {
- // TODO: can we possibly get here? This means send_close_ack was
- // called after a connection ended without getting a close
- // frame
- throw "shouldn't be here";
- } else if (close::status::invalid(m_remote_close_code)) {
- // TODO: shouldn't be able to get here now either
- m_local_close_code = close::status::PROTOCOL_ERROR;
- m_local_close_reason = "Status code is invalid";
- } else if (close::status::reserved(m_remote_close_code)) {
- // TODO: shouldn't be able to get here now either
- m_local_close_code = close::status::PROTOCOL_ERROR;
- m_local_close_reason = "Status code is reserved";
- } else {
- m_local_close_code = m_remote_close_code;
- m_local_close_reason = m_remote_close_reason;
- }
-
- // TODO: check whether we should cancel the current in flight write.
- // if not canceled the close message will be sent as soon as the
- // current write completes.
-
-
// TODO: optimize control messages and handle case where endpoint is
// out of messages
message::data_ptr msg = get_control_message2();
@@ -492,13 +492,13 @@ protected:
}
msg->reset(frame::opcode::CLOSE);
- m_processor->prepare_close_frame(msg,
+ m_processor->prepare_close_frame(msg,
m_local_close_code,
m_local_close_reason);
- write_message(msg);
- m_write_state = INTURRUPT;
- }
-
+ write_message(msg);
+ m_write_state = INTURRUPT;
+ }
+
void send_ping(const std::string& payload) {
// TODO: optimize control messages and handle case where
// endpoint is out of messages
@@ -519,42 +519,42 @@ protected:
write_message(control);
}
- void write_message(message::data_ptr msg) {
- if (m_write_state == INTURRUPT) {
- return;
- }
-
- m_write_buffer += msg->get_payload().size();
- m_write_queue.push(msg);
+ void write_message(message::data_ptr msg) {
+ if (m_write_state == INTURRUPT) {
+ return;
+ }
- write();
- }
-
- void write() {
+ m_write_buffer += msg->get_payload().size();
+ m_write_queue.push(msg);
+
+ write();
+ }
+
+ void write() {
switch (m_write_state) {
- case IDLE:
- break;
- case WRITING:
- // already writing. write() will get called again by the write
- // handler once it is ready.
- return;
- case INTURRUPT:
- // clear the queue except for the last message
- while (m_write_queue.size() > 1) {
- m_write_buffer -= m_write_queue.front()->get_payload().size();
- m_write_queue.pop();
- }
- break;
- default:
- // TODO: assert shouldn't be here
- break;
- }
-
- if (m_write_queue.size() > 0) {
- if (m_write_state == IDLE) {
- m_write_state = WRITING;
- }
-
+ case IDLE:
+ break;
+ case WRITING:
+ // already writing. write() will get called again by the write
+ // handler once it is ready.
+ return;
+ case INTURRUPT:
+ // clear the queue except for the last message
+ while (m_write_queue.size() > 1) {
+ m_write_buffer -= m_write_queue.front()->get_payload().size();
+ m_write_queue.pop();
+ }
+ break;
+ default:
+ // TODO: assert shouldn't be here
+ break;
+ }
+
+ if (m_write_queue.size() > 0) {
+ if (m_write_state == IDLE) {
+ m_write_state = WRITING;
+ }
+
std::vector data;
data.push_back(boost::asio::buffer(m_write_queue.front()->get_header()));
@@ -562,74 +562,74 @@ protected:
m_endpoint.alog().at(log::alevel::DEVEL) << "write header: " << to_hex(m_write_queue.front()->get_header()) << log::endl;
- boost::asio::async_write(
- socket_type::get_socket(),
- data,
- boost::bind(
- &type::handle_write,
- type::shared_from_this(),
- boost::asio::placeholders::error
- )
- );
- } else {
- // if we are in an inturrupted state and had nothing else to write
- // it is safe to terminate the connection.
- if (m_write_state == INTURRUPT) {
+ boost::asio::async_write(
+ socket_type::get_socket(),
+ data,
+ boost::bind(
+ &type::handle_write,
+ type::shared_from_this(),
+ boost::asio::placeholders::error
+ )
+ );
+ } else {
+ // if we are in an inturrupted state and had nothing else to write
+ // it is safe to terminate the connection.
+ if (m_write_state == INTURRUPT) {
m_endpoint.alog().at(log::alevel::DEBUG_CLOSE) << "Exit after inturrupt" << log::endl;
- terminate(false);
- }
- }
- }
-
- void handle_write(const boost::system::error_code& error) {
+ terminate(false);
+ }
+ }
+ }
+
+ void handle_write(const boost::system::error_code& error) {
if (error) {
- if (error == boost::asio::error::operation_aborted) {
- // previous write was aborted
+ if (error == boost::asio::error::operation_aborted) {
+ // previous write was aborted
m_endpoint.alog().at(log::alevel::DEBUG_CLOSE) << "handle_write was called with operation_aborted error" << log::endl;
- } else {
- log_error("Error writing frame data",error);
- terminate(false);
- return;
- }
- }
-
- if (m_write_queue.size() == 0) {
+ } else {
+ log_error("Error writing frame data",error);
+ terminate(false);
+ return;
+ }
+ }
+
+ if (m_write_queue.size() == 0) {
m_endpoint.alog().at(log::alevel::DEBUG_CLOSE) << "handle_write called with empty queue" << log::endl;
- return;
- }
+ return;
+ }
- m_write_buffer -= m_write_queue.front()->get_payload().size();
- m_write_queue.pop();
+ m_write_buffer -= m_write_queue.front()->get_payload().size();
+ m_write_queue.pop();
- if (m_write_state == WRITING) {
- m_write_state = IDLE;
- }
-
- write();
- }
-
- // terminate cleans up a connection and removes it from the endpoint's
- // connection list.
- void terminate(bool failed_by_me) {
- m_endpoint.alog().at(log::alevel::DEBUG_CLOSE) << "terminate called" << log::endl;
-
- if (m_state == session::state::CLOSED) {
- // shouldn't be here
- }
-
- // cancel the close timeout
- m_timer.cancel();
-
-
-
- // If this was a websocket connection notify the application handler
- // about the close using either on_fail or on_close
- if (role_type::get_version() != -1) {
+ if (m_write_state == WRITING) {
+ m_write_state = IDLE;
+ }
+
+ write();
+ }
+
+ // terminate cleans up a connection and removes it from the endpoint's
+ // connection list.
+ void terminate(bool failed_by_me) {
+ m_endpoint.alog().at(log::alevel::DEBUG_CLOSE) << "terminate called" << log::endl;
+
+ if (m_state == session::state::CLOSED) {
+ // shouldn't be here
+ }
+
+ // cancel the close timeout
+ m_timer.cancel();
+
+
+
+ // If this was a websocket connection notify the application handler
+ // about the close using either on_fail or on_close
+ if (role_type::get_version() != -1) {
// TODO: note, calling shutdown on the ssl socket for an HTTP
// connection seems to cause shutdown to block for a very long time.
// NOT calling it for a websocket connection causes the connection
// to time out. Behavior now is correct but I am not sure why.
- m_dropped_by_me = socket_type::shutdown();
+ m_dropped_by_me = socket_type::shutdown();
m_failed_by_me = failed_by_me;
@@ -637,106 +637,106 @@ protected:
m_state = session::state::CLOSED;
if (old_state == session::state::CONNECTING) {
- get_handler()->on_fail(type::shared_from_this());
- } else if (old_state == session::state::OPEN ||
- old_state == session::state::CLOSING) {
- get_handler()->on_close(type::shared_from_this());
- } else {
- // if we were already closed something is wrong
- }
- log_close_result();
- }
- // finally remove this connection from the endpoint's list. This will
- // remove the last shared pointer to the connection held by WS++.
- m_endpoint.remove_connection(type::shared_from_this());
- }
-
- // this is called when an async asio call encounters an error
- void log_error(std::string msg,const boost::system::error_code& e) {
- m_endpoint.elog().at(log::elevel::ERROR)
- << msg << "(" << e << ")" << log::endl;
- }
-
- void log_close_result() {
- m_endpoint.alog().at(log::alevel::DISCONNECT)
- //<< "Disconnect " << (m_was_clean ? "Clean" : "Unclean")
- << "Disconnect "
- << " close local:[" << m_local_close_code
- << (m_local_close_reason == "" ? "" : ","+m_local_close_reason)
- << "] remote:[" << m_remote_close_code
- << (m_remote_close_reason == "" ? "" : ","+m_remote_close_reason) << "]"
- << log::endl;
- }
-
- void fail_on_expire(const boost::system::error_code& error) {
- if (error) {
- if (error != boost::asio::error::operation_aborted) {
- m_endpoint.elog().at(log::elevel::DEVEL)
- << "fail_on_expire timer ended in unknown error" << log::endl;
- terminate(false);
- }
- return;
- }
- m_endpoint.elog().at(log::elevel::DEVEL)
- << "fail_on_expire timer expired" << log::endl;
- terminate(true);
- }
-
- boost::asio::streambuf& buffer() {
- return m_buf;
- }
-
- handler_ptr get_handler() {
- return m_handler;
- }
+ get_handler()->on_fail(type::shared_from_this());
+ } else if (old_state == session::state::OPEN ||
+ old_state == session::state::CLOSING) {
+ get_handler()->on_close(type::shared_from_this());
+ } else {
+ // if we were already closed something is wrong
+ }
+ log_close_result();
+ }
+ // finally remove this connection from the endpoint's list. This will
+ // remove the last shared pointer to the connection held by WS++.
+ m_endpoint.remove_connection(type::shared_from_this());
+ }
+
+ // this is called when an async asio call encounters an error
+ void log_error(std::string msg,const boost::system::error_code& e) {
+ m_endpoint.elog().at(log::elevel::ERROR)
+ << msg << "(" << e << ")" << log::endl;
+ }
+
+ void log_close_result() {
+ m_endpoint.alog().at(log::alevel::DISCONNECT)
+ //<< "Disconnect " << (m_was_clean ? "Clean" : "Unclean")
+ << "Disconnect "
+ << " close local:[" << m_local_close_code
+ << (m_local_close_reason == "" ? "" : ","+m_local_close_reason)
+ << "] remote:[" << m_remote_close_code
+ << (m_remote_close_reason == "" ? "" : ","+m_remote_close_reason) << "]"
+ << log::endl;
+ }
+
+ void fail_on_expire(const boost::system::error_code& error) {
+ if (error) {
+ if (error != boost::asio::error::operation_aborted) {
+ m_endpoint.elog().at(log::elevel::DEVEL)
+ << "fail_on_expire timer ended in unknown error" << log::endl;
+ terminate(false);
+ }
+ return;
+ }
+ m_endpoint.elog().at(log::elevel::DEVEL)
+ << "fail_on_expire timer expired" << log::endl;
+ terminate(true);
+ }
+
+ boost::asio::streambuf& buffer() {
+ return m_buf;
+ }
+
+ handler_ptr get_handler() {
+ return m_handler;
+ }
protected:
- endpoint_type& m_endpoint;
- handler_ptr m_handler;
-
- // Network resources
- boost::asio::streambuf m_buf;
- boost::asio::deadline_timer m_timer;
-
- // WebSocket connection state
- session::state::value m_state;
-
- // stuff that actually does the work
- processor::ptr m_processor;
-
- // Write queue
- std::queue m_write_queue;
- uint64_t m_write_buffer;
- write_state m_write_state;
-
- // Close state
- close::status::value m_local_close_code;
- std::string m_local_close_reason;
- close::status::value m_remote_close_code;
- std::string m_remote_close_reason;
- bool m_closed_by_me;
- bool m_failed_by_me;
- bool m_dropped_by_me;
-
- // Read queue
- read_state m_read_state;
- message::control_ptr m_control_message;
+ endpoint_type& m_endpoint;
+ handler_ptr m_handler;
+
+ // Network resources
+ boost::asio::streambuf m_buf;
+ boost::asio::deadline_timer m_timer;
+
+ // WebSocket connection state
+ session::state::value m_state;
+
+ // stuff that actually does the work
+ processor::ptr m_processor;
+
+ // Write queue
+ std::queue m_write_queue;
+ uint64_t m_write_buffer;
+ write_state m_write_state;
+
+ // Close state
+ close::status::value m_local_close_code;
+ std::string m_local_close_reason;
+ close::status::value m_remote_close_code;
+ std::string m_remote_close_reason;
+ bool m_closed_by_me;
+ bool m_failed_by_me;
+ bool m_dropped_by_me;
+
+ // Read queue
+ read_state m_read_state;
+ message::control_ptr m_control_message;
};
// connection related types that it and its policy classes need.
template <
- typename endpoint,
- template class role,
- template class socket>
+ typename endpoint,
+ template class role,
+ template class socket>
struct connection_traits< connection > {
- // type of the connection itself
- typedef connection type;
-
- // types of the connection policies
- typedef endpoint endpoint_type;
- typedef role< type > role_type;
- typedef socket< type > socket_type;
+ // type of the connection itself
+ typedef connection type;
+
+ // types of the connection policies
+ typedef endpoint endpoint_type;
+ typedef role< type > role_type;
+ typedef socket< type > socket_type;
};
-
+
} // namespace websocketpp
#endif // WEBSOCKETPP_CONNECTION_HPP
diff --git a/src/http/constants.hpp b/src/http/constants.hpp
index bbdd76e793..c1a7ffa59f 100644
--- a/src/http/constants.hpp
+++ b/src/http/constants.hpp
@@ -30,183 +30,183 @@
namespace websocketpp {
namespace http {
- namespace status_code {
- enum value {
- CONTINUE = 100,
- SWITCHING_PROTOCOLS = 101,
-
- OK = 200,
- CREATED = 201,
- ACCEPTED = 202,
- NON_AUTHORITATIVE_INFORMATION = 203,
- NO_CONTENT = 204,
- RESET_CONTENT = 205,
- PARTIAL_CONTENT = 206,
-
- MULTIPLE_CHOICES = 300,
- MOVED_PERMANENTLY = 301,
- FOUND = 302,
- SEE_OTHER = 303,
- NOT_MODIFIED = 304,
- USE_PROXY = 305,
- TEMPORARY_REDIRECT = 307,
-
- BAD_REQUEST = 400,
- UNAUTHORIZED = 401,
- PAYMENT_REQUIRED = 402,
- FORBIDDEN = 403,
- NOT_FOUND = 404,
- METHOD_NOT_ALLOWED = 405,
- NOT_ACCEPTABLE = 406,
- PROXY_AUTHENTICATION_REQUIRED = 407,
- REQUEST_TIMEOUT = 408,
- CONFLICT = 409,
- GONE = 410,
- LENGTH_REQUIRED = 411,
- PRECONDITION_FAILED = 412,
- REQUEST_ENTITY_TOO_LARGE = 413,
- REQUEST_URI_TOO_LONG = 414,
- UNSUPPORTED_MEDIA_TYPE = 415,
- REQUEST_RANGE_NOT_SATISFIABLE = 416,
- EXPECTATION_FAILED = 417,
- IM_A_TEAPOT = 418,
- UPGRADE_REQUIRED = 426,
- PRECONDITION_REQUIRED = 428,
- TOO_MANY_REQUESTS = 429,
- REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
-
- INTERNAL_SERVER_ERROR = 500,
- NOT_IMPLIMENTED = 501,
- BAD_GATEWAY = 502,
- SERVICE_UNAVAILABLE = 503,
- GATEWAY_TIMEOUT = 504,
- HTTP_VERSION_NOT_SUPPORTED = 505,
- NOT_EXTENDED = 510,
- NETWORK_AUTHENTICATION_REQUIRED = 511
- };
-
- // TODO: should this be inline?
- inline std::string get_string(value c) {
- switch (c) {
- case CONTINUE:
- return "Continue";
- case SWITCHING_PROTOCOLS:
- return "Switching Protocols";
- case OK:
- return "OK";
- case CREATED:
- return "Created";
- case ACCEPTED:
- return "Accepted";
- case NON_AUTHORITATIVE_INFORMATION:
- return "Non Authoritative Information";
- case NO_CONTENT:
- return "No Content";
- case RESET_CONTENT:
- return "Reset Content";
- case PARTIAL_CONTENT:
- return "Partial Content";
- case MULTIPLE_CHOICES:
- return "Multiple Choices";
- case MOVED_PERMANENTLY:
- return "Moved Permanently";
- case FOUND:
- return "Found";
- case SEE_OTHER:
- return "See Other";
- case NOT_MODIFIED:
- return "Not Modified";
- case USE_PROXY:
- return "Use Proxy";
- case TEMPORARY_REDIRECT:
- return "Temporary Redirect";
- case BAD_REQUEST:
- return "Bad Request";
- case UNAUTHORIZED:
- return "Unauthorized";
- case FORBIDDEN:
- return "Forbidden";
- case NOT_FOUND:
- return "Not Found";
- case METHOD_NOT_ALLOWED:
- return "Method Not Allowed";
- case NOT_ACCEPTABLE:
- return "Not Acceptable";
- case PROXY_AUTHENTICATION_REQUIRED:
- return "Proxy Authentication Required";
- case REQUEST_TIMEOUT:
- return "Request Timeout";
- case CONFLICT:
- return "Conflict";
- case GONE:
- return "Gone";
- case LENGTH_REQUIRED:
- return "Length Required";
- case PRECONDITION_FAILED:
- return "Precondition Failed";
- case REQUEST_ENTITY_TOO_LARGE:
- return "Request Entity Too Large";
- case REQUEST_URI_TOO_LONG:
- return "Request-URI Too Long";
- case UNSUPPORTED_MEDIA_TYPE:
- return "Unsupported Media Type";
- case REQUEST_RANGE_NOT_SATISFIABLE:
- return "Requested Range Not Satisfiable";
- case EXPECTATION_FAILED:
- return "Expectation Failed";
- case IM_A_TEAPOT:
- return "I'm a teapot";
- case UPGRADE_REQUIRED:
- return "Upgrade Required";
- case PRECONDITION_REQUIRED:
- return "Precondition Required";
- case TOO_MANY_REQUESTS:
- return "Too Many Requests";
- case REQUEST_HEADER_FIELDS_TOO_LARGE:
- return "Request Header Fields Too Large";
- case INTERNAL_SERVER_ERROR:
- return "Internal Server Error";
- case NOT_IMPLIMENTED:
- return "Not Implimented";
- case BAD_GATEWAY:
- return "Bad Gateway";
- case SERVICE_UNAVAILABLE:
- return "Service Unavailable";
- case GATEWAY_TIMEOUT:
- return "Gateway Timeout";
- case HTTP_VERSION_NOT_SUPPORTED:
- return "HTTP Version Not Supported";
- case NOT_EXTENDED:
- return "Not Extended";
- case NETWORK_AUTHENTICATION_REQUIRED:
- return "Network Authentication Required";
- default:
- return "Unknown";
- }
- }
- }
-
- class exception : public std::exception {
- public:
- exception(const std::string& log_msg,
- status_code::value error_code,
- const std::string& error_msg = "",
- const std::string& body = "")
- : m_msg(log_msg),
- m_error_code(error_code),
- m_error_msg(error_msg),
- m_body(body) {}
- ~exception() throw() {}
-
- virtual const char* what() const throw() {
- return m_msg.c_str();
- }
-
- std::string m_msg;
- status_code::value m_error_code;
- std::string m_error_msg;
- std::string m_body;
- };
+ namespace status_code {
+ enum value {
+ CONTINUE = 100,
+ SWITCHING_PROTOCOLS = 101,
+
+ OK = 200,
+ CREATED = 201,
+ ACCEPTED = 202,
+ NON_AUTHORITATIVE_INFORMATION = 203,
+ NO_CONTENT = 204,
+ RESET_CONTENT = 205,
+ PARTIAL_CONTENT = 206,
+
+ MULTIPLE_CHOICES = 300,
+ MOVED_PERMANENTLY = 301,
+ FOUND = 302,
+ SEE_OTHER = 303,
+ NOT_MODIFIED = 304,
+ USE_PROXY = 305,
+ TEMPORARY_REDIRECT = 307,
+
+ BAD_REQUEST = 400,
+ UNAUTHORIZED = 401,
+ PAYMENT_REQUIRED = 402,
+ FORBIDDEN = 403,
+ NOT_FOUND = 404,
+ METHOD_NOT_ALLOWED = 405,
+ NOT_ACCEPTABLE = 406,
+ PROXY_AUTHENTICATION_REQUIRED = 407,
+ REQUEST_TIMEOUT = 408,
+ CONFLICT = 409,
+ GONE = 410,
+ LENGTH_REQUIRED = 411,
+ PRECONDITION_FAILED = 412,
+ REQUEST_ENTITY_TOO_LARGE = 413,
+ REQUEST_URI_TOO_LONG = 414,
+ UNSUPPORTED_MEDIA_TYPE = 415,
+ REQUEST_RANGE_NOT_SATISFIABLE = 416,
+ EXPECTATION_FAILED = 417,
+ IM_A_TEAPOT = 418,
+ UPGRADE_REQUIRED = 426,
+ PRECONDITION_REQUIRED = 428,
+ TOO_MANY_REQUESTS = 429,
+ REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
+
+ INTERNAL_SERVER_ERROR = 500,
+ NOT_IMPLIMENTED = 501,
+ BAD_GATEWAY = 502,
+ SERVICE_UNAVAILABLE = 503,
+ GATEWAY_TIMEOUT = 504,
+ HTTP_VERSION_NOT_SUPPORTED = 505,
+ NOT_EXTENDED = 510,
+ NETWORK_AUTHENTICATION_REQUIRED = 511
+ };
+
+ // TODO: should this be inline?
+ inline std::string get_string(value c) {
+ switch (c) {
+ case CONTINUE:
+ return "Continue";
+ case SWITCHING_PROTOCOLS:
+ return "Switching Protocols";
+ case OK:
+ return "OK";
+ case CREATED:
+ return "Created";
+ case ACCEPTED:
+ return "Accepted";
+ case NON_AUTHORITATIVE_INFORMATION:
+ return "Non Authoritative Information";
+ case NO_CONTENT:
+ return "No Content";
+ case RESET_CONTENT:
+ return "Reset Content";
+ case PARTIAL_CONTENT:
+ return "Partial Content";
+ case MULTIPLE_CHOICES:
+ return "Multiple Choices";
+ case MOVED_PERMANENTLY:
+ return "Moved Permanently";
+ case FOUND:
+ return "Found";
+ case SEE_OTHER:
+ return "See Other";
+ case NOT_MODIFIED:
+ return "Not Modified";
+ case USE_PROXY:
+ return "Use Proxy";
+ case TEMPORARY_REDIRECT:
+ return "Temporary Redirect";
+ case BAD_REQUEST:
+ return "Bad Request";
+ case UNAUTHORIZED:
+ return "Unauthorized";
+ case FORBIDDEN:
+ return "Forbidden";
+ case NOT_FOUND:
+ return "Not Found";
+ case METHOD_NOT_ALLOWED:
+ return "Method Not Allowed";
+ case NOT_ACCEPTABLE:
+ return "Not Acceptable";
+ case PROXY_AUTHENTICATION_REQUIRED:
+ return "Proxy Authentication Required";
+ case REQUEST_TIMEOUT:
+ return "Request Timeout";
+ case CONFLICT:
+ return "Conflict";
+ case GONE:
+ return "Gone";
+ case LENGTH_REQUIRED:
+ return "Length Required";
+ case PRECONDITION_FAILED:
+ return "Precondition Failed";
+ case REQUEST_ENTITY_TOO_LARGE:
+ return "Request Entity Too Large";
+ case REQUEST_URI_TOO_LONG:
+ return "Request-URI Too Long";
+ case UNSUPPORTED_MEDIA_TYPE:
+ return "Unsupported Media Type";
+ case REQUEST_RANGE_NOT_SATISFIABLE:
+ return "Requested Range Not Satisfiable";
+ case EXPECTATION_FAILED:
+ return "Expectation Failed";
+ case IM_A_TEAPOT:
+ return "I'm a teapot";
+ case UPGRADE_REQUIRED:
+ return "Upgrade Required";
+ case PRECONDITION_REQUIRED:
+ return "Precondition Required";
+ case TOO_MANY_REQUESTS:
+ return "Too Many Requests";
+ case REQUEST_HEADER_FIELDS_TOO_LARGE:
+ return "Request Header Fields Too Large";
+ case INTERNAL_SERVER_ERROR:
+ return "Internal Server Error";
+ case NOT_IMPLIMENTED:
+ return "Not Implimented";
+ case BAD_GATEWAY:
+ return "Bad Gateway";
+ case SERVICE_UNAVAILABLE:
+ return "Service Unavailable";
+ case GATEWAY_TIMEOUT:
+ return "Gateway Timeout";
+ case HTTP_VERSION_NOT_SUPPORTED:
+ return "HTTP Version Not Supported";
+ case NOT_EXTENDED:
+ return "Not Extended";
+ case NETWORK_AUTHENTICATION_REQUIRED:
+ return "Network Authentication Required";
+ default:
+ return "Unknown";
+ }
+ }
+ }
+
+ class exception : public std::exception {
+ public:
+ exception(const std::string& log_msg,
+ status_code::value error_code,
+ const std::string& error_msg = "",
+ const std::string& body = "")
+ : m_msg(log_msg),
+ m_error_code(error_code),
+ m_error_msg(error_msg),
+ m_body(body) {}
+ ~exception() throw() {}
+
+ virtual const char* what() const throw() {
+ return m_msg.c_str();
+ }
+
+ std::string m_msg;
+ status_code::value m_error_code;
+ std::string m_error_msg;
+ std::string m_body;
+ };
}
}
diff --git a/src/http/parser.hpp b/src/http/parser.hpp
index 6ab143e00a..b71b9381ff 100644
--- a/src/http/parser.hpp
+++ b/src/http/parser.hpp
@@ -39,243 +39,243 @@ namespace websocketpp {
namespace http {
namespace parser {
- namespace state {
- enum value {
- METHOD,
- RESOURCE,
- VERSION,
- HEADERS
- };
- }
+ namespace state {
+ enum value {
+ METHOD,
+ RESOURCE,
+ VERSION,
+ HEADERS
+ };
+ }
typedef std::map header_list;
class parser {
public:
- // consumes bytes from the stream and returns true if enough bytes have
- // been read
- bool consume (std::istream& s) {
- throw "No Implimented";
- }
-
- void set_version(const std::string& version) {
- // TODO: validation?
- m_version = version;
- }
-
- const std::string& version() const {
- return m_version;
- }
-
- std::string header(const std::string& key) const {
- header_list::const_iterator h = m_headers.find(key);
-
- if (h == m_headers.end()) {
- return "";
- } else {
- return h->second;
- }
- }
-
- // multiple calls to add header will result in values aggregating.
- // use replace_header if you do not want this behavior.
- void add_header(const std::string &key,const std::string &val) {
- // TODO: prevent use of reserved headers?
- if (this->header(key) == "") {
- m_headers[key] = val;
- } else {
- m_headers[key] += ", " + val;
- }
- }
-
- void replace_header(const std::string &key,const std::string &val) {
- m_headers[key] = val;
- }
-
- void remove_header(const std::string &key) {
- m_headers.erase(key);
- }
+ // consumes bytes from the stream and returns true if enough bytes have
+ // been read
+ bool consume (std::istream& s) {
+ throw "No Implimented";
+ }
+
+ void set_version(const std::string& version) {
+ // TODO: validation?
+ m_version = version;
+ }
+
+ const std::string& version() const {
+ return m_version;
+ }
+
+ std::string header(const std::string& key) const {
+ header_list::const_iterator h = m_headers.find(key);
+
+ if (h == m_headers.end()) {
+ return "";
+ } else {
+ return h->second;
+ }
+ }
+
+ // multiple calls to add header will result in values aggregating.
+ // use replace_header if you do not want this behavior.
+ void add_header(const std::string &key,const std::string &val) {
+ // TODO: prevent use of reserved headers?
+ if (this->header(key) == "") {
+ m_headers[key] = val;
+ } else {
+ m_headers[key] += ", " + val;
+ }
+ }
+
+ void replace_header(const std::string &key,const std::string &val) {
+ m_headers[key] = val;
+ }
+
+ void remove_header(const std::string &key) {
+ m_headers.erase(key);
+ }
protected:
- bool parse_headers(std::istream& s) {
- std::string header;
- std::string::size_type end;
-
- // get headers
- while (std::getline(s, header) && header != "\r") {
- if (header[header.size()-1] != '\r') {
- continue; // ignore malformed header lines?
- } else {
- header.erase(header.end()-1);
- }
-
- end = header.find(": ",0);
-
- if (end != std::string::npos) {
- add_header(header.substr(0,end),header.substr(end+2));
- }
- }
-
- return true;
- }
-
- std::string raw_headers() {
- std::stringstream raw;
-
- header_list::iterator it;
- for (it = m_headers.begin(); it != m_headers.end(); it++) {
- raw << it->first << ": " << it->second << "\r\n";
- }
-
- return raw.str();
- }
-
+ bool parse_headers(std::istream& s) {
+ std::string header;
+ std::string::size_type end;
+
+ // get headers
+ while (std::getline(s, header) && header != "\r") {
+ if (header[header.size()-1] != '\r') {
+ continue; // ignore malformed header lines?
+ } else {
+ header.erase(header.end()-1);
+ }
+
+ end = header.find(": ",0);
+
+ if (end != std::string::npos) {
+ add_header(header.substr(0,end),header.substr(end+2));
+ }
+ }
+
+ return true;
+ }
+
+ std::string raw_headers() {
+ std::stringstream raw;
+
+ header_list::iterator it;
+ for (it = m_headers.begin(); it != m_headers.end(); it++) {
+ raw << it->first << ": " << it->second << "\r\n";
+ }
+
+ return raw.str();
+ }
+
private:
- std::string m_version;
- header_list m_headers;
+ std::string m_version;
+ header_list m_headers;
};
class request : public parser {
-public:
- // parse a complete header (ie \r\n\r\n MUST be in the input stream)
- bool parse_complete(std::istream& s) {
- std::string request;
-
- // get status line
- std::getline(s, request);
-
- if (request[request.size()-1] == '\r') {
- request.erase(request.end()-1);
-
- std::stringstream ss(request);
- std::string val;
-
- ss >> val;
- set_method(val);
-
- ss >> val;
- set_uri(val);
-
- ss >> val;
- set_version(val);
- } else {
- return false;
- }
-
- return parse_headers(s);
- }
-
- // TODO: validation. Make sure all required fields have been set?
- std::string raw() {
- std::stringstream raw;
-
- raw << m_method << " " << m_uri << " " << version() << "\r\n";
- raw << raw_headers() << "\r\n";
-
- return raw.str();
- }
-
- void set_method(const std::string& method) {
- // TODO: validation?
- m_method = method;
- }
-
- const std::string& method() const {
- return m_method;
- }
-
- void set_uri(const std::string& uri) {
- // TODO: validation?
- m_uri = uri;
- }
-
- const std::string& uri() const {
- return m_uri;
- }
-
+public:
+ // parse a complete header (ie \r\n\r\n MUST be in the input stream)
+ bool parse_complete(std::istream& s) {
+ std::string request;
+
+ // get status line
+ std::getline(s, request);
+
+ if (request[request.size()-1] == '\r') {
+ request.erase(request.end()-1);
+
+ std::stringstream ss(request);
+ std::string val;
+
+ ss >> val;
+ set_method(val);
+
+ ss >> val;
+ set_uri(val);
+
+ ss >> val;
+ set_version(val);
+ } else {
+ return false;
+ }
+
+ return parse_headers(s);
+ }
+
+ // TODO: validation. Make sure all required fields have been set?
+ std::string raw() {
+ std::stringstream raw;
+
+ raw << m_method << " " << m_uri << " " << version() << "\r\n";
+ raw << raw_headers() << "\r\n";
+
+ return raw.str();
+ }
+
+ void set_method(const std::string& method) {
+ // TODO: validation?
+ m_method = method;
+ }
+
+ const std::string& method() const {
+ return m_method;
+ }
+
+ void set_uri(const std::string& uri) {
+ // TODO: validation?
+ m_uri = uri;
+ }
+
+ const std::string& uri() const {
+ return m_uri;
+ }
+
private:
- std::string m_method;
- std::string m_uri;
+ std::string m_method;
+ std::string m_uri;
};
class response : public parser {
public:
- // parse a complete header (ie \r\n\r\n MUST be in the input stream)
- bool parse_complete(std::istream& s) {
- std::string response;
-
- // get status line
- std::getline(s, response);
-
- if (response[response.size()-1] == '\r') {
- response.erase(response.end()-1);
-
- std::stringstream ss(response);
- std::string str_val;
- int int_val;
- char char_val[256];
-
- ss >> str_val;
- set_version(str_val);
-
- ss >> int_val;
- ss.getline(char_val,256);
- set_status(status_code::value(int_val),std::string(char_val));
- } else {
- return false;
- }
-
- return parse_headers(s);
- }
-
- // TODO: validation. Make sure all required fields have been set?
- std::string raw() {
- std::stringstream raw;
-
- raw << version() << " " << m_status_code << " " << m_status_msg << "\r\n";
- raw << raw_headers() << "\r\n";
-
- raw << m_body;
-
- return raw.str();
- }
-
- void set_status(status_code::value code) {
- // TODO: validation?
- m_status_code = code;
- m_status_msg = get_string(code);
- }
-
- void set_status(status_code::value code, const std::string& msg) {
- // TODO: validation?
- m_status_code = code;
- m_status_msg = msg;
- }
-
- void set_body(const std::string& value) {
- if (value.size() == 0) {
- remove_header("Content-Length");
- m_body = "";
- return;
- }
-
- std::stringstream foo;
- foo << value.size();
- replace_header("Content-Length", foo.str());
- m_body = value;
- }
-
- status_code::value get_status_code() const {
- return m_status_code;
- }
-
- const std::string& get_status_msg() const {
- return m_status_msg;
- }
+ // parse a complete header (ie \r\n\r\n MUST be in the input stream)
+ bool parse_complete(std::istream& s) {
+ std::string response;
+
+ // get status line
+ std::getline(s, response);
+
+ if (response[response.size()-1] == '\r') {
+ response.erase(response.end()-1);
+
+ std::stringstream ss(response);
+ std::string str_val;
+ int int_val;
+ char char_val[256];
+
+ ss >> str_val;
+ set_version(str_val);
+
+ ss >> int_val;
+ ss.getline(char_val,256);
+ set_status(status_code::value(int_val),std::string(char_val));
+ } else {
+ return false;
+ }
+
+ return parse_headers(s);
+ }
+
+ // TODO: validation. Make sure all required fields have been set?
+ std::string raw() {
+ std::stringstream raw;
+
+ raw << version() << " " << m_status_code << " " << m_status_msg << "\r\n";
+ raw << raw_headers() << "\r\n";
+
+ raw << m_body;
+
+ return raw.str();
+ }
+
+ void set_status(status_code::value code) {
+ // TODO: validation?
+ m_status_code = code;
+ m_status_msg = get_string(code);
+ }
+
+ void set_status(status_code::value code, const std::string& msg) {
+ // TODO: validation?
+ m_status_code = code;
+ m_status_msg = msg;
+ }
+
+ void set_body(const std::string& value) {
+ if (value.size() == 0) {
+ remove_header("Content-Length");
+ m_body = "";
+ return;
+ }
+
+ std::stringstream foo;
+ foo << value.size();
+ replace_header("Content-Length", foo.str());
+ m_body = value;
+ }
+
+ status_code::value get_status_code() const {
+ return m_status_code;
+ }
+
+ const std::string& get_status_msg() const {
+ return m_status_msg;
+ }
private:
- status_code::value m_status_code;
- std::string m_status_msg;
- std::string m_body;
+ status_code::value m_status_code;
+ std::string m_status_msg;
+ std::string m_body;
};
}
diff --git a/src/logger/logger.hpp b/src/logger/logger.hpp
index 4b5cc7f89a..49491c3e8b 100644
--- a/src/logger/logger.hpp
+++ b/src/logger/logger.hpp
@@ -37,127 +37,125 @@ namespace websocketpp {
namespace log {
namespace alevel {
- typedef uint16_t value;
-
- static const value OFF = 0x0;
-
- // A single line on connect with connecting ip, websocket version,
- // request resource, user agent, and the response code.
- static const value CONNECT = 0x1;
- // A single line on disconnect with wasClean status and local and remote
- // close codes and reasons.
- static const value DISCONNECT = 0x2;
- // A single line on incoming and outgoing control messages.
- static const value CONTROL = 0x4;
- // A single line on incoming and outgoing frames with full frame headers
- static const value FRAME_HEADER = 0x10;
- // Adds payloads to frame logs. Note these can be long!
- static const value FRAME_PAYLOAD = 0x20;
- // A single line on incoming and outgoing messages with metadata about type,
- // length, etc
- static const value MESSAGE_HEADER = 0x40;
- // Adds payloads to message logs. Note these can be long!
- static const value MESSAGE_PAYLOAD = 0x80;
-
-
- // DEBUG values
- static const value DEBUG_HANDSHAKE = 0x8000;
- static const value DEBUG_CLOSE = 0x4000;
- static const value DEVEL = 0x2000;
-
- static const value ALL = 0xFFFF;
+ typedef uint16_t value;
+
+ static const value OFF = 0x0;
+
+ // A single line on connect with connecting ip, websocket version,
+ // request resource, user agent, and the response code.
+ static const value CONNECT = 0x1;
+ // A single line on disconnect with wasClean status and local and remote
+ // close codes and reasons.
+ static const value DISCONNECT = 0x2;
+ // A single line on incoming and outgoing control messages.
+ static const value CONTROL = 0x4;
+ // A single line on incoming and outgoing frames with full frame headers
+ static const value FRAME_HEADER = 0x10;
+ // Adds payloads to frame logs. Note these can be long!
+ static const value FRAME_PAYLOAD = 0x20;
+ // A single line on incoming and outgoing messages with metadata about type,
+ // length, etc
+ static const value MESSAGE_HEADER = 0x40;
+ // Adds payloads to message logs. Note these can be long!
+ static const value MESSAGE_PAYLOAD = 0x80;
+
+
+ // DEBUG values
+ static const value DEBUG_HANDSHAKE = 0x8000;
+ static const value DEBUG_CLOSE = 0x4000;
+ static const value DEVEL = 0x2000;
+
+ static const value ALL = 0xFFFF;
}
namespace elevel {
- typedef uint16_t value;
-
- static const value OFF = 0x0;
-
- static const value DEVEL = 0x1; // debugging
- static const value LIBRARY = 0x2; // library usage exceptions
- static const value INFO = 0x4;
- static const value WARN = 0x8;
- static const value ERROR = 0x10;
- static const value FATAL = 0x20;
-
- static const value ALL = 0xFFFF;
+ typedef uint16_t value;
+
+ static const value OFF = 0x0;
+
+ static const value DEVEL = 0x1; // debugging
+ static const value LIBRARY = 0x2; // library usage exceptions
+ static const value INFO = 0x4;
+ static const value WARN = 0x8;
+ static const value ERROR = 0x10;
+ static const value FATAL = 0x20;
+
+ static const value ALL = 0xFFFF;
}
-
+
template
class logger {
public:
- template
- logger& operator<<(T a) {
- if (test_level(m_write_level)) {
- m_oss << a;
- }
- return *this;
- }
-
- logger& operator<<(logger& (*f)(logger&)) {
- return f(*this);
- }
-
- bool test_level(level_type l) {
- return (m_level & l) != 0;
- }
-
- void set_level(level_type l) {
- m_level |= l;
- }
-
- void set_levels(level_type l1, level_type l2) {
- level_type i = l1;
-
- while (i <= l2) {
- set_level(i);
- i *= 2;
- }
- }
-
- void unset_level(level_type l) {
- m_level &= ~l;
- }
-
- void set_prefix(const std::string& prefix) {
- if (prefix == "") {
- m_prefix = prefix;
- } else {
- m_prefix = prefix + " ";
- }
- }
-
- logger& print() {
- if (test_level(m_write_level)) {
- std::cout << m_prefix <<
- boost::posix_time::to_iso_extended_string(
- boost::posix_time::second_clock::local_time()
- ) << " [" << m_write_level << "] " << m_oss.str() << std::endl;
- m_oss.str("");
- }
-
- return *this;
- }
-
- logger& at(level_type l) {
- m_write_level = l;
- return *this;
- }
+ template
+ logger& operator<<(T a) {
+ if (test_level(m_write_level)) {
+ m_oss << a;
+ }
+ return *this;
+ }
+
+ logger& operator<<(logger& (*f)(logger&)) {
+ return f(*this);
+ }
+
+ bool test_level(level_type l) {
+ return (m_level & l) != 0;
+ }
+
+ void set_level(level_type l) {
+ m_level |= l;
+ }
+
+ void set_levels(level_type l1, level_type l2) {
+ level_type i = l1;
+
+ while (i <= l2) {
+ set_level(i);
+ i *= 2;
+ }
+ }
+
+ void unset_level(level_type l) {
+ m_level &= ~l;
+ }
+
+ void set_prefix(const std::string& prefix) {
+ if (prefix == "") {
+ m_prefix = prefix;
+ } else {
+ m_prefix = prefix + " ";
+ }
+ }
+
+ logger& print() {
+ if (test_level(m_write_level)) {
+ std::cout << m_prefix <<
+ boost::posix_time::to_iso_extended_string(
+ boost::posix_time::second_clock::local_time()
+ ) << " [" << m_write_level << "] " << m_oss.str() << std::endl;
+ m_oss.str("");
+ }
+
+ return *this;
+ }
+
+ logger& at(level_type l) {
+ m_write_level = l;
+ return *this;
+ }
private:
- std::ostringstream m_oss;
- level_type m_write_level;
- level_type m_level;
- std::string m_prefix;
+ std::ostringstream m_oss;
+ level_type m_write_level;
+ level_type m_level;
+ std::string m_prefix;
};
template
logger& endl(logger& out)
{
- return out.print();
+ return out.print();
}
-
-
}
}
diff --git a/src/messages/control.hpp b/src/messages/control.hpp
index bd49f1633d..a3cc9d5296 100644
--- a/src/messages/control.hpp
+++ b/src/messages/control.hpp
@@ -44,19 +44,19 @@ public:
m_payload.reserve(PAYLOAD_SIZE_INIT);
}
- frame::opcode::value get_opcode() const {
+ frame::opcode::value get_opcode() const {
return m_opcode;
};
-
- const std::string& get_payload() const {
- return m_payload;
- }
-
+
+ const std::string& get_payload() const {
+ return m_payload;
+ }
+
uint64_t process_payload(std::istream& input,uint64_t size) {
char c;
const uint64_t new_size = m_payload.size() + size;
uint64_t i;
-
+
if (new_size > PAYLOAD_SIZE_MAX) {
throw processor::exception("Message payload was too large.",processor::error::MESSAGE_TOO_BIG);
}
@@ -73,9 +73,9 @@ public:
if (input.good()) {
// process c
if (m_masking_index >= 0) {
- c = c ^ m_masking_key[(m_masking_index++)%4];
- }
-
+ c = c ^ m_masking_key[(m_masking_index++)%4];
+ }
+
// add c to payload
m_payload.push_back(c);
} else if (input.eof()) {
@@ -90,91 +90,91 @@ public:
return i;
}
- void complete() {
- if (m_opcode == frame::opcode::CLOSE) {
- if (m_payload.size() == 1) {
- throw processor::exception("Single byte close code",processor::error::PROTOCOL_VIOLATION);
- } else if (m_payload.size() >= 2) {
- close::status::value code = close::status::value(get_raw_close_code());
-
- if (close::status::invalid(code)) {
- throw processor::exception("Close code is not allowed on the wire.",processor::error::PROTOCOL_VIOLATION);
- } else if (close::status::reserved(code)) {
- throw processor::exception("Close code is reserved.",processor::error::PROTOCOL_VIOLATION);
- }
-
- }
- if (m_payload.size() > 2) {
- if (!m_validator.decode(m_payload.begin()+2,m_payload.end())) {
- throw processor::exception("Invalid UTF8",processor::error::PAYLOAD_VIOLATION);
- }
- if (!m_validator.complete()) {
- throw processor::exception("Invalid UTF8",processor::error::PAYLOAD_VIOLATION);
- }
- }
- }
- }
-
+ void complete() {
+ if (m_opcode == frame::opcode::CLOSE) {
+ if (m_payload.size() == 1) {
+ throw processor::exception("Single byte close code",processor::error::PROTOCOL_VIOLATION);
+ } else if (m_payload.size() >= 2) {
+ close::status::value code = close::status::value(get_raw_close_code());
+
+ if (close::status::invalid(code)) {
+ throw processor::exception("Close code is not allowed on the wire.",processor::error::PROTOCOL_VIOLATION);
+ } else if (close::status::reserved(code)) {
+ throw processor::exception("Close code is reserved.",processor::error::PROTOCOL_VIOLATION);
+ }
+
+ }
+ if (m_payload.size() > 2) {
+ if (!m_validator.decode(m_payload.begin()+2,m_payload.end())) {
+ throw processor::exception("Invalid UTF8",processor::error::PAYLOAD_VIOLATION);
+ }
+ if (!m_validator.complete()) {
+ throw processor::exception("Invalid UTF8",processor::error::PAYLOAD_VIOLATION);
+ }
+ }
+ }
+ }
+
void reset(frame::opcode::value opcode, uint32_t masking_key) {
m_opcode = opcode;
set_masking_key(masking_key);
m_payload.resize(0);
- m_validator.reset();
+ m_validator.reset();
+ }
+
+ close::status::value get_close_code() const {
+ if (m_payload.size() == 0) {
+ return close::status::NO_STATUS;
+ } else {
+ return close::status::value(get_raw_close_code());
+ }
+ }
+
+ std::string get_close_reason() const {
+ if (m_payload.size() > 2) {
+ return m_payload.substr(2);
+ } else {
+ return std::string();
+ }
+ }
+
+ void set_masking_key(int32_t key) {
+ *reinterpret_cast(m_masking_key) = key;
+ m_masking_index = (key == 0 ? -1 : 0);
}
-
- close::status::value get_close_code() const {
- if (m_payload.size() == 0) {
- return close::status::NO_STATUS;
- } else {
- return close::status::value(get_raw_close_code());
- }
- }
-
- std::string get_close_reason() const {
- if (m_payload.size() > 2) {
- return m_payload.substr(2);
- } else {
- return std::string();
- }
- }
-
- void set_masking_key(int32_t key) {
- *reinterpret_cast(m_masking_key) = key;
- m_masking_index = (key == 0 ? -1 : 0);
- }
private:
- uint16_t get_raw_close_code() const {
- if (m_payload.size() <= 1) {
- throw processor::exception("get_raw_close_code called with invalid size",processor::error::FATAL_ERROR);
- }
-
- char val[2];
-
- val[0] = m_payload[0];
- val[1] = m_payload[1];
-
- return ntohs(*(reinterpret_cast(&val[0])));
- }
-
+ uint16_t get_raw_close_code() const {
+ if (m_payload.size() <= 1) {
+ throw processor::exception("get_raw_close_code called with invalid size",processor::error::FATAL_ERROR);
+ }
+
+ char val[2];
+
+ val[0] = m_payload[0];
+ val[1] = m_payload[1];
+
+ return ntohs(*(reinterpret_cast(&val[0])));
+ }
+
static const uint64_t PAYLOAD_SIZE_INIT = 128; // 128B
static const uint64_t PAYLOAD_SIZE_MAX = 128; // 128B
- // Message state
- frame::opcode::value m_opcode;
-
- // UTF8 validation state
- utf8_validator::validator m_validator;
-
- // Masking state
- unsigned char m_masking_key[4];
+ // Message state
+ frame::opcode::value m_opcode;
+
+ // UTF8 validation state
+ utf8_validator::validator m_validator;
+
+ // Masking state
+ unsigned char m_masking_key[4];
int m_masking_index;
-
- // Message payload
- std::string m_payload;
+
+ // Message payload
+ std::string m_payload;
};
typedef boost::shared_ptr control_ptr;
-
+
} // namespace message
} // namespace websocketpp
diff --git a/src/messages/data.cpp b/src/messages/data.cpp
index f6fb9cdf6d..252dcf8043 100644
--- a/src/messages/data.cpp
+++ b/src/messages/data.cpp
@@ -39,14 +39,14 @@ data::data(data::pool_ptr p, size_t s) : m_prepared(false),m_index(s),m_ref_coun
websocketpp::frame::opcode::value data::get_opcode() const {
return m_opcode;
}
-
+
const std::string& data::get_payload() const {
return m_payload;
}
const std::string& data::get_header() const {
return m_header;
}
-
+
uint64_t data::process_payload(std::istream& input,uint64_t size) {
unsigned char c;
const uint64_t new_size = m_payload.size() + size;
@@ -84,7 +84,7 @@ uint64_t data::process_payload(std::istream& input,uint64_t size) {
// successfully read all bytes
return i;
}
-
+
void data::process_character(unsigned char c) {
if (m_masking_index >= 0) {
c = c ^ m_masking_key[m_masking_index];
@@ -108,7 +108,7 @@ void data::reset(frame::opcode::value opcode) {
m_validator.reset();
m_prepared = false;
}
-
+
void data::complete() {
if (m_opcode == frame::opcode::TEXT) {
if (!m_validator.complete()) {
diff --git a/src/messages/data.hpp b/src/messages/data.hpp
index b131e066d2..4b74261993 100644
--- a/src/messages/data.hpp
+++ b/src/messages/data.hpp
@@ -151,11 +151,11 @@ public:
typedef pool::ptr pool_ptr;
data(pool_ptr p, size_t s);
-
+
void reset(frame::opcode::value opcode);
frame::opcode::value get_opcode() const;
- const std::string& get_payload() const;
+ const std::string& get_payload() const;
const std::string& get_header() const;
// ##reading##
@@ -167,8 +167,8 @@ public:
// throws a processor::exception if the message is too big, there is a fatal
// istream read error, or invalid UTF8 data is read for a text message
uint64_t process_payload(std::istream& input,uint64_t size);
- void process_character(unsigned char c);
- void complete();
+ void process_character(unsigned char c);
+ void complete();
void validate_payload();
// ##writing##
@@ -183,7 +183,7 @@ public:
void set_prepared(bool b);
bool get_prepared() const;
void mask();
-
+
// pool management interface
void set_live();
size_t get_index() const;
@@ -216,19 +216,19 @@ private:
}
}
- // Message state
- frame::opcode::value m_opcode;
-
- // UTF8 validation state
- utf8_validator::validator m_validator;
-
- // Masking state
- unsigned char m_masking_key[4];
+ // Message state
+ frame::opcode::value m_opcode;
+
+ // UTF8 validation state
+ utf8_validator::validator m_validator;
+
+ // Masking state
+ unsigned char m_masking_key[4];
// m_masking_index can take on
index_value m_masking_index;
std::string m_header;
- std::string m_payload;
+ std::string m_payload;
bool m_prepared;
@@ -240,7 +240,7 @@ private:
};
typedef boost::intrusive_ptr data_ptr;
-
+
} // namespace message
} // namespace websocketpp
diff --git a/src/network_utilities.cpp b/src/network_utilities.cpp
index 1994ab9316..792551d5e8 100644
--- a/src/network_utilities.cpp
+++ b/src/network_utilities.cpp
@@ -28,57 +28,57 @@
#include "network_utilities.hpp"
uint64_t htonll(uint64_t src) {
- static int typ = TYP_INIT;
- unsigned char c;
- union {
- uint64_t ull;
- unsigned char c[8];
- } x;
- if (typ == TYP_INIT) {
- x.ull = 0x01;
- typ = (x.c[7] == 0x01ULL) ? TYP_BIGE : TYP_SMLE;
- }
- if (typ == TYP_BIGE)
- return src;
- x.ull = src;
- c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c;
- c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c;
- c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c;
- c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c;
- return x.ull;
+ static int typ = TYP_INIT;
+ unsigned char c;
+ union {
+ uint64_t ull;
+ unsigned char c[8];
+ } x;
+ if (typ == TYP_INIT) {
+ x.ull = 0x01;
+ typ = (x.c[7] == 0x01ULL) ? TYP_BIGE : TYP_SMLE;
+ }
+ if (typ == TYP_BIGE)
+ return src;
+ x.ull = src;
+ c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c;
+ c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c;
+ c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c;
+ c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c;
+ return x.ull;
}
uint64_t ntohll(uint64_t src) {
- return htonll(src);
+ return htonll(src);
}
std::string lookup_ws_close_status_string(uint16_t code) {
- switch (code) {
- case 1000:
- return "Normal closure";
- case 1001:
- return "Going away";
- case 1002:
- return "Protocol error";
- case 1003:
- return "Unacceptable data";
- case 1004:
- return "Reserved";
- case 1005:
- return "No status received";
- case 1006:
- return "Abnormal closure";
- case 1007:
- return "Invalid message data";
- case 1008:
- return "Policy Violation";
- case 1009:
- return "Message too large";
- case 1010:
- return "Missing required extensions";
- default:
- return "Unknown";
- }
+ switch (code) {
+ case 1000:
+ return "Normal closure";
+ case 1001:
+ return "Going away";
+ case 1002:
+ return "Protocol error";
+ case 1003:
+ return "Unacceptable data";
+ case 1004:
+ return "Reserved";
+ case 1005:
+ return "No status received";
+ case 1006:
+ return "Abnormal closure";
+ case 1007:
+ return "Invalid message data";
+ case 1008:
+ return "Policy Violation";
+ case 1009:
+ return "Message too large";
+ case 1010:
+ return "Missing required extensions";
+ default:
+ return "Unknown";
+ }
}
std::string to_hex(const std::string& input) {
diff --git a/src/processors/hybi.hpp b/src/processors/hybi.hpp
index 920dbb1fc5..fb938af110 100644
--- a/src/processors/hybi.hpp
+++ b/src/processors/hybi.hpp
@@ -41,11 +41,11 @@ namespace websocketpp {
namespace processor {
namespace hybi_state {
- enum value {
- READ_HEADER = 0,
- READ_PAYLOAD = 1,
- READY = 2
- };
+ enum value {
+ READ_HEADER = 0,
+ READ_PAYLOAD = 1,
+ READY = 2
+ };
}
/*
@@ -104,163 +104,163 @@ private:
template
class hybi : public processor_base {
public:
- hybi(connection_type &connection)
+ hybi(connection_type &connection)
: m_connection(connection),
m_write_frame(connection)
{
- reset();
- }
-
- void validate_handshake(const http::parser::request& request) const {
- std::stringstream err;
- std::string h;
-
- if (request.method() != "GET") {
- err << "Websocket handshake has invalid method: "
- << request.method();
-
- throw(http::exception(err.str(),http::status_code::BAD_REQUEST));
- }
-
- // TODO: allow versions greater than 1.1
- if (request.version() != "HTTP/1.1") {
- err << "Websocket handshake has invalid HTTP version: "
- << request.method();
-
- throw(http::exception(err.str(),http::status_code::BAD_REQUEST));
- }
-
- // verify the presence of required headers
- if (request.header("Host") == "") {
- throw(http::exception("Required Host header is missing",http::status_code::BAD_REQUEST));
- }
-
- h = request.header("Upgrade");
- if (h == "") {
- throw(http::exception("Required Upgrade header is missing",http::status_code::BAD_REQUEST));
- } else if (!boost::ifind_first(h,"websocket")) {
- err << "Upgrade header \"" << h << "\", does not contain required token \"websocket\"";
- throw(http::exception(err.str(),http::status_code::BAD_REQUEST));
- }
-
- h = request.header("Connection");
- if (h == "") {
- throw(http::exception("Required Connection header is missing",http::status_code::BAD_REQUEST));
- } else if (!boost::ifind_first(h,"upgrade")) {
- err << "Connection header, \"" << h
- << "\", does not contain required token \"upgrade\"";
- throw(http::exception(err.str(),http::status_code::BAD_REQUEST));
- }
-
- if (request.header("Sec-WebSocket-Key") == "") {
- throw(http::exception("Required Sec-WebSocket-Key header is missing",http::status_code::BAD_REQUEST));
- }
-
- h = request.header("Sec-WebSocket-Version");
- if (h == "") {
- throw(http::exception("Required Sec-WebSocket-Version header is missing",http::status_code::BAD_REQUEST));
- } else {
- int version = atoi(h.c_str());
-
- if (version != 7 && version != 8 && version != 13) {
- err << "This processor doesn't support WebSocket protocol version "
- << version;
- throw(http::exception(err.str(),http::status_code::BAD_REQUEST));
- }
- }
- }
-
- std::string get_origin(const http::parser::request& request) const {
- std::string h = request.header("Sec-WebSocket-Version");
- int version = atoi(h.c_str());
-
- if (version == 13) {
- return request.header("Origin");
- } else if (version == 7 || version == 8) {
- return request.header("Sec-WebSocket-Origin");
- } else {
- throw(http::exception("Could not determine origin header. Check Sec-WebSocket-Version header",http::status_code::BAD_REQUEST));
- }
- }
-
- uri_ptr get_uri(const http::parser::request& request) const {
- std::string h = request.header("Host");
-
- size_t last_colon = h.rfind(":");
+ reset();
+ }
+
+ void validate_handshake(const http::parser::request& request) const {
+ std::stringstream err;
+ std::string h;
+
+ if (request.method() != "GET") {
+ err << "Websocket handshake has invalid method: "
+ << request.method();
+
+ throw(http::exception(err.str(),http::status_code::BAD_REQUEST));
+ }
+
+ // TODO: allow versions greater than 1.1
+ if (request.version() != "HTTP/1.1") {
+ err << "Websocket handshake has invalid HTTP version: "
+ << request.method();
+
+ throw(http::exception(err.str(),http::status_code::BAD_REQUEST));
+ }
+
+ // verify the presence of required headers
+ if (request.header("Host") == "") {
+ throw(http::exception("Required Host header is missing",http::status_code::BAD_REQUEST));
+ }
+
+ h = request.header("Upgrade");
+ if (h == "") {
+ throw(http::exception("Required Upgrade header is missing",http::status_code::BAD_REQUEST));
+ } else if (!boost::ifind_first(h,"websocket")) {
+ err << "Upgrade header \"" << h << "\", does not contain required token \"websocket\"";
+ throw(http::exception(err.str(),http::status_code::BAD_REQUEST));
+ }
+
+ h = request.header("Connection");
+ if (h == "") {
+ throw(http::exception("Required Connection header is missing",http::status_code::BAD_REQUEST));
+ } else if (!boost::ifind_first(h,"upgrade")) {
+ err << "Connection header, \"" << h
+ << "\", does not contain required token \"upgrade\"";
+ throw(http::exception(err.str(),http::status_code::BAD_REQUEST));
+ }
+
+ if (request.header("Sec-WebSocket-Key") == "") {
+ throw(http::exception("Required Sec-WebSocket-Key header is missing",http::status_code::BAD_REQUEST));
+ }
+
+ h = request.header("Sec-WebSocket-Version");
+ if (h == "") {
+ throw(http::exception("Required Sec-WebSocket-Version header is missing",http::status_code::BAD_REQUEST));
+ } else {
+ int version = atoi(h.c_str());
+
+ if (version != 7 && version != 8 && version != 13) {
+ err << "This processor doesn't support WebSocket protocol version "
+ << version;
+ throw(http::exception(err.str(),http::status_code::BAD_REQUEST));
+ }
+ }
+ }
+
+ std::string get_origin(const http::parser::request& request) const {
+ std::string h = request.header("Sec-WebSocket-Version");
+ int version = atoi(h.c_str());
+
+ if (version == 13) {
+ return request.header("Origin");
+ } else if (version == 7 || version == 8) {
+ return request.header("Sec-WebSocket-Origin");
+ } else {
+ throw(http::exception("Could not determine origin header. Check Sec-WebSocket-Version header",http::status_code::BAD_REQUEST));
+ }
+ }
+
+ uri_ptr get_uri(const http::parser::request& request) const {
+ std::string h = request.header("Host");
+
+ size_t last_colon = h.rfind(":");
size_t last_sbrace = h.rfind("]");
// no : = hostname with no port
// last : before ] = ipv6 literal with no port
// : with no ] = hostname with port
// : after ] = ipv6 literal with port
- if (last_colon == std::string::npos ||
+ if (last_colon == std::string::npos ||
(last_sbrace != std::string::npos && last_sbrace > last_colon))
{
- return uri_ptr(new uri(m_connection.is_secure(),h,request.uri()));
- } else {
- return uri_ptr(new uri(m_connection.is_secure(),
- h.substr(0,last_colon),
- h.substr(last_colon+1),
- request.uri()));
- }
-
- // TODO: check if get_uri is a full uri
- }
-
- void handshake_response(const http::parser::request& request,
- http::parser::response& response)
- {
- std::string server_key = request.header("Sec-WebSocket-Key");
- server_key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
-
- SHA1 sha;
- uint32_t message_digest[5];
-
- sha.Reset();
- sha << server_key.c_str();
-
- if (sha.Result(message_digest)){
- // convert sha1 hash bytes to network byte order because this sha1
- // library works on ints rather than bytes
- for (int i = 0; i < 5; i++) {
- message_digest[i] = htonl(message_digest[i]);
- }
-
- server_key = base64_encode(
- reinterpret_cast
- (message_digest),20
- );
-
- // set handshake accept headers
- response.replace_header("Sec-WebSocket-Accept",server_key);
- response.add_header("Upgrade","websocket");
- response.add_header("Connection","Upgrade");
- } else {
- //m_endpoint->elog().at(log::elevel::ERROR)
- //<< "Error computing handshake sha1 hash" << log::endl;
- // TODO: make sure this error path works
- response.set_status(http::status_code::INTERNAL_SERVER_ERROR);
- }
- }
-
- void consume(std::istream& s) {
- while (s.good() && m_state != hybi_state::READY) {
- try {
- switch (m_state) {
- case hybi_state::READ_HEADER:
- process_header(s);
- break;
- case hybi_state::READ_PAYLOAD:
- process_payload(s);
- break;
- case hybi_state::READY:
- // shouldn't be here..
- break;
- default:
- break;
- }
- } catch (const processor::exception& e) {
- if (e.code() != processor::error::OUT_OF_MESSAGES) {
+ return uri_ptr(new uri(m_connection.is_secure(),h,request.uri()));
+ } else {
+ return uri_ptr(new uri(m_connection.is_secure(),
+ h.substr(0,last_colon),
+ h.substr(last_colon+1),
+ request.uri()));
+ }
+
+ // TODO: check if get_uri is a full uri
+ }
+
+ void handshake_response(const http::parser::request& request,
+ http::parser::response& response)
+ {
+ std::string server_key = request.header("Sec-WebSocket-Key");
+ server_key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+
+ SHA1 sha;
+ uint32_t message_digest[5];
+
+ sha.Reset();
+ sha << server_key.c_str();
+
+ if (sha.Result(message_digest)){
+ // convert sha1 hash bytes to network byte order because this sha1
+ // library works on ints rather than bytes
+ for (int i = 0; i < 5; i++) {
+ message_digest[i] = htonl(message_digest[i]);
+ }
+
+ server_key = base64_encode(
+ reinterpret_cast
+ (message_digest),20
+ );
+
+ // set handshake accept headers
+ response.replace_header("Sec-WebSocket-Accept",server_key);
+ response.add_header("Upgrade","websocket");
+ response.add_header("Connection","Upgrade");
+ } else {
+ //m_endpoint->elog().at(log::elevel::ERROR)
+ //<< "Error computing handshake sha1 hash" << log::endl;
+ // TODO: make sure this error path works
+ response.set_status(http::status_code::INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ void consume(std::istream& s) {
+ while (s.good() && m_state != hybi_state::READY) {
+ try {
+ switch (m_state) {
+ case hybi_state::READ_HEADER:
+ process_header(s);
+ break;
+ case hybi_state::READ_PAYLOAD:
+ process_payload(s);
+ break;
+ case hybi_state::READY:
+ // shouldn't be here..
+ break;
+ default:
+ break;
+ }
+ } catch (const processor::exception& e) {
+ if (e.code() != processor::error::OUT_OF_MESSAGES) {
// The out of messages exception acts as an inturrupt rather
// than an error. In that case we don't want to reset
// processor state. In all other cases we are aborting
@@ -270,244 +270,244 @@ public:
m_header.reset();
}
}
-
- throw e;
- }
- }
- }
-
- void process_header(std::istream& s) {
- m_header.consume(s);
-
- if (m_header.ready()) {
- // Get a free message from the read queue for the type of the
- // current message
- if (m_header.is_control()) {
- process_control_header();
- } else {
- process_data_header();
- }
- }
- }
-
- void process_control_header() {
- m_control_message = m_connection.get_control_message();
-
- if (!m_control_message) {
- throw processor::exception("Out of control messages",
- processor::error::OUT_OF_MESSAGES);
- }
-
- m_control_message->reset(m_header.get_opcode(),m_header.get_masking_key());
-
- m_payload_left = m_header.get_payload_size();
-
- if (m_payload_left == 0) {
- process_frame();
- } else {
- m_state = hybi_state::READ_PAYLOAD;
- }
- }
-
- void process_data_header() {
- if (!m_data_message) {
- // This is a new message. No continuation frames allowed.
- if (m_header.get_opcode() == frame::opcode::CONTINUATION) {
- throw processor::exception("Received continuation frame without an outstanding message.",processor::error::PROTOCOL_VIOLATION);
- }
-
- m_data_message = m_connection.get_data_message();
-
- if (!m_data_message) {
- throw processor::exception("Out of data messages",
- processor::error::OUT_OF_MESSAGES);
- }
-
- m_data_message->reset(m_header.get_opcode());
- } else {
- // A message has already been started. Continuation frames only!
- if (m_header.get_opcode() != frame::opcode::CONTINUATION) {
- throw processor::exception("Received new message before the completion of the existing one.",processor::error::PROTOCOL_VIOLATION);
- }
- }
-
- m_payload_left = m_header.get_payload_size();
-
- if (m_payload_left == 0) {
- process_frame();
- } else {
- // each frame has a new masking key
- m_data_message->set_masking_key(m_header.get_masking_key());
- m_state = hybi_state::READ_PAYLOAD;
- }
- }
-
- void process_payload(std::istream& input) {
- uint64_t written;
- if (m_header.is_control()) {
- written = m_control_message->process_payload(input,m_payload_left);
- } else {
- //m_connection.alog().at(log::alevel::DEVEL) << "process_payload. Size: " << m_payload_left << log::endl;
- written = m_data_message->process_payload(input,m_payload_left);
- }
- m_payload_left -= written;
-
- if (m_payload_left == 0) {
- process_frame();
- }
-
- }
-
- void process_frame() {
- if (m_header.get_fin()) {
- if (m_header.is_control()) {
- m_control_message->complete();
- } else {
- m_data_message->complete();
- }
- m_state = hybi_state::READY;
- } else {
- reset();
- }
- }
-
- bool ready() const {
- return m_state == hybi_state::READY;
- }
-
- bool is_control() const {
- return m_header.is_control();
- }
-
- // note this can only be called once
- message::data_ptr get_data_message() {
- message::data_ptr p = m_data_message;
- m_data_message.reset();
- return p;
- }
-
- // note this can only be called once
- message::control_ptr get_control_message() {
- message::control_ptr p = m_control_message;
- m_control_message.reset();
- return p;
- }
-
- void reset() {
- m_state = m_state = hybi_state::READ_HEADER;
- m_header.reset();
- }
-
- uint64_t get_bytes_needed() const {
- switch (m_state) {
- case hybi_state::READ_HEADER:
- return m_header.get_bytes_needed();
- case hybi_state::READ_PAYLOAD:
- return m_payload_left;
- case hybi_state::READY:
- return 0;
- default:
- throw "shouldn't be here";
- }
- }
+
+ throw e;
+ }
+ }
+ }
+
+ void process_header(std::istream& s) {
+ m_header.consume(s);
+
+ if (m_header.ready()) {
+ // Get a free message from the read queue for the type of the
+ // current message
+ if (m_header.is_control()) {
+ process_control_header();
+ } else {
+ process_data_header();
+ }
+ }
+ }
+
+ void process_control_header() {
+ m_control_message = m_connection.get_control_message();
+
+ if (!m_control_message) {
+ throw processor::exception("Out of control messages",
+ processor::error::OUT_OF_MESSAGES);
+ }
+
+ m_control_message->reset(m_header.get_opcode(),m_header.get_masking_key());
+
+ m_payload_left = m_header.get_payload_size();
+
+ if (m_payload_left == 0) {
+ process_frame();
+ } else {
+ m_state = hybi_state::READ_PAYLOAD;
+ }
+ }
+
+ void process_data_header() {
+ if (!m_data_message) {
+ // This is a new message. No continuation frames allowed.
+ if (m_header.get_opcode() == frame::opcode::CONTINUATION) {
+ throw processor::exception("Received continuation frame without an outstanding message.",processor::error::PROTOCOL_VIOLATION);
+ }
+
+ m_data_message = m_connection.get_data_message();
+
+ if (!m_data_message) {
+ throw processor::exception("Out of data messages",
+ processor::error::OUT_OF_MESSAGES);
+ }
+
+ m_data_message->reset(m_header.get_opcode());
+ } else {
+ // A message has already been started. Continuation frames only!
+ if (m_header.get_opcode() != frame::opcode::CONTINUATION) {
+ throw processor::exception("Received new message before the completion of the existing one.",processor::error::PROTOCOL_VIOLATION);
+ }
+ }
+
+ m_payload_left = m_header.get_payload_size();
+
+ if (m_payload_left == 0) {
+ process_frame();
+ } else {
+ // each frame has a new masking key
+ m_data_message->set_masking_key(m_header.get_masking_key());
+ m_state = hybi_state::READ_PAYLOAD;
+ }
+ }
+
+ void process_payload(std::istream& input) {
+ uint64_t written;
+ if (m_header.is_control()) {
+ written = m_control_message->process_payload(input,m_payload_left);
+ } else {
+ //m_connection.alog().at(log::alevel::DEVEL) << "process_payload. Size: " << m_payload_left << log::endl;
+ written = m_data_message->process_payload(input,m_payload_left);
+ }
+ m_payload_left -= written;
+
+ if (m_payload_left == 0) {
+ process_frame();
+ }
+
+ }
+
+ void process_frame() {
+ if (m_header.get_fin()) {
+ if (m_header.is_control()) {
+ m_control_message->complete();
+ } else {
+ m_data_message->complete();
+ }
+ m_state = hybi_state::READY;
+ } else {
+ reset();
+ }
+ }
+
+ bool ready() const {
+ return m_state == hybi_state::READY;
+ }
+
+ bool is_control() const {
+ return m_header.is_control();
+ }
+
+ // note this can only be called once
+ message::data_ptr get_data_message() {
+ message::data_ptr p = m_data_message;
+ m_data_message.reset();
+ return p;
+ }
+
+ // note this can only be called once
+ message::control_ptr get_control_message() {
+ message::control_ptr p = m_control_message;
+ m_control_message.reset();
+ return p;
+ }
+
+ void reset() {
+ m_state = m_state = hybi_state::READ_HEADER;
+ m_header.reset();
+ }
+
+ uint64_t get_bytes_needed() const {
+ switch (m_state) {
+ case hybi_state::READ_HEADER:
+ return m_header.get_bytes_needed();
+ case hybi_state::READ_PAYLOAD:
+ return m_payload_left;
+ case hybi_state::READY:
+ return 0;
+ default:
+ throw "shouldn't be here";
+ }
+ }
+
+ // TODO: replace all this to remove all lingering dependencies on
+ // websocket_frame
+ binary_string_ptr prepare_frame(frame::opcode::value opcode,
+ bool mask,
+ const utf8_string& payload) {
+ /*if (opcode != frame::opcode::TEXT) {
+ // TODO: hybi_legacy doesn't allow non-text frames.
+ throw;
+ }*/
+
+ // TODO: utf8 validation on payload.
+
+
+
+ binary_string_ptr response(new binary_string(0));
+
+
+ m_write_frame.reset();
+ m_write_frame.set_opcode(opcode);
+ m_write_frame.set_masked(mask);
+
+ m_write_frame.set_fin(true);
+ m_write_frame.set_payload(payload);
+
+
+ m_write_frame.process_payload();
+
+ // TODO
+ response->resize(m_write_frame.get_header_len()+m_write_frame.get_payload().size());
+
+ // copy header
+ std::copy(m_write_frame.get_header(),m_write_frame.get_header()+m_write_frame.get_header_len(),response->begin());
+
+ // copy payload
+ std::copy(m_write_frame.get_payload().begin(),m_write_frame.get_payload().end(),response->begin()+m_write_frame.get_header_len());
+
+
+ return response;
+ }
+
+ binary_string_ptr prepare_frame(frame::opcode::value opcode,
+ bool mask,
+ const binary_string& payload) {
+ /*if (opcode != frame::opcode::TEXT) {
+ // TODO: hybi_legacy doesn't allow non-text frames.
+ throw;
+ }*/
+
+ // TODO: utf8 validation on payload.
+
+ binary_string_ptr response(new binary_string(0));
+
+ m_write_frame.reset();
+ m_write_frame.set_opcode(opcode);
+ m_write_frame.set_masked(mask);
+ m_write_frame.set_fin(true);
+ m_write_frame.set_payload(payload);
+
+ m_write_frame.process_payload();
+
+ // TODO
+ response->resize(m_write_frame.get_header_len()+m_write_frame.get_payload().size());
+
+ // copy header
+ std::copy(m_write_frame.get_header(),m_write_frame.get_header()+m_write_frame.get_header_len(),response->begin());
+
+ // copy payload
+ std::copy(m_write_frame.get_payload().begin(),m_write_frame.get_payload().end(),response->begin()+m_write_frame.get_header_len());
+
+ return response;
+ }
+
+ /*binary_string_ptr prepare_close_frame(close::status::value code,
+ bool mask,
+ const std::string& reason) {
+ binary_string_ptr response(new binary_string(0));
+
+ m_write_frame.reset();
+ m_write_frame.set_opcode(frame::opcode::CLOSE);
+ m_write_frame.set_masked(mask);
+ m_write_frame.set_fin(true);
+ m_write_frame.set_status(code,reason);
+
+ m_write_frame.process_payload();
+
+ // TODO
+ response->resize(m_write_frame.get_header_len()+m_write_frame.get_payload().size());
+
+ // copy header
+ std::copy(m_write_frame.get_header(),m_write_frame.get_header()+m_write_frame.get_header_len(),response->begin());
+
+ // copy payload
+ std::copy(m_write_frame.get_payload().begin(),m_write_frame.get_payload().end(),response->begin()+m_write_frame.get_header_len());
+
+ return response;
+ }*/
- // TODO: replace all this to remove all lingering dependencies on
- // websocket_frame
- binary_string_ptr prepare_frame(frame::opcode::value opcode,
- bool mask,
- const utf8_string& payload) {
- /*if (opcode != frame::opcode::TEXT) {
- // TODO: hybi_legacy doesn't allow non-text frames.
- throw;
- }*/
-
- // TODO: utf8 validation on payload.
-
-
-
- binary_string_ptr response(new binary_string(0));
-
-
- m_write_frame.reset();
- m_write_frame.set_opcode(opcode);
- m_write_frame.set_masked(mask);
-
- m_write_frame.set_fin(true);
- m_write_frame.set_payload(payload);
-
-
- m_write_frame.process_payload();
-
- // TODO
- response->resize(m_write_frame.get_header_len()+m_write_frame.get_payload().size());
-
- // copy header
- std::copy(m_write_frame.get_header(),m_write_frame.get_header()+m_write_frame.get_header_len(),response->begin());
-
- // copy payload
- std::copy(m_write_frame.get_payload().begin(),m_write_frame.get_payload().end(),response->begin()+m_write_frame.get_header_len());
-
-
- return response;
- }
-
- binary_string_ptr prepare_frame(frame::opcode::value opcode,
- bool mask,
- const binary_string& payload) {
- /*if (opcode != frame::opcode::TEXT) {
- // TODO: hybi_legacy doesn't allow non-text frames.
- throw;
- }*/
-
- // TODO: utf8 validation on payload.
-
- binary_string_ptr response(new binary_string(0));
-
- m_write_frame.reset();
- m_write_frame.set_opcode(opcode);
- m_write_frame.set_masked(mask);
- m_write_frame.set_fin(true);
- m_write_frame.set_payload(payload);
-
- m_write_frame.process_payload();
-
- // TODO
- response->resize(m_write_frame.get_header_len()+m_write_frame.get_payload().size());
-
- // copy header
- std::copy(m_write_frame.get_header(),m_write_frame.get_header()+m_write_frame.get_header_len(),response->begin());
-
- // copy payload
- std::copy(m_write_frame.get_payload().begin(),m_write_frame.get_payload().end(),response->begin()+m_write_frame.get_header_len());
-
- return response;
- }
-
- /*binary_string_ptr prepare_close_frame(close::status::value code,
- bool mask,
- const std::string& reason) {
- binary_string_ptr response(new binary_string(0));
-
- m_write_frame.reset();
- m_write_frame.set_opcode(frame::opcode::CLOSE);
- m_write_frame.set_masked(mask);
- m_write_frame.set_fin(true);
- m_write_frame.set_status(code,reason);
-
- m_write_frame.process_payload();
-
- // TODO
- response->resize(m_write_frame.get_header_len()+m_write_frame.get_payload().size());
-
- // copy header
- std::copy(m_write_frame.get_header(),m_write_frame.get_header()+m_write_frame.get_header_len(),response->begin());
-
- // copy payload
- std::copy(m_write_frame.get_payload().begin(),m_write_frame.get_payload().end(),response->begin()+m_write_frame.get_header_len());
-
- return response;
- }*/
-
// new prepare frame stuff
void prepare_frame(message::data_ptr msg) {
assert(msg);
@@ -558,18 +558,18 @@ public:
prepare_frame(msg);
}
private:
- connection_type& m_connection;
- int m_state;
-
- message::data_ptr m_data_message;
- message::control_ptr m_control_message;
- hybi_header m_header;
- hybi_header m_write_header;
- uint64_t m_payload_left;
-
+ connection_type& m_connection;
+ int m_state;
- frame::parser m_write_frame; // TODO: refactor this out
-};
+ message::data_ptr m_data_message;
+ message::control_ptr m_control_message;
+ hybi_header m_header;
+ hybi_header m_write_header;
+ uint64_t m_payload_left;
+
+
+ frame::parser m_write_frame; // TODO: refactor this out
+};
} // namespace processor
} // namespace websocketpp
diff --git a/src/processors/hybi_header.cpp b/src/processors/hybi_header.cpp
index fab21860ad..ae587f7d06 100644
--- a/src/processors/hybi_header.cpp
+++ b/src/processors/hybi_header.cpp
@@ -32,83 +32,83 @@
using websocketpp::processor::hybi_header;
hybi_header::hybi_header() {
- reset();
+ reset();
}
void hybi_header::reset() {
memset(m_header, 0x00, MAX_HEADER_LENGTH);
- m_state = STATE_BASIC_HEADER;
+ m_state = STATE_BASIC_HEADER;
m_bytes_needed = BASIC_HEADER_LENGTH;
}
// Writing interface (parse a byte stream)
void hybi_header::consume(std::istream& input) {
- switch (m_state) {
- case STATE_BASIC_HEADER:
- input.read(&m_header[BASIC_HEADER_LENGTH-m_bytes_needed],
+ switch (m_state) {
+ case STATE_BASIC_HEADER:
+ input.read(&m_header[BASIC_HEADER_LENGTH-m_bytes_needed],
m_bytes_needed);
-
- m_bytes_needed -= input.gcount();
-
- if (m_bytes_needed == 0) {
- process_basic_header();
-
- validate_basic_header();
-
- if (m_bytes_needed > 0) {
- m_state = STATE_EXTENDED_HEADER;
- } else {
- process_extended_header();
- m_state = STATE_READY;
- }
- }
- break;
- case STATE_EXTENDED_HEADER:
- input.read(&m_header[get_header_len()-m_bytes_needed],
+
+ m_bytes_needed -= input.gcount();
+
+ if (m_bytes_needed == 0) {
+ process_basic_header();
+
+ validate_basic_header();
+
+ if (m_bytes_needed > 0) {
+ m_state = STATE_EXTENDED_HEADER;
+ } else {
+ process_extended_header();
+ m_state = STATE_READY;
+ }
+ }
+ break;
+ case STATE_EXTENDED_HEADER:
+ input.read(&m_header[get_header_len()-m_bytes_needed],
m_bytes_needed);
-
- m_bytes_needed -= input.gcount();
-
- if (m_bytes_needed == 0) {
- process_extended_header();
- m_state = STATE_READY;
- }
- break;
- default:
- break;
- }
+
+ m_bytes_needed -= input.gcount();
+
+ if (m_bytes_needed == 0) {
+ process_extended_header();
+ m_state = STATE_READY;
+ }
+ break;
+ default:
+ break;
+ }
}
uint64_t hybi_header::get_bytes_needed() const {
- return m_bytes_needed;
+ return m_bytes_needed;
}
bool hybi_header::ready() const {
- return m_state == STATE_READY;
+ return m_state == STATE_READY;
}
// Writing interface (set fields directly)
void hybi_header::set_fin(bool fin) {
- set_header_bit(BPB0_FIN,0,fin);
+ set_header_bit(BPB0_FIN,0,fin);
}
void hybi_header::set_rsv1(bool b) {
- set_header_bit(BPB0_RSV1,0,b);
+ set_header_bit(BPB0_RSV1,0,b);
}
void hybi_header::set_rsv2(bool b) {
- set_header_bit(BPB0_RSV2,0,b);
+ set_header_bit(BPB0_RSV2,0,b);
}
void hybi_header::set_rsv3(bool b) {
- set_header_bit(BPB0_RSV3,0,b);
+ set_header_bit(BPB0_RSV3,0,b);
}
void hybi_header::set_opcode(frame::opcode::value op) {
- m_header[0] &= (0xFF ^ BPB0_OPCODE); // clear op bits
- m_header[0] |= op; // set op bits
+ m_header[0] &= (0xFF ^ BPB0_OPCODE); // clear op bits
+ m_header[0] |= op; // set op bits
}
void hybi_header::set_masked(bool masked,int32_t key) {
- if (masked) {
- m_header[1] |= BPB1_MASK;
- set_masking_key(key);
- } else {
- m_header[1] &= (0xFF ^ BPB1_MASK);
- clear_masking_key();
- }
+ if (masked) {
+ m_header[1] |= BPB1_MASK;
+ set_masking_key(key);
+ } else {
+ m_header[1] &= (0xFF ^ BPB1_MASK);
+ clear_masking_key();
+ }
}
void hybi_header::set_payload_size(uint64_t size) {
if (size <= frame::limits::PAYLOAD_SIZE_BASIC) {
@@ -153,137 +153,137 @@ std::string hybi_header::get_header_bytes() const {
// Reading interface (get fields directly)
bool hybi_header::get_fin() const {
- return ((m_header[0] & BPB0_FIN) == BPB0_FIN);
+ return ((m_header[0] & BPB0_FIN) == BPB0_FIN);
}
bool hybi_header::get_rsv1() const {
- return ((m_header[0] & BPB0_RSV1) == BPB0_RSV1);
+ return ((m_header[0] & BPB0_RSV1) == BPB0_RSV1);
}
bool hybi_header::get_rsv2() const {
- return ((m_header[0] & BPB0_RSV2) == BPB0_RSV2);
+ return ((m_header[0] & BPB0_RSV2) == BPB0_RSV2);
}
bool hybi_header::get_rsv3() const {
- return ((m_header[0] & BPB0_RSV3) == BPB0_RSV3);
+ return ((m_header[0] & BPB0_RSV3) == BPB0_RSV3);
}
websocketpp::frame::opcode::value hybi_header::get_opcode() const {
- return frame::opcode::value(m_header[0] & BPB0_OPCODE);
+ return frame::opcode::value(m_header[0] & BPB0_OPCODE);
}
bool hybi_header::get_masked() const {
- return ((m_header[1] & BPB1_MASK) == BPB1_MASK);
+ return ((m_header[1] & BPB1_MASK) == BPB1_MASK);
}
int32_t hybi_header::get_masking_key() const {
- if (!get_masked()) {
- return 0;
- }
- return *reinterpret_cast(&m_header[get_header_len()-4]);
+ if (!get_masked()) {
+ return 0;
+ }
+ return *reinterpret_cast(&m_header[get_header_len()-4]);
}
uint64_t hybi_header::get_payload_size() const {
- return m_payload_size;
+ return m_payload_size;
}
bool hybi_header::is_control() const {
- return (frame::opcode::is_control(get_opcode()));
+ return (frame::opcode::is_control(get_opcode()));
}
// private
unsigned int hybi_header::get_header_len() const {
- unsigned int temp = 2;
-
- if (get_masked()) {
- temp += 4;
- }
-
- if (get_basic_size() == 126) {
- temp += 2;
- } else if (get_basic_size() == 127) {
- temp += 8;
- }
-
- return temp;
+ unsigned int temp = 2;
+
+ if (get_masked()) {
+ temp += 4;
+ }
+
+ if (get_basic_size() == 126) {
+ temp += 2;
+ } else if (get_basic_size() == 127) {
+ temp += 8;
+ }
+
+ return temp;
}
uint8_t hybi_header::get_basic_size() const {
- return m_header[1] & BPB1_PAYLOAD;
+ return m_header[1] & BPB1_PAYLOAD;
}
void hybi_header::validate_basic_header() const {
// check for control frame size
- if (is_control() && get_basic_size() > frame::limits::PAYLOAD_SIZE_BASIC) {
- throw processor::exception("Control Frame is too large",processor::error::PROTOCOL_VIOLATION);
- }
-
- // check for reserved bits
- if (get_rsv1() || get_rsv2() || get_rsv3()) {
- throw processor::exception("Reserved bit used",processor::error::PROTOCOL_VIOLATION);
- }
-
- // check for reserved opcodes
- if (frame::opcode::reserved(get_opcode())) {
- throw processor::exception("Reserved opcode used",processor::error::PROTOCOL_VIOLATION);
- }
+ if (is_control() && get_basic_size() > frame::limits::PAYLOAD_SIZE_BASIC) {
+ throw processor::exception("Control Frame is too large",processor::error::PROTOCOL_VIOLATION);
+ }
+
+ // check for reserved bits
+ if (get_rsv1() || get_rsv2() || get_rsv3()) {
+ throw processor::exception("Reserved bit used",processor::error::PROTOCOL_VIOLATION);
+ }
+
+ // check for reserved opcodes
+ if (frame::opcode::reserved(get_opcode())) {
+ throw processor::exception("Reserved opcode used",processor::error::PROTOCOL_VIOLATION);
+ }
// check for invalid opcodes
- if (frame::opcode::invalid(get_opcode())) {
- throw processor::exception("Invalid opcode used",processor::error::PROTOCOL_VIOLATION);
- }
-
- // check for fragmented control message
- if (is_control() && !get_fin()) {
- throw processor::exception("Fragmented control message",processor::error::PROTOCOL_VIOLATION);
- }
+ if (frame::opcode::invalid(get_opcode())) {
+ throw processor::exception("Invalid opcode used",processor::error::PROTOCOL_VIOLATION);
+ }
+
+ // check for fragmented control message
+ if (is_control() && !get_fin()) {
+ throw processor::exception("Fragmented control message",processor::error::PROTOCOL_VIOLATION);
+ }
}
void hybi_header::process_basic_header() {
- m_bytes_needed = get_header_len() - BASIC_HEADER_LENGTH;
+ m_bytes_needed = get_header_len() - BASIC_HEADER_LENGTH;
}
void hybi_header::process_extended_header() {
- uint8_t s = get_basic_size();
-
- if (s <= frame::limits::PAYLOAD_SIZE_BASIC) {
- m_payload_size = s;
- } else if (s == BASIC_PAYLOAD_16BIT_CODE) {
- // reinterpret the second two bytes as a 16 bit integer in network
- // byte order. Convert to host byte order and store locally.
- m_payload_size = ntohs(*(
+ uint8_t s = get_basic_size();
+
+ if (s <= frame::limits::PAYLOAD_SIZE_BASIC) {
+ m_payload_size = s;
+ } else if (s == BASIC_PAYLOAD_16BIT_CODE) {
+ // reinterpret the second two bytes as a 16 bit integer in network
+ // byte order. Convert to host byte order and store locally.
+ m_payload_size = ntohs(*(
reinterpret_cast(&m_header[BASIC_HEADER_LENGTH])
));
-
- if (m_payload_size < s) {
- std::stringstream err;
- err << "payload length not minimally encoded. Using 16 bit form for payload size: " << m_payload_size;
- throw processor::exception(err.str(),processor::error::PROTOCOL_VIOLATION);
- }
-
- } else if (s == BASIC_PAYLOAD_64BIT_CODE) {
- // reinterpret the second eight bytes as a 64 bit integer in
- // network byte order. Convert to host byte order and store.
- m_payload_size = ntohll(*(
+
+ if (m_payload_size < s) {
+ std::stringstream err;
+ err << "payload length not minimally encoded. Using 16 bit form for payload size: " << m_payload_size;
+ throw processor::exception(err.str(),processor::error::PROTOCOL_VIOLATION);
+ }
+
+ } else if (s == BASIC_PAYLOAD_64BIT_CODE) {
+ // reinterpret the second eight bytes as a 64 bit integer in
+ // network byte order. Convert to host byte order and store.
+ m_payload_size = ntohll(*(
reinterpret_cast(&m_header[BASIC_HEADER_LENGTH])
));
-
- if (m_payload_size <= frame::limits::PAYLOAD_SIZE_EXTENDED) {
- throw processor::exception("payload length not minimally encoded",
- processor::error::PROTOCOL_VIOLATION);
- }
-
- } else {
- // TODO: shouldn't be here how to handle?
- throw processor::exception("invalid get_basic_size in process_extended_header");
- }
+
+ if (m_payload_size <= frame::limits::PAYLOAD_SIZE_EXTENDED) {
+ throw processor::exception("payload length not minimally encoded",
+ processor::error::PROTOCOL_VIOLATION);
+ }
+
+ } else {
+ // TODO: shouldn't be here how to handle?
+ throw processor::exception("invalid get_basic_size in process_extended_header");
+ }
}
void hybi_header::set_header_bit(uint8_t bit,int byte,bool value) {
- if (value) {
- m_header[byte] |= bit;
- } else {
- m_header[byte] &= (0xFF ^ bit);
- }
+ if (value) {
+ m_header[byte] |= bit;
+ } else {
+ m_header[byte] &= (0xFF ^ bit);
+ }
}
void hybi_header::set_masking_key(int32_t key) {
- *(reinterpret_cast(&m_header[get_header_len()-4])) = key;
+ *(reinterpret_cast(&m_header[get_header_len()-4])) = key;
}
void hybi_header::clear_masking_key() {
- // this is a no-op as clearing the mask bit also changes the get_header_len
- // method to not include these byte ranges. Whenever the masking bit is re-
- // set a new key is generated anyways.
+ // this is a no-op as clearing the mask bit also changes the get_header_len
+ // method to not include these byte ranges. Whenever the masking bit is re-
+ // set a new key is generated anyways.
}
\ No newline at end of file
diff --git a/src/processors/hybi_header.hpp b/src/processors/hybi_header.hpp
index 6343a05c62..0437ef4692 100644
--- a/src/processors/hybi_header.hpp
+++ b/src/processors/hybi_header.hpp
@@ -57,16 +57,16 @@ namespace processor {
class hybi_header {
public:
/// Construct a header processor and initialize for writing
- hybi_header();
+ hybi_header();
/// Reset a header processor for writing
- void reset();
-
- // Writing interface (parse a byte stream)
+ void reset();
+
+ // Writing interface (parse a byte stream)
// valid only if ready() returns false
// Consume will throw a processor::exception in the case that the bytes it
// read do not form a valid WebSocket frame header.
void consume(std::istream& input);
- uint64_t get_bytes_needed() const;
+ uint64_t get_bytes_needed() const;
bool ready() const;
// Writing interface (set fields directly)
@@ -110,37 +110,37 @@ private:
// helper functions for writing
void process_basic_header();
- void process_extended_header();
+ void process_extended_header();
void set_header_bit(uint8_t bit,int byte,bool value);
void set_masking_key(int32_t key);
- void clear_masking_key();
+ void clear_masking_key();
- // basic payload byte flags
- static const uint8_t BPB0_OPCODE = 0x0F;
- static const uint8_t BPB0_RSV3 = 0x10;
- static const uint8_t BPB0_RSV2 = 0x20;
- static const uint8_t BPB0_RSV1 = 0x40;
- static const uint8_t BPB0_FIN = 0x80;
- static const uint8_t BPB1_PAYLOAD = 0x7F;
- static const uint8_t BPB1_MASK = 0x80;
-
- static const uint8_t BASIC_PAYLOAD_16BIT_CODE = 0x7E; // 126
- static const uint8_t BASIC_PAYLOAD_64BIT_CODE = 0x7F; // 127
-
- static const unsigned int BASIC_HEADER_LENGTH = 2;
- static const unsigned int MAX_HEADER_LENGTH = 14;
-
- static const uint8_t STATE_BASIC_HEADER = 1;
- static const uint8_t STATE_EXTENDED_HEADER = 2;
- static const uint8_t STATE_READY = 3;
+ // basic payload byte flags
+ static const uint8_t BPB0_OPCODE = 0x0F;
+ static const uint8_t BPB0_RSV3 = 0x10;
+ static const uint8_t BPB0_RSV2 = 0x20;
+ static const uint8_t BPB0_RSV1 = 0x40;
+ static const uint8_t BPB0_FIN = 0x80;
+ static const uint8_t BPB1_PAYLOAD = 0x7F;
+ static const uint8_t BPB1_MASK = 0x80;
+
+ static const uint8_t BASIC_PAYLOAD_16BIT_CODE = 0x7E; // 126
+ static const uint8_t BASIC_PAYLOAD_64BIT_CODE = 0x7F; // 127
+
+ static const unsigned int BASIC_HEADER_LENGTH = 2;
+ static const unsigned int MAX_HEADER_LENGTH = 14;
+
+ static const uint8_t STATE_BASIC_HEADER = 1;
+ static const uint8_t STATE_EXTENDED_HEADER = 2;
+ static const uint8_t STATE_READY = 3;
static const uint8_t STATE_WRITE = 4;
-
- uint8_t m_state;
- uint64_t m_bytes_needed;
- uint64_t m_payload_size;
- char m_header[MAX_HEADER_LENGTH];
+
+ uint8_t m_state;
+ uint64_t m_bytes_needed;
+ uint64_t m_payload_size;
+ char m_header[MAX_HEADER_LENGTH];
};
-
+
} // namespace processor
} // namespace websocketpp
diff --git a/src/processors/hybi_legacy.hpp b/src/processors/hybi_legacy.hpp
index acdb00b894..44632217de 100644
--- a/src/processors/hybi_legacy.hpp
+++ b/src/processors/hybi_legacy.hpp
@@ -37,230 +37,230 @@ namespace websocketpp {
namespace processor {
namespace hybi_legacy_state {
- enum value {
- INIT = 0,
- READ = 1,
- DONE = 2
- };
+ enum value {
+ INIT = 0,
+ READ = 1,
+ DONE = 2
+ };
}
template
class hybi_legacy : public processor_base {
public:
- hybi_legacy(connection_type &connection)
- : m_connection(connection),
- m_state(hybi_legacy_state::INIT)
- {
- reset();
- }
-
- void validate_handshake(const http::parser::request& headers) const {
-
- }
-
- void handshake_response(const http::parser::request& request,http::parser::response& response) {
- char key_final[16];
-
- // key1
- *reinterpret_cast(&key_final[0]) =
- decode_client_key(request.header("Sec-WebSocket-Key1"));
-
- // key2
- *reinterpret_cast(&key_final[4]) =
- decode_client_key(request.header("Sec-WebSocket-Key2"));
-
- // key3
- memcpy(&key_final[8],request.header("Sec-WebSocket-Key3").c_str(),8);
-
- // md5
+ hybi_legacy(connection_type &connection)
+ : m_connection(connection),
+ m_state(hybi_legacy_state::INIT)
+ {
+ reset();
+ }
+
+ void validate_handshake(const http::parser::request& headers) const {
+
+ }
+
+ void handshake_response(const http::parser::request& request,http::parser::response& response) {
+ char key_final[16];
+
+ // key1
+ *reinterpret_cast(&key_final[0]) =
+ decode_client_key(request.header("Sec-WebSocket-Key1"));
+
+ // key2
+ *reinterpret_cast(&key_final[4]) =
+ decode_client_key(request.header("Sec-WebSocket-Key2"));
+
+ // key3
+ memcpy(&key_final[8],request.header("Sec-WebSocket-Key3").c_str(),8);
+
+ // md5
m_key3 = key_final;
- m_key3 = md5_hash_string(m_key3);
-
- response.add_header("Upgrade","websocket");
- response.add_header("Connection","Upgrade");
-
- // TODO: require headers that need application specific information?
-
- // Echo back client's origin unless our local application set a
- // more restrictive one.
- if (response.header("Sec-WebSocket-Origin") == "") {
- response.add_header("Sec-WebSocket-Origin",request.header("Origin"));
- }
-
- // Echo back the client's request host unless our local application
- // set a different one.
- if (response.header("Sec-WebSocket-Location") == "") {
- // TODO: extract from host header rather than hard code
- uri_ptr uri = get_uri(request);
- response.add_header("Sec-WebSocket-Location",uri->str());
- }
- }
-
- std::string get_origin(const http::parser::request& request) const {
- return request.header("Origin");
- }
-
- uri_ptr get_uri(const http::parser::request& request) const {
- std::string h = request.header("Host");
-
- size_t last_colon = h.rfind(":");
+ m_key3 = md5_hash_string(m_key3);
+
+ response.add_header("Upgrade","websocket");
+ response.add_header("Connection","Upgrade");
+
+ // TODO: require headers that need application specific information?
+
+ // Echo back client's origin unless our local application set a
+ // more restrictive one.
+ if (response.header("Sec-WebSocket-Origin") == "") {
+ response.add_header("Sec-WebSocket-Origin",request.header("Origin"));
+ }
+
+ // Echo back the client's request host unless our local application
+ // set a different one.
+ if (response.header("Sec-WebSocket-Location") == "") {
+ // TODO: extract from host header rather than hard code
+ uri_ptr uri = get_uri(request);
+ response.add_header("Sec-WebSocket-Location",uri->str());
+ }
+ }
+
+ std::string get_origin(const http::parser::request& request) const {
+ return request.header("Origin");
+ }
+
+ uri_ptr get_uri(const http::parser::request& request) const {
+ std::string h = request.header("Host");
+
+ size_t last_colon = h.rfind(":");
size_t last_sbrace = h.rfind("]");
// no : = hostname with no port
// last : before ] = ipv6 literal with no port
// : with no ] = hostname with port
// : after ] = ipv6 literal with port
- if (last_colon == std::string::npos ||
+ if (last_colon == std::string::npos ||
(last_sbrace != std::string::npos && last_sbrace > last_colon))
{
- return uri_ptr(new uri(m_connection.is_secure(),h,request.uri()));
- } else {
- return uri_ptr(new uri(m_connection.is_secure(),
- h.substr(0,last_colon),
- h.substr(last_colon+1),
- request.uri()));
- }
-
- // TODO: check if get_uri is a full uri
- }
-
- void consume(std::istream& s) {
- //unsigned char c;
- while (s.good() && m_state != hybi_legacy_state::DONE) {
- //c = s.get();
- //if (s.good()) {
- process(s);
- //}
- }
- }
-
- bool ready() const {
- return m_state == hybi_legacy_state::DONE;
- }
-
- // legacy hybi has no control messages.
- bool is_control() const {
- return false;
- }
-
- message::data_ptr get_data_message() {
- message::data_ptr p = m_data_message;
- m_data_message.reset();
- return p;
- }
-
- message::control_ptr get_control_message() {
- throw "Hybi legacy has no control messages.";
- }
-
- void process(std::istream& input) {
- if (m_state == hybi_legacy_state::INIT) {
- // we are looking for a 0x00
- if (input.peek() == 0x00) {
- // start a message
- input.ignore();
-
- m_state = hybi_legacy_state::READ;
-
- m_data_message = m_connection.get_data_message();
-
- if (!m_data_message) {
- throw processor::exception("Out of data messages",processor::error::OUT_OF_MESSAGES);
- }
-
- m_data_message->reset(frame::opcode::TEXT);
- } else {
- input.ignore();
- // TODO: ignore or error
- //std::stringstream foo;
-
- //foo << "invalid character read: |" << input.peek() << "|";
-
- std::cout << "invalid character read: |" << input.peek() << "|" << std::endl;
-
- //throw processor::exception(foo.str(),processor::error::PROTOCOL_VIOLATION);
- }
- } else if (m_state == hybi_legacy_state::READ) {
- if (input.peek() == 0xFF) {
- // end
- input.ignore();
-
- m_state = hybi_legacy_state::DONE;
- } else {
- if (m_data_message) {
- m_data_message->process_payload(input,1);
- }
- }
- }
- }
-
- void reset() {
- m_state = hybi_legacy_state::INIT;
- m_data_message.reset();
- }
-
- uint64_t get_bytes_needed() const {
- return 1;
- }
-
- std::string get_key3() const {
- return m_key3;
- }
-
- // TODO: to factor away
- binary_string_ptr prepare_frame(frame::opcode::value opcode,
- bool mask,
- const binary_string& payload) {
- if (opcode != frame::opcode::TEXT) {
- // TODO: hybi_legacy doesn't allow non-text frames.
- throw;
- }
-
- // TODO: mask = ignore?
-
- // TODO: utf8 validation on payload.
-
- binary_string_ptr response(new binary_string(payload.size()+2));
-
- (*response)[0] = 0x00;
- std::copy(payload.begin(),payload.end(),response->begin()+1);
- (*response)[response->size()-1] = 0xFF;
-
- return response;
- }
-
- binary_string_ptr prepare_frame(frame::opcode::value opcode,
- bool mask,
- const utf8_string& payload) {
- if (opcode != frame::opcode::TEXT) {
- // TODO: hybi_legacy doesn't allow non-text frames.
- throw;
- }
-
- // TODO: mask = ignore?
-
- // TODO: utf8 validation on payload.
-
- binary_string_ptr response(new binary_string(payload.size()+2));
-
- (*response)[0] = 0x00;
- std::copy(payload.begin(),payload.end(),response->begin()+1);
- (*response)[response->size()-1] = 0xFF;
-
- return response;
- }
-
- binary_string_ptr prepare_close_frame(close::status::value code,
- bool mask,
- const std::string& reason) {
- binary_string_ptr response(new binary_string(2));
-
- (*response)[0] = 0xFF;
- (*response)[1] = 0x00;
-
- return response;
- }
-
+ return uri_ptr(new uri(m_connection.is_secure(),h,request.uri()));
+ } else {
+ return uri_ptr(new uri(m_connection.is_secure(),
+ h.substr(0,last_colon),
+ h.substr(last_colon+1),
+ request.uri()));
+ }
+
+ // TODO: check if get_uri is a full uri
+ }
+
+ void consume(std::istream& s) {
+ //unsigned char c;
+ while (s.good() && m_state != hybi_legacy_state::DONE) {
+ //c = s.get();
+ //if (s.good()) {
+ process(s);
+ //}
+ }
+ }
+
+ bool ready() const {
+ return m_state == hybi_legacy_state::DONE;
+ }
+
+ // legacy hybi has no control messages.
+ bool is_control() const {
+ return false;
+ }
+
+ message::data_ptr get_data_message() {
+ message::data_ptr p = m_data_message;
+ m_data_message.reset();
+ return p;
+ }
+
+ message::control_ptr get_control_message() {
+ throw "Hybi legacy has no control messages.";
+ }
+
+ void process(std::istream& input) {
+ if (m_state == hybi_legacy_state::INIT) {
+ // we are looking for a 0x00
+ if (input.peek() == 0x00) {
+ // start a message
+ input.ignore();
+
+ m_state = hybi_legacy_state::READ;
+
+ m_data_message = m_connection.get_data_message();
+
+ if (!m_data_message) {
+ throw processor::exception("Out of data messages",processor::error::OUT_OF_MESSAGES);
+ }
+
+ m_data_message->reset(frame::opcode::TEXT);
+ } else {
+ input.ignore();
+ // TODO: ignore or error
+ //std::stringstream foo;
+
+ //foo << "invalid character read: |" << input.peek() << "|";
+
+ std::cout << "invalid character read: |" << input.peek() << "|" << std::endl;
+
+ //throw processor::exception(foo.str(),processor::error::PROTOCOL_VIOLATION);
+ }
+ } else if (m_state == hybi_legacy_state::READ) {
+ if (input.peek() == 0xFF) {
+ // end
+ input.ignore();
+
+ m_state = hybi_legacy_state::DONE;
+ } else {
+ if (m_data_message) {
+ m_data_message->process_payload(input,1);
+ }
+ }
+ }
+ }
+
+ void reset() {
+ m_state = hybi_legacy_state::INIT;
+ m_data_message.reset();
+ }
+
+ uint64_t get_bytes_needed() const {
+ return 1;
+ }
+
+ std::string get_key3() const {
+ return m_key3;
+ }
+
+ // TODO: to factor away
+ binary_string_ptr prepare_frame(frame::opcode::value opcode,
+ bool mask,
+ const binary_string& payload) {
+ if (opcode != frame::opcode::TEXT) {
+ // TODO: hybi_legacy doesn't allow non-text frames.
+ throw;
+ }
+
+ // TODO: mask = ignore?
+
+ // TODO: utf8 validation on payload.
+
+ binary_string_ptr response(new binary_string(payload.size()+2));
+
+ (*response)[0] = 0x00;
+ std::copy(payload.begin(),payload.end(),response->begin()+1);
+ (*response)[response->size()-1] = 0xFF;
+
+ return response;
+ }
+
+ binary_string_ptr prepare_frame(frame::opcode::value opcode,
+ bool mask,
+ const utf8_string& payload) {
+ if (opcode != frame::opcode::TEXT) {
+ // TODO: hybi_legacy doesn't allow non-text frames.
+ throw;
+ }
+
+ // TODO: mask = ignore?
+
+ // TODO: utf8 validation on payload.
+
+ binary_string_ptr response(new binary_string(payload.size()+2));
+
+ (*response)[0] = 0x00;
+ std::copy(payload.begin(),payload.end(),response->begin()+1);
+ (*response)[response->size()-1] = 0xFF;
+
+ return response;
+ }
+
+ binary_string_ptr prepare_close_frame(close::status::value code,
+ bool mask,
+ const std::string& reason) {
+ binary_string_ptr response(new binary_string(2));
+
+ (*response)[0] = 0xFF;
+ (*response)[1] = 0x00;
+
+ return response;
+ }
+
void prepare_frame(message::data_ptr msg) {
assert(msg);
if (msg->get_prepared()) {
@@ -294,36 +294,36 @@ public:
}
private:
- uint32_t decode_client_key(const std::string& key) {
- int spaces = 0;
- std::string digits = "";
- uint32_t num;
-
- // key2
- for (size_t i = 0; i < key.size(); i++) {
- if (key[i] == ' ') {
- spaces++;
- } else if (key[i] >= '0' && key[i] <= '9') {
- digits += key[i];
- }
- }
-
- num = atoi(digits.c_str());
- if (spaces > 0 && num > 0) {
- return htonl(num/spaces);
- } else {
- return 0;
- }
- }
-
- connection_type& m_connection;
- hybi_legacy_state::value m_state;
-
- message::data_ptr m_data_message;
-
- std::string m_key3;
+ uint32_t decode_client_key(const std::string& key) {
+ int spaces = 0;
+ std::string digits = "";
+ uint32_t num;
+
+ // key2
+ for (size_t i = 0; i < key.size(); i++) {
+ if (key[i] == ' ') {
+ spaces++;
+ } else if (key[i] >= '0' && key[i] <= '9') {
+ digits += key[i];
+ }
+ }
+
+ num = atoi(digits.c_str());
+ if (spaces > 0 && num > 0) {
+ return htonl(num/spaces);
+ } else {
+ return 0;
+ }
+ }
+
+ connection_type& m_connection;
+ hybi_legacy_state::value m_state;
+
+ message::data_ptr m_data_message;
+
+ std::string m_key3;
};
-
+
} // processor
} // websocketpp
#endif // WEBSOCKET_PROCESSOR_HYBI_LEGACY_HPP
diff --git a/src/processors/processor.hpp b/src/processors/processor.hpp
index b616953186..9919f96d87 100644
--- a/src/processors/processor.hpp
+++ b/src/processors/processor.hpp
@@ -33,41 +33,41 @@
namespace websocketpp {
namespace processor {
-
+
namespace error {
- enum value {
- FATAL_ERROR = 0, // force session end
- SOFT_ERROR = 1, // should log and ignore
- PROTOCOL_VIOLATION = 2, // must end session
- PAYLOAD_VIOLATION = 3, // should end session
- INTERNAL_ENDPOINT_ERROR = 4,// cleanly end session
- MESSAGE_TOO_BIG = 5, // ???
- OUT_OF_MESSAGES = 6 // read queue is empty, wait
- };
+ enum value {
+ FATAL_ERROR = 0, // force session end
+ SOFT_ERROR = 1, // should log and ignore
+ PROTOCOL_VIOLATION = 2, // must end session
+ PAYLOAD_VIOLATION = 3, // should end session
+ INTERNAL_ENDPOINT_ERROR = 4,// cleanly end session
+ MESSAGE_TOO_BIG = 5, // ???
+ OUT_OF_MESSAGES = 6 // read queue is empty, wait
+ };
}
class exception : public std::exception {
-public:
- exception(const std::string& msg,
- error::value code = error::FATAL_ERROR)
- : m_msg(msg),m_code(code) {}
- ~exception() throw() {}
-
- virtual const char* what() const throw() {
- return m_msg.c_str();
- }
-
- error::value code() const throw() {
- return m_code;
- }
-
- std::string m_msg;
- error::value m_code;
+public:
+ exception(const std::string& msg,
+ error::value code = error::FATAL_ERROR)
+ : m_msg(msg),m_code(code) {}
+ ~exception() throw() {}
+
+ virtual const char* what() const throw() {
+ return m_msg.c_str();
+ }
+
+ error::value code() const throw() {
+ return m_code;
+ }
+
+ std::string m_msg;
+ error::value m_code;
};
} // namespace processor
} // namespace websocketpp
-
+
#include "../http/parser.hpp"
#include "../uri.hpp"
#include "../websocket_frame.hpp" // TODO: clean up
@@ -81,62 +81,62 @@ public:
namespace websocketpp {
namespace processor {
-
+
class processor_base {
public:
- // validate client handshake
- // validate server handshake
-
- // Given a list of HTTP headers determine if the values are sufficient
- // to start a websocket session. If so begin constructing a response, if not throw a handshake
- // exception.
- // validate handshake request
- virtual void validate_handshake(const http::parser::request& headers) const = 0;
-
- virtual void handshake_response(const http::parser::request& request,http::parser::response& response) = 0;
-
- // Extracts client origin from a handshake request
- virtual std::string get_origin(const http::parser::request& request) const = 0;
- // Extracts client uri from a handshake request
- virtual uri_ptr get_uri(const http::parser::request& request) const = 0;
-
- // consume bytes, throw on exception
- virtual void consume(std::istream& s) = 0;
-
- // is there a message ready to be dispatched?
- virtual bool ready() const = 0;
- virtual bool is_control() const = 0;
- virtual message::data_ptr get_data_message() = 0;
- virtual message::control_ptr get_control_message() = 0;
- virtual void reset() = 0;
-
- virtual uint64_t get_bytes_needed() const = 0;
-
- // Get information about the message that is ready
- //virtual frame::opcode::value get_opcode() const = 0;
-
- //virtual utf8_string_ptr get_utf8_payload() const = 0;
- //virtual binary_string_ptr get_binary_payload() const = 0;
- //virtual close::status::value get_close_code() const = 0;
- //virtual utf8_string get_close_reason() const = 0;
-
- // TODO: prepare a frame
- //virtual binary_string_ptr prepare_frame(frame::opcode::value opcode,
- // bool mask,
- // const utf8_string& payload) = 0;
- //virtual binary_string_ptr prepare_frame(frame::opcode::value opcode,
- // bool mask,
- // const binary_string& payload) = 0;
- //
- //virtual binary_string_ptr prepare_close_frame(close::status::value code,
- // bool mask,
- // const std::string& reason) = 0;
-
- virtual void prepare_frame(message::data_ptr msg) = 0;
+ // validate client handshake
+ // validate server handshake
+
+ // Given a list of HTTP headers determine if the values are sufficient
+ // to start a websocket session. If so begin constructing a response, if not throw a handshake
+ // exception.
+ // validate handshake request
+ virtual void validate_handshake(const http::parser::request& headers) const = 0;
+
+ virtual void handshake_response(const http::parser::request& request,http::parser::response& response) = 0;
+
+ // Extracts client origin from a handshake request
+ virtual std::string get_origin(const http::parser::request& request) const = 0;
+ // Extracts client uri from a handshake request
+ virtual uri_ptr get_uri(const http::parser::request& request) const = 0;
+
+ // consume bytes, throw on exception
+ virtual void consume(std::istream& s) = 0;
+
+ // is there a message ready to be dispatched?
+ virtual bool ready() const = 0;
+ virtual bool is_control() const = 0;
+ virtual message::data_ptr get_data_message() = 0;
+ virtual message::control_ptr get_control_message() = 0;
+ virtual void reset() = 0;
+
+ virtual uint64_t get_bytes_needed() const = 0;
+
+ // Get information about the message that is ready
+ //virtual frame::opcode::value get_opcode() const = 0;
+
+ //virtual utf8_string_ptr get_utf8_payload() const = 0;
+ //virtual binary_string_ptr get_binary_payload() const = 0;
+ //virtual close::status::value get_close_code() const = 0;
+ //virtual utf8_string get_close_reason() const = 0;
+
+ // TODO: prepare a frame
+ //virtual binary_string_ptr prepare_frame(frame::opcode::value opcode,
+ // bool mask,
+ // const utf8_string& payload) = 0;
+ //virtual binary_string_ptr prepare_frame(frame::opcode::value opcode,
+ // bool mask,
+ // const binary_string& payload) = 0;
+ //
+ //virtual binary_string_ptr prepare_close_frame(close::status::value code,
+ // bool mask,
+ // const std::string& reason) = 0;
+
+ virtual void prepare_frame(message::data_ptr msg) = 0;
virtual void prepare_close_frame(message::data_ptr msg,
close::status::value code,
const std::string& reason) = 0;
-
+
};
typedef boost::shared_ptr ptr;
diff --git a/src/rng/blank_rng.hpp b/src/rng/blank_rng.hpp
index 5bc731bf96..c4a53a99e8 100644
--- a/src/rng/blank_rng.hpp
+++ b/src/rng/blank_rng.hpp
@@ -33,14 +33,14 @@
#include
namespace websocketpp {
-
+
class blank_rng {
public:
- int32_t gen() {
- throw "Random Number generation not supported";
- }
+ int32_t gen() {
+ throw "Random Number generation not supported";
+ }
};
-
+
}
#endif // BLANK_RNG_HPP
diff --git a/src/rng/boost_rng.cpp b/src/rng/boost_rng.cpp
index a20212dca5..8cef6fe9dc 100644
--- a/src/rng/boost_rng.cpp
+++ b/src/rng/boost_rng.cpp
@@ -32,8 +32,8 @@
using websocketpp::boost_rng;
boost_rng::boost_rng() : m_gen(m_rng,
- boost::random::uniform_int_distribution<>(INT32_MIN,INT32_MAX)); {}
+ boost::random::uniform_int_distribution<>(INT32_MIN,INT32_MAX)); {}
int32_t boost_rng::gen() {
- return m_gen();
+ return m_gen();
}
\ No newline at end of file
diff --git a/src/rng/boost_rng.hpp b/src/rng/boost_rng.hpp
index 730fea05ab..2513163910 100644
--- a/src/rng/boost_rng.hpp
+++ b/src/rng/boost_rng.hpp
@@ -35,18 +35,18 @@
#include
namespace websocketpp {
- class boost_rng {
- public:
- boost_rng();
- int32_t gen();
- private:
- boost::random::random_device m_rng;
- boost::random::variate_generator
- <
- boost::random::random_device&,
- boost::random::uniform_int_distribution<>
- > m_gen;
- };
+ class boost_rng {
+ public:
+ boost_rng();
+ int32_t gen();
+ private:
+ boost::random::random_device m_rng;
+ boost::random::variate_generator
+ <
+ boost::random::random_device&,
+ boost::random::uniform_int_distribution<>
+ > m_gen;
+ };
}
#endif // BOOST_RNG_HPP
diff --git a/src/roles/client.hpp b/src/roles/client.hpp
index e3f4af2817..d320c64355 100644
--- a/src/roles/client.hpp
+++ b/src/roles/client.hpp
@@ -48,105 +48,105 @@ using boost::asio::ip::tcp;
namespace websocketpp {
namespace role {
-
+
template
class client {
public:
- // Connection specific details
- template
- class connection {
- public:
- typedef connection type;
- typedef endpoint endpoint_type;
+ // Connection specific details
+ template
+ class connection {
+ public:
+ typedef connection type;
+ typedef endpoint endpoint_type;
// client connections are friends with their respective client endpoint
friend class client;
// Valid always
int get_version() const {
- return m_version;
- }
-
- std::string get_origin() const {
- return m_origin;
- }
+ return m_version;
+ }
+
+ std::string get_origin() const {
+ return m_origin;
+ }
+
+ // not sure when valid
+ std::string get_request_header(const std::string& key) const {
+ return m_request.header(key);
+ }
+ std::string get_response_header(const std::string& key) const {
+ return m_response.header(key);
+ }
- // not sure when valid
- std::string get_request_header(const std::string& key) const {
- return m_request.header(key);
- }
- std::string get_response_header(const std::string& key) const {
- return m_response.header(key);
- }
-
// Valid before connect is called
void add_request_header(const std::string& key, const std::string& value) {
- m_request.add_header(key,value);
- }
- void replace_request_header(const std::string& key, const std::string& value) {
- m_request.replace_header(key,value);
- }
- void remove_request_header(const std::string& key) {
- m_request.remove_header(key);
- }
-
+ m_request.add_header(key,value);
+ }
+ void replace_request_header(const std::string& key, const std::string& value) {
+ m_request.replace_header(key,value);
+ }
+ void remove_request_header(const std::string& key) {
+ m_request.remove_header(key);
+ }
+
// Information about the requested URI
- // valid only after URIs are loaded
- // TODO: check m_uri for NULLness
- bool get_secure() const {
- return m_uri->get_secure();
- }
- std::string get_host() const {
- return m_uri->get_host();
- }
- std::string get_resource() const {
- return m_uri->get_resource();
- }
- uint16_t get_port() const {
- return m_uri->get_port();
- }
+ // valid only after URIs are loaded
+ // TODO: check m_uri for NULLness
+ bool get_secure() const {
+ return m_uri->get_secure();
+ }
+ std::string get_host() const {
+ return m_uri->get_host();
+ }
+ std::string get_resource() const {
+ return m_uri->get_resource();
+ }
+ uint16_t get_port() const {
+ return m_uri->get_port();
+ }
std::string get_uri() const {
- return m_uri->str();
- }
-
- int32_t rand() {
+ return m_uri->str();
+ }
+
+ int32_t rand() {
return m_endpoint.rand();
}
bool is_server() const {
return false;
}
-
- // should this exist?
- boost::asio::io_service& get_io_service() {
- return m_endpoint.get_io_service();
- }
- protected:
+
+ // should this exist?
+ boost::asio::io_service& get_io_service() {
+ return m_endpoint.get_io_service();
+ }
+ protected:
connection(endpoint& e)
: m_endpoint(e),
m_connection(static_cast< connection_type& >(*this)),
// TODO: version shouldn't be hardcoded
m_version(13) {}
-
+
void set_uri(uri_ptr u) {
m_uri = u;
}
- void async_init() {
- m_connection.m_processor = processor::ptr(new processor::hybi(m_connection));
-
- write_request();
- }
-
+ void async_init() {
+ m_connection.m_processor = processor::ptr(new processor::hybi(m_connection));
+
+ write_request();
+ }
- void write_request();
- void handle_write_request(const boost::system::error_code& error);
- void read_response();
- void handle_read_response(const boost::system::error_code& error,
- std::size_t bytes_transferred);
-
- void log_open_result();
+
+ void write_request();
+ void handle_write_request(const boost::system::error_code& error);
+ void read_response();
+ void handle_read_response(const boost::system::error_code& error,
+ std::size_t bytes_transferred);
+
+ void log_open_result();
// retry once
bool retry() {
@@ -157,92 +157,92 @@ public:
return true;
}
}
- private:
- endpoint& m_endpoint;
+ private:
+ endpoint& m_endpoint;
connection_type& m_connection;
- int m_version;
- uri_ptr m_uri;
- std::string m_origin;
- std::vector m_requested_subprotocols;
- std::vector m_requested_extensions;
- std::string m_subprotocol;
- std::vector m_extensions;
-
+ int m_version;
+ uri_ptr m_uri;
+ std::string m_origin;
+ std::vector m_requested_subprotocols;
+ std::vector m_requested_extensions;
+ std::string m_subprotocol;
+ std::vector m_extensions;
+
std::string m_handshake_key;
- http::parser::request m_request;
- http::parser::response m_response;
+ http::parser::request m_request;
+ http::parser::response m_response;
int m_retry;
- };
+ };
+
+ // types
+ typedef client type;
+ typedef endpoint endpoint_type;
+
+ typedef typename endpoint_traits::connection_ptr connection_ptr;
+ typedef typename endpoint_traits::handler_ptr handler_ptr;
- // types
- typedef client type;
- typedef endpoint endpoint_type;
-
- typedef typename endpoint_traits::connection_ptr connection_ptr;
- typedef typename endpoint_traits::handler_ptr handler_ptr;
-
// handler interface callback class
- class handler_interface {
- public:
- // Required
- virtual void on_open(connection_ptr connection) {};
- virtual void on_close(connection_ptr connection) {};
- virtual void on_fail(connection_ptr connection) {}
-
- virtual void on_message(connection_ptr connection,message::data_ptr) {};
-
- // Optional
- virtual bool on_ping(connection_ptr connection,std::string) {return true;}
- virtual void on_pong(connection_ptr connection,std::string) {}
-
- };
-
- client (boost::asio::io_service& m)
- : m_state(UNINITIALIZED),
- m_endpoint(static_cast< endpoint_type& >(*this)),
- m_io_service(m),
- m_resolver(m),
+ class handler_interface {
+ public:
+ // Required
+ virtual void on_open(connection_ptr connection) {};
+ virtual void on_close(connection_ptr connection) {};
+ virtual void on_fail(connection_ptr connection) {}
+
+ virtual void on_message(connection_ptr connection,message::data_ptr) {};
+
+ // Optional
+ virtual bool on_ping(connection_ptr connection,std::string) {return true;}
+ virtual void on_pong(connection_ptr connection,std::string) {}
+
+ };
+
+ client (boost::asio::io_service& m)
+ : m_state(UNINITIALIZED),
+ m_endpoint(static_cast< endpoint_type& >(*this)),
+ m_io_service(m),
+ m_resolver(m),
m_gen(m_rng,boost::random::uniform_int_distribution<>(INT32_MIN,
INT32_MAX)) {}
-
- connection_ptr connect(const std::string& u);
-
- // TODO: add a `perpetual` option
- void run() {
- m_io_service.run();
- }
-
- void reset() {
- m_io_service.reset();
- }
-
+
+ connection_ptr connect(const std::string& u);
+
+ // TODO: add a `perpetual` option
+ void run() {
+ m_io_service.run();
+ }
+
+ void reset() {
+ m_io_service.reset();
+ }
+
protected:
- bool is_server() {
- return false;
- }
+ bool is_server() {
+ return false;
+ }
int32_t rand() {
return m_gen();
}
private:
- enum state {
- UNINITIALIZED = 0,
- INITIALIZED = 1,
- CONNECTING = 2,
- CONNECTED = 3
- };
-
- void handle_connect(connection_ptr con,
+ enum state {
+ UNINITIALIZED = 0,
+ INITIALIZED = 1,
+ CONNECTING = 2,
+ CONNECTED = 3
+ };
+
+ void handle_connect(connection_ptr con,
const boost::system::error_code& error);
-
- state m_state;
- endpoint_type& m_endpoint;
- boost::asio::io_service& m_io_service;
- tcp::resolver m_resolver;
+
+ state m_state;
+ endpoint_type& m_endpoint;
+ boost::asio::io_service& m_io_service;
+ tcp::resolver m_resolver;
boost::random::random_device m_rng;
- boost::random::variate_generator<
+ boost::random::variate_generator<
boost::random::random_device&,
boost::random::uniform_int_distribution<>
> m_gen;
@@ -296,17 +296,17 @@ void client::handle_connect(connection_ptr con,
con->start();
} else {
if (error == boost::system::errc::connection_refused) {
- m_endpoint.elog().at(log::elevel::ERROR)
- << "An error occurred while establishing a connection: "
- << error << " (connection refused)" << log::endl;
- } else if (error == boost::system::errc::operation_canceled) {
- m_endpoint.elog().at(log::elevel::ERROR)
- << "An error occurred while establishing a connection: "
- << error << " (operation canceled)" << log::endl;
- } else if (error == boost::system::errc::connection_reset) {
- m_endpoint.elog().at(log::elevel::ERROR)
- << "An error occurred while establishing a connection: "
- << error << " (connection reset)" << log::endl;
+ m_endpoint.elog().at(log::elevel::ERROR)
+ << "An error occurred while establishing a connection: "
+ << error << " (connection refused)" << log::endl;
+ } else if (error == boost::system::errc::operation_canceled) {
+ m_endpoint.elog().at(log::elevel::ERROR)
+ << "An error occurred while establishing a connection: "
+ << error << " (operation canceled)" << log::endl;
+ } else if (error == boost::system::errc::connection_reset) {
+ m_endpoint.elog().at(log::elevel::ERROR)
+ << "An error occurred while establishing a connection: "
+ << error << " (connection reset)" << log::endl;
if (con->retry()) {
m_endpoint.elog().at(log::elevel::ERROR)
@@ -314,20 +314,20 @@ void client::handle_connect(connection_ptr con,
connect(con->get_uri());
m_endpoint.remove_connection(con);
}
- } else if (error == boost::system::errc::timed_out) {
- m_endpoint.elog().at(log::elevel::ERROR)
- << "An error occurred while establishing a connection: "
- << error << " (operation timed out)" << log::endl;
- } else if (error == boost::system::errc::broken_pipe) {
- m_endpoint.elog().at(log::elevel::ERROR)
- << "An error occurred while establishing a connection: "
- << error << " (broken pipe)" << log::endl;
- } else {
- m_endpoint.elog().at(log::elevel::ERROR)
- << "An error occurred while establishing a connection: "
- << error << " (unknown)" << log::endl;
- throw "client error";
- }
+ } else if (error == boost::system::errc::timed_out) {
+ m_endpoint.elog().at(log::elevel::ERROR)
+ << "An error occurred while establishing a connection: "
+ << error << " (operation timed out)" << log::endl;
+ } else if (error == boost::system::errc::broken_pipe) {
+ m_endpoint.elog().at(log::elevel::ERROR)
+ << "An error occurred while establishing a connection: "
+ << error << " (broken pipe)" << log::endl;
+ } else {
+ m_endpoint.elog().at(log::elevel::ERROR)
+ << "An error occurred while establishing a connection: "
+ << error << " (unknown)" << log::endl;
+ throw "client error";
+ }
}
}
@@ -349,15 +349,15 @@ void client::connection::write_request() {
m_request.replace_header("Host",m_uri->get_host_port());
if (m_origin != "") {
- m_request.replace_header("Origin",m_origin);
- }
+ m_request.replace_header("Origin",m_origin);
+ }
// Generate client key
int32_t raw_key[4];
for (int i = 0; i < 4; i++) {
- raw_key[i] = this->rand();
- }
+ raw_key[i] = this->rand();
+ }
m_handshake_key = base64_encode(reinterpret_cast(raw_key), 16);
@@ -386,8 +386,8 @@ void client::connection::handle_write_request(
{
if (error) {
-
- m_endpoint.elog().at(log::elevel::ERROR) << "Error writing WebSocket request. code: " << error << log::endl;
+
+ m_endpoint.elog().at(log::elevel::ERROR) << "Error writing WebSocket request. code: " << error << log::endl;
m_connection.terminate(false);
return;
@@ -462,33 +462,33 @@ void client::connection::handle_read_response (
m_response.get_status_msg());
} else {
std::string server_key = m_handshake_key;
- server_key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+ server_key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
- SHA1 sha;
- uint32_t message_digest[5];
-
- sha.Reset();
- sha << server_key.c_str();
+ SHA1 sha;
+ uint32_t message_digest[5];
+
+ sha.Reset();
+ sha << server_key.c_str();
if (!sha.Result(message_digest)) {
- m_endpoint.elog().at(log::elevel::ERROR) << "Error computing handshake sha1 hash." << log::endl;
- // TODO: close behavior
- return;
- }
+ m_endpoint.elog().at(log::elevel::ERROR) << "Error computing handshake sha1 hash." << log::endl;
+ // TODO: close behavior
+ return;
+ }
// convert sha1 hash bytes to network byte order because this sha1
- // library works on ints rather than bytes
- for (int i = 0; i < 5; i++) {
- message_digest[i] = htonl(message_digest[i]);
- }
+ // library works on ints rather than bytes
+ for (int i = 0; i < 5; i++) {
+ message_digest[i] = htonl(message_digest[i]);
+ }
server_key = base64_encode(
reinterpret_cast(message_digest),20);
if (server_key != h) {
- m_endpoint.elog().at(log::elevel::ERROR) << "Server returned incorrect handshake key." << log::endl;
- // TODO: close behavior
- return;
- }
+ m_endpoint.elog().at(log::elevel::ERROR) << "Server returned incorrect handshake key." << log::endl;
+ // TODO: close behavior
+ return;
+ }
}
log_open_result();
@@ -513,17 +513,17 @@ void client::connection::handle_read_response (
template
template
void client::connection::log_open_result() {
- /*std::stringstream version;
- version << "v" << m_version << " ";
-
- m_endpoint.alog().at(log::alevel::CONNECT) << (m_version == -1 ? "HTTP" : "WebSocket") << " Connection "
- << m_connection.get_raw_socket().remote_endpoint() << " "
- << (m_version == -1 ? "" : version.str())
- << (get_request_header("User-Agent") == "" ? "NULL" : get_request_header("User-Agent"))
- << " " << m_uri->get_resource() << " " << m_response.get_status_code()
- << log::endl;*/
+ /*std::stringstream version;
+ version << "v" << m_version << " ";
+
+ m_endpoint.alog().at(log::alevel::CONNECT) << (m_version == -1 ? "HTTP" : "WebSocket") << " Connection "
+ << m_connection.get_raw_socket().remote_endpoint() << " "
+ << (m_version == -1 ? "" : version.str())
+ << (get_request_header("User-Agent") == "" ? "NULL" : get_request_header("User-Agent"))
+ << " " << m_uri->get_resource() << " " << m_response.get_status_code()
+ << log::endl;*/
}
-
+
} // namespace role
} // namespace websocketpp
diff --git a/src/roles/server.hpp b/src/roles/server.hpp
index 866424dfce..0c0f431ad0 100644
--- a/src/roles/server.hpp
+++ b/src/roles/server.hpp
@@ -51,158 +51,158 @@ namespace role {
template
class server {
public:
- // Connection specific details
- template
- class connection {
- public:
- typedef connection type;
- typedef endpoint endpoint_type;
-
- // Valid always
+ // Connection specific details
+ template
+ class connection {
+ public:
+ typedef connection type;
+ typedef endpoint endpoint_type;
+
+ // Valid always
int get_version() const {
- return m_version;
- }
- std::string get_request_header(const std::string& key) const {
- return m_request.header(key);
- }
- std::string get_origin() const {
- return m_origin;
- }
-
- // Information about the requested URI
- // valid only after URIs are loaded
- // TODO: check m_uri for NULLness
- bool get_secure() const {
- return m_uri->get_secure();
- }
- std::string get_host() const {
- return m_uri->get_host();
- }
- std::string get_resource() const {
- return m_uri->get_resource();
- }
- uint16_t get_port() const {
- return m_uri->get_port();
- }
-
- // Valid for CONNECTING state
- void add_response_header(const std::string& key, const std::string& value) {
- m_response.add_header(key,value);
- }
- void replace_response_header(const std::string& key, const std::string& value) {
- m_response.replace_header(key,value);
- }
- void remove_response_header(const std::string& key) {
- m_response.remove_header(key);
- }
-
- const std::vector& get_subprotocols() const {
- return m_requested_subprotocols;
- }
- const std::vector& get_extensions() const {
- return m_requested_extensions;
- }
- void select_subprotocol(const std::string& value);
- void select_extension(const std::string& value);
-
- // Valid if get_version() returns -1 (ie this is an http connection)
- void set_body(const std::string& value);
-
- int32_t rand() {
+ return m_version;
+ }
+ std::string get_request_header(const std::string& key) const {
+ return m_request.header(key);
+ }
+ std::string get_origin() const {
+ return m_origin;
+ }
+
+ // Information about the requested URI
+ // valid only after URIs are loaded
+ // TODO: check m_uri for NULLness
+ bool get_secure() const {
+ return m_uri->get_secure();
+ }
+ std::string get_host() const {
+ return m_uri->get_host();
+ }
+ std::string get_resource() const {
+ return m_uri->get_resource();
+ }
+ uint16_t get_port() const {
+ return m_uri->get_port();
+ }
+
+ // Valid for CONNECTING state
+ void add_response_header(const std::string& key, const std::string& value) {
+ m_response.add_header(key,value);
+ }
+ void replace_response_header(const std::string& key, const std::string& value) {
+ m_response.replace_header(key,value);
+ }
+ void remove_response_header(const std::string& key) {
+ m_response.remove_header(key);
+ }
+
+ const std::vector& get_subprotocols() const {
+ return m_requested_subprotocols;
+ }
+ const std::vector& get_extensions() const {
+ return m_requested_extensions;
+ }
+ void select_subprotocol(const std::string& value);
+ void select_extension(const std::string& value);
+
+ // Valid if get_version() returns -1 (ie this is an http connection)
+ void set_body(const std::string& value);
+
+ int32_t rand() {
return 0;
}
-
+
bool is_server() const {
return true;
}
- // should this exist?
- boost::asio::io_service& get_io_service() {
- return m_endpoint.get_io_service();
- }
- protected:
- connection(endpoint& e)
+ // should this exist?
+ boost::asio::io_service& get_io_service() {
+ return m_endpoint.get_io_service();
+ }
+ protected:
+ connection(endpoint& e)
: m_endpoint(e),
m_connection(static_cast< connection_type& >(*this)),
m_version(-1),
m_uri() {}
-
- // initializes the websocket connection
- void async_init();
- void handle_read_request(const boost::system::error_code& error,
- std::size_t bytes_transferred);
- void write_response();
- void handle_write_response(const boost::system::error_code& error);
-
- void log_open_result();
- private:
- endpoint& m_endpoint;
- connection_type& m_connection;
-
- int m_version;
- uri_ptr m_uri;
- std::string m_origin;
- std::vector m_requested_subprotocols;
- std::vector m_requested_extensions;
- std::string m_subprotocol;
- std::vector m_extensions;
-
- http::parser::request m_request;
- http::parser::response m_response;
- blank_rng m_rng;
- };
-
- // types
- typedef server type;
- typedef endpoint endpoint_type;
-
- typedef typename endpoint_traits::connection_ptr connection_ptr;
- typedef typename endpoint_traits::handler_ptr handler_ptr;
+
+ // initializes the websocket connection
+ void async_init();
+ void handle_read_request(const boost::system::error_code& error,
+ std::size_t bytes_transferred);
+ void write_response();
+ void handle_write_response(const boost::system::error_code& error);
+
+ void log_open_result();
+ private:
+ endpoint& m_endpoint;
+ connection_type& m_connection;
+
+ int m_version;
+ uri_ptr m_uri;
+ std::string m_origin;
+ std::vector m_requested_subprotocols;
+ std::vector m_requested_extensions;
+ std::string m_subprotocol;
+ std::vector m_extensions;
+
+ http::parser::request m_request;
+ http::parser::response m_response;
+ blank_rng m_rng;
+ };
- // handler interface callback base class
+ // types
+ typedef server type;
+ typedef endpoint endpoint_type;
+
+ typedef typename endpoint_traits::connection_ptr connection_ptr;
+ typedef typename endpoint_traits::handler_ptr handler_ptr;
+
+ // handler interface callback base class
class handler_interface {
- public:
- virtual void validate(connection_ptr connection) {}
- virtual void on_open(connection_ptr connection) {}
- virtual void on_close(connection_ptr connection) {}
- virtual void on_fail(connection_ptr connection) {}
-
- virtual void on_message(connection_ptr connection,message::data_ptr) {};
-
- virtual bool on_ping(connection_ptr connection,std::string) {return true;}
- virtual void on_pong(connection_ptr connection,std::string) {}
- virtual void http(connection_ptr connection) {}
- };
-
- server(boost::asio::io_service& m)
- : m_ws_endpoint(static_cast< endpoint_type& >(*this)),
- m_io_service(m),
+ public:
+ virtual void validate(connection_ptr connection) {}
+ virtual void on_open(connection_ptr connection) {}
+ virtual void on_close(connection_ptr connection) {}
+ virtual void on_fail(connection_ptr connection) {}
+
+ virtual void on_message(connection_ptr connection,message::data_ptr) {};
+
+ virtual bool on_ping(connection_ptr connection,std::string) {return true;}
+ virtual void on_pong(connection_ptr connection,std::string) {}
+ virtual void http(connection_ptr connection) {}
+ };
+
+ server(boost::asio::io_service& m)
+ : m_ws_endpoint(static_cast< endpoint_type& >(*this)),
+ m_io_service(m),
// the only way to set an endpoint address family appears to be using
// this constructor, which also requires a port. This port number can be
// ignored, as it is always overwriten later by the listen() member func
- m_endpoint(boost::asio::ip::tcp::v6(),9000),
- m_acceptor(m),
+ m_endpoint(boost::asio::ip::tcp::v6(),9000),
+ m_acceptor(m),
m_timer(m,boost::posix_time::seconds(0)) {}
-
+
void listen(uint16_t port);
protected:
- bool is_server() {
- return true;
- }
+ bool is_server() {
+ return true;
+ }
private:
- // start_accept creates a new connection and begins an async_accept on it
- void start_accept();
-
- // handle_accept will begin the connection's read/write loop and then reset
- // the server to accept a new connection. Errors returned by async_accept
- // are logged and ingored.
- void handle_accept(connection_ptr con,
+ // start_accept creates a new connection and begins an async_accept on it
+ void start_accept();
+
+ // handle_accept will begin the connection's read/write loop and then reset
+ // the server to accept a new connection. Errors returned by async_accept
+ // are logged and ingored.
+ void handle_accept(connection_ptr con,
const boost::system::error_code& error);
-
- endpoint_type& m_ws_endpoint;
- boost::asio::io_service& m_io_service;
- boost::asio::ip::tcp::endpoint m_endpoint;
- boost::asio::ip::tcp::acceptor m_acceptor;
+
+ endpoint_type& m_ws_endpoint;
+ boost::asio::io_service& m_io_service;
+ boost::asio::ip::tcp::endpoint m_endpoint;
+ boost::asio::ip::tcp::acceptor m_acceptor;
boost::asio::deadline_timer m_timer;
};
@@ -246,18 +246,18 @@ void server::handle_accept(connection_ptr con,
const boost::system::error_code& error)
{
if (error) {
- if (error == boost::system::errc::too_many_files_open) {
- m_ws_endpoint.elog().at(log::elevel::ERROR)
- << "async_accept returned error: " << error
- << " (too many files open)" << log::endl;
+ if (error == boost::system::errc::too_many_files_open) {
+ m_ws_endpoint.elog().at(log::elevel::ERROR)
+ << "async_accept returned error: " << error
+ << " (too many files open)" << log::endl;
m_timer.expires_from_now(boost::posix_time::milliseconds(1000));
m_timer.async_wait(boost::bind(&type::start_accept,this));
return;
- } else {
- m_ws_endpoint.elog().at(log::elevel::ERROR)
- << "async_accept returned error: " << error
- << " (unknown)" << log::endl;
- }
+ } else {
+ m_ws_endpoint.elog().at(log::elevel::ERROR)
+ << "async_accept returned error: " << error
+ << " (unknown)" << log::endl;
+ }
} else {
con->start();
}
@@ -533,19 +533,19 @@ void server::connection::log_open_result() {
std::stringstream version;
version << "v" << m_version << " ";
- std::string remote;
- boost::system::error_code ec;
- boost::asio::ip::tcp::endpoint ep = m_connection.get_raw_socket().remote_endpoint(ec);
- if (ec) {
- // An error occurred.
- //remote = "Unknown";
- //ignore?
- m_endpoint.elog().at(log::elevel::WARN) << "Error getting remote endpoint. code: " << ec << log::endl;
- } else {
-
- }
-
-
+ std::string remote;
+ boost::system::error_code ec;
+ boost::asio::ip::tcp::endpoint ep = m_connection.get_raw_socket().remote_endpoint(ec);
+ if (ec) {
+ // An error occurred.
+ //remote = "Unknown";
+ //ignore?
+ m_endpoint.elog().at(log::elevel::WARN) << "Error getting remote endpoint. code: " << ec << log::endl;
+ } else {
+
+ }
+
+
m_endpoint.alog().at(log::alevel::CONNECT) << (m_version == -1 ? "HTTP" : "WebSocket") << " Connection "
<< ep << " "
<< (m_version == -1 ? "" : version.str())
@@ -554,7 +554,7 @@ void server::connection::log_open_result() {
<< log::endl;
}
-} // namespace role
+} // namespace role
} // namespace websocketpp
#endif // WEBSOCKETPP_ROLE_SERVER_HPP
diff --git a/src/sockets/plain.hpp b/src/sockets/plain.hpp
index e6dbcf82c8..875a681edb 100644
--- a/src/sockets/plain.hpp
+++ b/src/sockets/plain.hpp
@@ -41,67 +41,67 @@ namespace socket {
template
class plain {
public:
- boost::asio::io_service& get_io_service() {
- return m_io_service;
- }
-
- bool is_secure() {
- return false;
- }
-
- // plain sockets do not add anything to the handler interface
- class handler_interface {};
-
- // Connection specific details
- template
- class connection {
- public:
- // should these two be public or protected. If protected, how?
- boost::asio::ip::tcp::socket& get_raw_socket() {
- return m_socket;
- }
-
- boost::asio::ip::tcp::socket& get_socket() {
- return m_socket;
- }
-
- bool is_secure() {
- return false;
- }
- protected:
- connection(plain& e) : m_socket(e.get_io_service()) {}
-
- void init() {
-
- }
-
- void async_init(socket_init_callback callback) {
- // TODO: should this use post()?
- //m_socket.set_option(boost::asio::ip::tcp::no_delay(true));
-
- callback(boost::system::error_code());
- }
-
- bool shutdown() {
- boost::system::error_code ignored_ec;
- m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both,ignored_ec);
-
- if (ignored_ec) {
- return false;
- } else {
- return true;
- }
- }
- private:
- boost::asio::ip::tcp::socket m_socket;
- };
+ boost::asio::io_service& get_io_service() {
+ return m_io_service;
+ }
+
+ bool is_secure() {
+ return false;
+ }
+
+ // plain sockets do not add anything to the handler interface
+ class handler_interface {};
+
+ // Connection specific details
+ template
+ class connection {
+ public:
+ // should these two be public or protected. If protected, how?
+ boost::asio::ip::tcp::socket& get_raw_socket() {
+ return m_socket;
+ }
+
+ boost::asio::ip::tcp::socket& get_socket() {
+ return m_socket;
+ }
+
+ bool is_secure() {
+ return false;
+ }
+ protected:
+ connection(plain& e) : m_socket(e.get_io_service()) {}
+
+ void init() {
+
+ }
+
+ void async_init(socket_init_callback callback) {
+ // TODO: should this use post()?
+ //m_socket.set_option(boost::asio::ip::tcp::no_delay(true));
+
+ callback(boost::system::error_code());
+ }
+
+ bool shutdown() {
+ boost::system::error_code ignored_ec;
+ m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both,ignored_ec);
+
+ if (ignored_ec) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ private:
+ boost::asio::ip::tcp::socket m_socket;
+ };
protected:
- plain (boost::asio::io_service& m) : m_io_service(m) {}
+ plain (boost::asio::io_service& m) : m_io_service(m) {}
private:
- boost::asio::io_service& m_io_service;
+ boost::asio::io_service& m_io_service;
};
-
+
} // namespace socket
} // namespace websocketpp
diff --git a/src/sockets/ssl.hpp b/src/sockets/ssl.hpp
index 78ee78aa62..16c4fb342f 100644
--- a/src/sockets/ssl.hpp
+++ b/src/sockets/ssl.hpp
@@ -42,115 +42,115 @@ namespace socket {
template
class ssl {
public:
- typedef ssl type;
- typedef boost::asio::ssl::stream ssl_socket;
- typedef boost::shared_ptr ssl_socket_ptr;
-
- // should be private friended
- boost::asio::io_service& get_io_service() {
- return m_io_service;
- }
-
- // should be private friended?
- ssl_socket::handshake_type get_handshake_type() {
- if (static_cast< endpoint_type* >(this)->is_server()) {
- return boost::asio::ssl::stream_base::server;
- } else {
- return boost::asio::ssl::stream_base::client;
- }
- }
-
- bool is_secure() {
- return true;
- }
-
- // TLS policy adds the on_tls_init method to the handler to allow the user
- // to set up their asio TLS context.
- class handler_interface {
- public:
- virtual boost::shared_ptr on_tls_init() = 0;
- };
-
- // Connection specific details
- template
- class connection {
- public:
- // should these two be public or protected. If protected, how?
- ssl_socket::lowest_layer_type& get_raw_socket() {
- return m_socket_ptr->lowest_layer();
- }
-
- ssl_socket& get_socket() {
- return *m_socket_ptr;
- }
-
- bool is_secure() {
- return true;
- }
- protected:
- connection(ssl& e)
- : m_endpoint(e),
- m_connection(static_cast< connection_type& >(*this)) {}
-
- void init() {
- m_context_ptr = m_connection.get_handler()->on_tls_init();
-
+ typedef ssl type;
+ typedef boost::asio::ssl::stream ssl_socket;
+ typedef boost::shared_ptr ssl_socket_ptr;
+
+ // should be private friended
+ boost::asio::io_service& get_io_service() {
+ return m_io_service;
+ }
+
+ // should be private friended?
+ ssl_socket::handshake_type get_handshake_type() {
+ if (static_cast< endpoint_type* >(this)->is_server()) {
+ return boost::asio::ssl::stream_base::server;
+ } else {
+ return boost::asio::ssl::stream_base::client;
+ }
+ }
+
+ bool is_secure() {
+ return true;
+ }
+
+ // TLS policy adds the on_tls_init method to the handler to allow the user
+ // to set up their asio TLS context.
+ class handler_interface {
+ public:
+ virtual boost::shared_ptr on_tls_init() = 0;
+ };
+
+ // Connection specific details
+ template
+ class connection {
+ public:
+ // should these two be public or protected. If protected, how?
+ ssl_socket::lowest_layer_type& get_raw_socket() {
+ return m_socket_ptr->lowest_layer();
+ }
+
+ ssl_socket& get_socket() {
+ return *m_socket_ptr;
+ }
+
+ bool is_secure() {
+ return true;
+ }
+ protected:
+ connection(ssl& e)
+ : m_endpoint(e),
+ m_connection(static_cast< connection_type& >(*this)) {}
+
+ void init() {
+ m_context_ptr = m_connection.get_handler()->on_tls_init();
+
if (!m_context_ptr) {
throw "handler was unable to init tls, connection error";
}
m_socket_ptr = ssl_socket_ptr(new ssl_socket(m_endpoint.get_io_service(),*m_context_ptr));
- }
-
- void async_init(boost::function callback)
- {
- m_socket_ptr->async_handshake(
- m_endpoint.get_handshake_type(),
- boost::bind(
- &connection::handle_init,
- this,
- callback,
- boost::asio::placeholders::error
- )
- );
- }
-
- void handle_init(socket_init_callback callback,const boost::system::error_code& error) {
- /*if (error) {
- std::cout << "SSL handshake error" << std::endl;
- } else {
- //static_cast< connection_type* >(this)->websocket_handshake();
-
- }*/
- callback(error);
- }
-
+ }
+
+ void async_init(boost::function callback)
+ {
+ m_socket_ptr->async_handshake(
+ m_endpoint.get_handshake_type(),
+ boost::bind(
+ &connection::handle_init,
+ this,
+ callback,
+ boost::asio::placeholders::error
+ )
+ );
+ }
+
+ void handle_init(socket_init_callback callback,const boost::system::error_code& error) {
+ /*if (error) {
+ std::cout << "SSL handshake error" << std::endl;
+ } else {
+ //static_cast< connection_type* >(this)->websocket_handshake();
+
+ }*/
+ callback(error);
+ }
+
// note, this function for some reason shouldn't/doesn't need to be
// called for plain HTTP connections. not sure why.
- bool shutdown() {
- boost::system::error_code ignored_ec;
-
- m_socket_ptr->shutdown(ignored_ec);
-
- if (ignored_ec) {
- return false;
- } else {
- return true;
- }
- }
- private:
- boost::shared_ptr m_context_ptr;
- ssl_socket_ptr m_socket_ptr;
- ssl& m_endpoint;
- connection_type& m_connection;
- };
+ bool shutdown() {
+ boost::system::error_code ignored_ec;
+
+ m_socket_ptr->shutdown(ignored_ec);
+
+ if (ignored_ec) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ private:
+ boost::shared_ptr m_context_ptr;
+ ssl_socket_ptr m_socket_ptr;
+ ssl