Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c1161f859b | |||
| ae49a83c64 | |||
| 528a91ff7f | |||
| d645ccc36f | |||
| cd2bab2ec5 | |||
| 71300f047b | |||
| e96edc8cc4 | |||
| 1cfa069dab | |||
| 7d60ad5849 | |||
| 3e8195588f | |||
| a6d2c325b1 | |||
| 6c8908f493 | |||
| a10b3a1704 |
+20
@@ -0,0 +1,20 @@
|
|||||||
|
language: cpp
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
before_install:
|
||||||
|
- sudo apt-get install libboost-regex1.48-dev libboost-system1.48-dev libboost-thread1.48-dev libboost-test1.48-dev libboost-random1.48-dev -y
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- BOOST_INCLUDES=/usr/include
|
||||||
|
- BOOST_LIBS=/usr/lib
|
||||||
|
script: scons -j 2 && scons test
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- experimental
|
||||||
|
- 0.3.x-cmake
|
||||||
|
notifications:
|
||||||
|
recipients:
|
||||||
|
- travis@zaphoyd.com
|
||||||
|
email:
|
||||||
|
on_success: change
|
||||||
|
on_failure: always
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
**WARNING: LEGACY VERSION**
|
||||||
|
|
||||||
|
NOTE: This is the 0.2.x version of WebSocket++. There some fairly significant
|
||||||
|
API changes in 0.3.x so upgrading should be done carefully. Due to these
|
||||||
|
changes, a snapshot of the last 0.2.x version will be tagged in the master
|
||||||
|
branch and retained in the 0.2.x branch for any 0.2 user's convenience. The
|
||||||
|
0.2.x branch may be updated if any particularly problematic issues are found.
|
||||||
|
|
||||||
|
The 0.3.x+ line is the preferred code for any new development. 0.3.x can be
|
||||||
|
found in the 'Experimental' branch on GitHub. In the near future it will be
|
||||||
|
promoted to the master branch.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
WebSocket++ is a C++ library that impliments RFC6455, the WebSocket protocol.
|
||||||
|
It can be used to build applications that feature WebSocket functionality.
|
||||||
|
|
||||||
|
For more information, please visit: http://www.zaphoyd.com/websocketpp/
|
||||||
|
|
||||||
|
0.2.x Features:
|
||||||
|
|
||||||
|
* Fully supports RFC6455 protocol
|
||||||
|
* Partial support for Hixie draft 76 and Hybi drafts 7-17
|
||||||
|
* Easy to use message/event based API
|
||||||
|
* Boost ASIO based asynchronous network core
|
||||||
|
* Supports secure WebSockets (TLS) and IPv6
|
||||||
|
* Fully passes the AutoBahn 0.4.10 test suite
|
||||||
|
* Includes WebSocket performance and stress testing tools
|
||||||
|
* Open-source (BSD license)
|
||||||
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
WebSocket++ is a full featured C++/Boost ASIO implimentation of RFC6455, the
|
|
||||||
WebSocket protocol which can be used to build applications that feature
|
|
||||||
WebSocket client and server functionality.
|
|
||||||
|
|
||||||
* Fully supports RFC6455 protocol
|
|
||||||
* Partial support for Hixie draft 76 and Hybi drafts 7-17
|
|
||||||
* Easy to use message/event based API
|
|
||||||
* Boost ASIO based asynchronous network core
|
|
||||||
* Supports secure WebSockets (TLS) and IPv6
|
|
||||||
* Fully passes the AutoBahn 0.4.10 test suite
|
|
||||||
* Includes WebSocket performance and stress testing tools
|
|
||||||
* Open-source (BSD license)
|
|
||||||
|
|
||||||
For more information, please visit: http://www.zaphoyd.com/websocketpp/ or the
|
|
||||||
project's github wiki at: https://github.com/zaphoyd/websocketpp/wiki
|
|
||||||
+6
-1
@@ -53,7 +53,12 @@
|
|||||||
|
|
||||||
// Defaults
|
// Defaults
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
static const std::string USER_AGENT = "WebSocket++/0.2.2dev";
|
union uint64_converter {
|
||||||
|
uint64_t i;
|
||||||
|
uint8_t c[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::string USER_AGENT = "WebSocket++/0.2.3dev";
|
||||||
|
|
||||||
typedef std::vector<unsigned char> binary_string;
|
typedef std::vector<unsigned char> binary_string;
|
||||||
typedef boost::shared_ptr<binary_string> binary_string_ptr;
|
typedef boost::shared_ptr<binary_string> binary_string_ptr;
|
||||||
|
|||||||
@@ -200,6 +200,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void send(const std::string& payload, frame::opcode::value op = frame::opcode::TEXT);
|
void send(const std::string& payload, frame::opcode::value op = frame::opcode::TEXT);
|
||||||
|
// In the future this could be changed to string_ref if it is adopted by
|
||||||
|
// the standard http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3334.html
|
||||||
|
void send(const void *payload, uint64_t length, frame::opcode::value op = frame::opcode::BINARY);
|
||||||
void send(message::data_ptr msg);
|
void send(message::data_ptr msg);
|
||||||
|
|
||||||
/// Close connection
|
/// Close connection
|
||||||
@@ -1573,6 +1576,41 @@ connection<endpoint,role,socket>::send(const std::string& payload,frame::opcode:
|
|||||||
send(msg);
|
send(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// convenience overload for sending a one off message.
|
||||||
|
/**
|
||||||
|
* Creates a message, fills in payload, and queues a write as a message of
|
||||||
|
* type op. Default type is BINARY.
|
||||||
|
*
|
||||||
|
* Visibility: public
|
||||||
|
* State: Valid from OPEN, ignored otherwise
|
||||||
|
* Concurrency: callable from any thread
|
||||||
|
*
|
||||||
|
* @param payload Payload to write_state
|
||||||
|
* @param op opcode to send the message as
|
||||||
|
*/
|
||||||
|
template <typename endpoint,template <class> class role,template <class> class socket>
|
||||||
|
void
|
||||||
|
connection<endpoint,role,socket>::send(const void *payload, uint64_t length, frame::opcode::value op)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::recursive_mutex> lock(m_lock);
|
||||||
|
if (m_state != session::state::OPEN) {return;}
|
||||||
|
}
|
||||||
|
|
||||||
|
websocketpp::message::data::ptr msg = get_control_message2();
|
||||||
|
|
||||||
|
if (!msg) {
|
||||||
|
throw exception("Endpoint send queue is full",error::SEND_QUEUE_FULL);
|
||||||
|
}
|
||||||
|
if (op != frame::opcode::TEXT && op != frame::opcode::BINARY) {
|
||||||
|
throw exception("opcode must be either TEXT or BINARY",error::GENERIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->reset(op);
|
||||||
|
msg->set_payload(payload, length);
|
||||||
|
send(msg);
|
||||||
|
}
|
||||||
|
|
||||||
/// Send message
|
/// Send message
|
||||||
/**
|
/**
|
||||||
* Prepares (if necessary) and sends the given message
|
* Prepares (if necessary) and sends the given message
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "data.hpp"
|
#include "data.hpp"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "../processors/processor.hpp"
|
#include "../processors/processor.hpp"
|
||||||
#include "../processors/hybi_header.hpp"
|
#include "../processors/hybi_header.hpp"
|
||||||
@@ -155,6 +156,15 @@ void data::set_payload(const std::string& payload) {
|
|||||||
m_payload.reserve(payload.size());
|
m_payload.reserve(payload.size());
|
||||||
m_payload = payload;
|
m_payload = payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This could be improved using string_ref if it is ever added to the language.
|
||||||
|
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3334.html
|
||||||
|
void data::set_payload(const void *payload, size_t length) {
|
||||||
|
m_payload.reserve(length);
|
||||||
|
const char* pl = static_cast<const char*>(payload);
|
||||||
|
m_payload.assign(pl, pl + length);
|
||||||
|
}
|
||||||
|
|
||||||
void data::append_payload(const std::string& payload) {
|
void data::append_payload(const std::string& payload) {
|
||||||
m_payload.reserve(m_payload.size()+payload.size());
|
m_payload.reserve(m_payload.size()+payload.size());
|
||||||
m_payload.append(payload);
|
m_payload.append(payload);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <boost/enable_shared_from_this.hpp>
|
#include <boost/enable_shared_from_this.hpp>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/intrusive_ptr.hpp>
|
#include <boost/intrusive_ptr.hpp>
|
||||||
|
#include <boost/thread/locks.hpp>
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
@@ -186,6 +187,9 @@ public:
|
|||||||
// sets the payload to payload. Performs max size and UTF8 validation
|
// sets the payload to payload. Performs max size and UTF8 validation
|
||||||
// immediately and throws processor::exception if it fails
|
// immediately and throws processor::exception if it fails
|
||||||
void set_payload(const std::string& payload);
|
void set_payload(const std::string& payload);
|
||||||
|
// This could be improved using string_ref if it is ever added to the language.
|
||||||
|
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3334.html
|
||||||
|
void set_payload(const void *payload, size_t length);
|
||||||
void append_payload(const std::string& payload);
|
void append_payload(const std::string& payload);
|
||||||
|
|
||||||
void set_header(const std::string& header);
|
void set_header(const std::string& header);
|
||||||
|
|||||||
@@ -144,7 +144,10 @@ void hybi_header::set_payload_size(uint64_t size) {
|
|||||||
m_header[1] |= BASIC_PAYLOAD_64BIT_CODE;
|
m_header[1] |= BASIC_PAYLOAD_64BIT_CODE;
|
||||||
}
|
}
|
||||||
m_payload_size = size;
|
m_payload_size = size;
|
||||||
*(reinterpret_cast<uint64_t*>(&m_header[BASIC_HEADER_LENGTH])) = zsutil::htonll(size);
|
|
||||||
|
uint64_converter temp64;
|
||||||
|
temp64.i = zsutil::htonll(size);
|
||||||
|
std::copy(temp64.c,temp64.c+8,m_header+BASIC_HEADER_LENGTH);
|
||||||
} else {
|
} else {
|
||||||
throw processor::exception("set_payload_size called with value that was too large (>2^63)",processor::error::MESSAGE_TOO_BIG);
|
throw processor::exception("set_payload_size called with value that was too large (>2^63)",processor::error::MESSAGE_TOO_BIG);
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-11
@@ -71,7 +71,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
template <class rng_policy>
|
template <class rng_policy>
|
||||||
class parser : boost::noncopyable {
|
class parser : boost::noncopyable {
|
||||||
public:
|
public:
|
||||||
@@ -395,10 +396,13 @@ public:
|
|||||||
// this reinterprets the second pair of bytes in m_header as a
|
// this reinterprets the second pair of bytes in m_header as a
|
||||||
// 16 bit int and writes the payload size there as an integer
|
// 16 bit int and writes the payload size there as an integer
|
||||||
// in network byte order
|
// in network byte order
|
||||||
*reinterpret_cast<uint16_t*>(&m_header[BASIC_HEADER_LENGTH]) = htons(s);
|
uint16_t value = htons(s);
|
||||||
|
memcpy(&m_header[BASIC_HEADER_LENGTH], &value, sizeof(uint16_t));
|
||||||
} else if (s <= limits::PAYLOAD_SIZE_JUMBO) {
|
} else if (s <= limits::PAYLOAD_SIZE_JUMBO) {
|
||||||
m_header[1] = BASIC_PAYLOAD_64BIT_CODE;
|
m_header[1] = BASIC_PAYLOAD_64BIT_CODE;
|
||||||
*reinterpret_cast<uint64_t*>(&m_header[BASIC_HEADER_LENGTH]) = zsutil::htonll(s);
|
uint64_converter temp64;
|
||||||
|
temp64.i = zsutil::htonll(s);
|
||||||
|
std::copy(temp64.c,temp64.c+8,m_header+BASIC_HEADER_LENGTH);
|
||||||
} else {
|
} else {
|
||||||
throw processor::exception("payload size limit is 63 bits",processor::error::PROTOCOL_VIOLATION);
|
throw processor::exception("payload size limit is 63 bits",processor::error::PROTOCOL_VIOLATION);
|
||||||
}
|
}
|
||||||
@@ -484,9 +488,9 @@ public:
|
|||||||
} else if (s == BASIC_PAYLOAD_16BIT_CODE) {
|
} else if (s == BASIC_PAYLOAD_16BIT_CODE) {
|
||||||
// reinterpret the second two bytes as a 16 bit integer in network
|
// reinterpret the second two bytes as a 16 bit integer in network
|
||||||
// byte order. Convert to host byte order and store locally.
|
// byte order. Convert to host byte order and store locally.
|
||||||
payload_size = ntohs(*(
|
uint16_t value;
|
||||||
reinterpret_cast<uint16_t*>(&m_header[BASIC_HEADER_LENGTH])
|
memcpy(&value, &m_header[BASIC_HEADER_LENGTH], sizeof(uint16_t));
|
||||||
));
|
payload_size = ntohs(value);
|
||||||
|
|
||||||
if (payload_size < s) {
|
if (payload_size < s) {
|
||||||
std::stringstream err;
|
std::stringstream err;
|
||||||
@@ -497,11 +501,10 @@ public:
|
|||||||
|
|
||||||
mask_index += 2;
|
mask_index += 2;
|
||||||
} else if (s == BASIC_PAYLOAD_64BIT_CODE) {
|
} else if (s == BASIC_PAYLOAD_64BIT_CODE) {
|
||||||
// reinterpret the second eight bytes as a 64 bit integer in
|
// reinterpret the second eight bytes as a 64 bit integer in
|
||||||
// network byte order. Convert to host byte order and store.
|
// network byte order. Convert to host byte order and store.
|
||||||
payload_size = zsutil::ntohll(*(
|
memcpy(&payload_size, &m_header[BASIC_HEADER_LENGTH], sizeof(uint64_t));
|
||||||
reinterpret_cast<uint64_t*>(&m_header[BASIC_HEADER_LENGTH])
|
payload_size = zsutil::ntohll(payload_size);
|
||||||
));
|
|
||||||
|
|
||||||
if (payload_size <= limits::PAYLOAD_SIZE_EXTENDED) {
|
if (payload_size <= limits::PAYLOAD_SIZE_EXTENDED) {
|
||||||
m_bytes_needed = payload_size;
|
m_bytes_needed = payload_size;
|
||||||
@@ -608,7 +611,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void generate_masking_key() {
|
void generate_masking_key() {
|
||||||
*(reinterpret_cast<int32_t *>(&m_header[get_header_len()-4])) = m_rng.rand();
|
int32_t value = m_rng.rand();
|
||||||
|
memcpy(&m_header[get_header_len()-4], &value, sizeof(int32_t));
|
||||||
}
|
}
|
||||||
void clear_masking_key() {
|
void clear_masking_key() {
|
||||||
// this is a no-op as clearing the mask bit also changes the get_header_len
|
// this is a no-op as clearing the mask bit also changes the get_header_len
|
||||||
|
|||||||
Reference in New Issue
Block a user