mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
remove unneeded code and trailing whitespace
This commit is contained in:
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBSOCKETPP_PROCESSOR_HYBI13_HPP
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
typedef typename config::request_type request_type;
|
||||
typedef typename config::response_type response_type;
|
||||
|
||||
|
||||
typedef typename config::message_type message_type;
|
||||
typedef typename message_type::ptr message_ptr;
|
||||
|
||||
@@ -64,22 +64,22 @@ public:
|
||||
typedef typename config::rng_type rng_type;
|
||||
|
||||
typedef typename config::permessage_deflate_type permessage_deflate_type;
|
||||
|
||||
|
||||
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
||||
|
||||
explicit hybi13(bool secure, bool server, msg_manager_ptr manager,
|
||||
rng_type& rng)
|
||||
explicit hybi13(bool secure, bool server, msg_manager_ptr manager,
|
||||
rng_type& rng)
|
||||
: processor<config>(secure,server)
|
||||
, m_msg_manager(manager)
|
||||
, m_rng(rng)
|
||||
{
|
||||
reset_headers();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int get_version() const {
|
||||
return 13;
|
||||
}
|
||||
|
||||
|
||||
bool has_permessage_deflate() const {
|
||||
return m_permessage_deflate.is_implemented();
|
||||
}
|
||||
@@ -93,35 +93,35 @@ public:
|
||||
ret.first = make_error_code(error::extensions_disabled);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
http::parameter_list p;
|
||||
|
||||
bool error = req.get_header_as_plist("Sec-WebSocket-Extensions",p);
|
||||
|
||||
|
||||
if (error) {
|
||||
ret.first = make_error_code(error::extension_parse_error);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// If there are no extensions parsed then we are done!
|
||||
if (p.size() == 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
http::parameter_list::const_iterator it;
|
||||
|
||||
|
||||
if (m_permessage_deflate.is_implemented()) {
|
||||
err_str_pair neg_ret;
|
||||
for (it = p.begin(); it != p.end(); ++it) {
|
||||
// look through each extension, if the key is permessage-deflate
|
||||
if (it->first == "permessage-deflate") {
|
||||
neg_ret = m_permessage_deflate.negotiate(it->second);
|
||||
|
||||
|
||||
if (neg_ret.first) {
|
||||
// Figure out if this is an error that should halt all
|
||||
// extension negotiations or simply cause negotiation of
|
||||
// this specific extension to fail.
|
||||
std::cout << "permessage-compress negotiation failed: "
|
||||
std::cout << "permessage-compress negotiation failed: "
|
||||
<< neg_ret.first.message() << std::endl;
|
||||
} else {
|
||||
// Note: this list will need commas if WebSocket++ ever
|
||||
@@ -140,11 +140,11 @@ public:
|
||||
if (r.get_method() != "GET") {
|
||||
return make_error_code(error::invalid_http_method);
|
||||
}
|
||||
|
||||
|
||||
if (r.get_version() != "HTTP/1.1") {
|
||||
return make_error_code(error::invalid_http_version);
|
||||
}
|
||||
|
||||
|
||||
// required headers
|
||||
// Host is required by HTTP/1.1
|
||||
// Connection is required by is_websocket_handshake
|
||||
@@ -152,11 +152,11 @@ public:
|
||||
if (r.get_header("Sec-WebSocket-Key") == "") {
|
||||
return make_error_code(error::missing_required_header);
|
||||
}
|
||||
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
/* TODO: the 'subprotocol' parameter may need to be expanded into a more
|
||||
|
||||
/* TODO: the 'subprotocol' parameter may need to be expanded into a more
|
||||
* generic struct if other user input parameters to the processed handshake
|
||||
* are found.
|
||||
*/
|
||||
@@ -164,36 +164,36 @@ public:
|
||||
std::string & subprotocol, response_type& response) const
|
||||
{
|
||||
std::string server_key = request.get_header("Sec-WebSocket-Key");
|
||||
|
||||
|
||||
lib::error_code ec = process_handshake_key(server_key);
|
||||
|
||||
|
||||
if (ec) {
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
||||
response.replace_header("Sec-WebSocket-Accept",server_key);
|
||||
response.append_header("Upgrade",constants::upgrade_token);
|
||||
response.append_header("Connection",constants::connection_token);
|
||||
|
||||
|
||||
if (!subprotocol.empty()) {
|
||||
response.replace_header("Sec-WebSocket-Protocol",subprotocol);
|
||||
}
|
||||
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
lib::error_code client_handshake_request(request_type& req, uri_ptr
|
||||
|
||||
lib::error_code client_handshake_request(request_type& req, uri_ptr
|
||||
uri, std::vector<std::string> const & subprotocols) const
|
||||
{
|
||||
req.set_method("GET");
|
||||
req.set_uri(uri->get_resource());
|
||||
req.set_version("HTTP/1.1");
|
||||
|
||||
|
||||
req.append_header("Upgrade","websocket");
|
||||
req.append_header("Connection","Upgrade");
|
||||
req.replace_header("Sec-WebSocket-Version","13");
|
||||
req.replace_header("Host",uri->get_host_port());
|
||||
|
||||
|
||||
if (!subprotocols.empty()) {
|
||||
std::ostringstream result;
|
||||
std::vector<std::string>::const_iterator it = subprotocols.begin();
|
||||
@@ -201,24 +201,24 @@ public:
|
||||
while (it != subprotocols.end()) {
|
||||
result << ", " << *it++;
|
||||
}
|
||||
|
||||
|
||||
req.replace_header("Sec-WebSocket-Protocol",result.str());
|
||||
}
|
||||
|
||||
|
||||
// Generate handshake key
|
||||
frame::uint32_converter conv;
|
||||
unsigned char raw_key[16];
|
||||
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
conv.i = m_rng();
|
||||
std::copy(conv.c,conv.c+4,&raw_key[i*4]);
|
||||
}
|
||||
|
||||
|
||||
req.replace_header("Sec-WebSocket-Key",base64_encode(raw_key, 16));
|
||||
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
|
||||
lib::error_code validate_server_handshake_response(request_type const & req,
|
||||
response_type& res) const
|
||||
{
|
||||
@@ -226,7 +226,7 @@ public:
|
||||
if (res.get_status_code() != http::status_code::switching_protocols) {
|
||||
return error::make_error_code(error::invalid_http_status);
|
||||
}
|
||||
|
||||
|
||||
// And the upgrade token in an upgrade header
|
||||
std::string const & upgrade_header = res.get_header("Upgrade");
|
||||
if (utility::ci_find_substr(upgrade_header, constants::upgrade_token,
|
||||
@@ -234,7 +234,7 @@ public:
|
||||
{
|
||||
return error::make_error_code(error::missing_required_header);
|
||||
}
|
||||
|
||||
|
||||
// And the websocket token in the connection header
|
||||
std::string const & con_header = res.get_header("Connection");
|
||||
if (utility::ci_find_substr(con_header, constants::connection_token,
|
||||
@@ -242,32 +242,32 @@ public:
|
||||
{
|
||||
return error::make_error_code(error::missing_required_header);
|
||||
}
|
||||
|
||||
|
||||
// And has a valid Sec-WebSocket-Accept value
|
||||
std::string key = req.get_header("Sec-WebSocket-Key");
|
||||
lib::error_code ec = process_handshake_key(key);
|
||||
|
||||
|
||||
if (ec || key != res.get_header("Sec-WebSocket-Accept")) {
|
||||
return error::make_error_code(error::missing_required_header);
|
||||
}
|
||||
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
|
||||
std::string get_raw(response_type const & res) const {
|
||||
return res.raw();
|
||||
}
|
||||
|
||||
|
||||
std::string const & get_origin(request_type const & r) const {
|
||||
return r.get_header("Origin");
|
||||
}
|
||||
|
||||
|
||||
lib::error_code extract_subprotocols(request_type const & req,
|
||||
std::vector<std::string> & subprotocol_list)
|
||||
{
|
||||
if (!req.get_header("Sec-WebSocket-Protocol").empty()) {
|
||||
http::parameter_list p;
|
||||
|
||||
|
||||
if (!req.get_header_as_plist("Sec-WebSocket-Protocol",p)) {
|
||||
http::parameter_list::const_iterator it;
|
||||
|
||||
@@ -280,57 +280,57 @@ public:
|
||||
}
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
|
||||
uri_ptr get_uri(request_type const & request) const {
|
||||
return get_uri_from_host(request,(base::m_secure ? "wss" : "ws"));
|
||||
}
|
||||
|
||||
/// Process new websocket connection bytes
|
||||
/**
|
||||
*
|
||||
* Hybi 13 data streams represent a series of variable length frames. Each
|
||||
*
|
||||
* Hybi 13 data streams represent a series of variable length frames. Each
|
||||
* frame is made up of a series of fixed length fields. The lengths of later
|
||||
* fields are contained in earlier fields. The first field length is fixed
|
||||
* by the spec.
|
||||
*
|
||||
* This processor represents a state machine that keeps track of what field
|
||||
* is presently being read and how many more bytes are needed to complete it
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Read two header bytes
|
||||
* Extract full frame length.
|
||||
* Read extra header bytes
|
||||
* Validate frame header (including extension validate)
|
||||
* Read extension data into extension message state object
|
||||
* Read payload data into payload
|
||||
*
|
||||
*
|
||||
* @param buf Input buffer
|
||||
*
|
||||
*
|
||||
* @param len Length of input buffer
|
||||
*
|
||||
*
|
||||
* @return Number of bytes processed or zero on error
|
||||
*/
|
||||
size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) {
|
||||
size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) {
|
||||
size_t p = 0;
|
||||
|
||||
|
||||
ec = lib::error_code();
|
||||
|
||||
//std::cout << "consume: " << utility::to_hex(buf,len) << std::endl;
|
||||
|
||||
// Loop while we don't have a message ready and we still have bytes
|
||||
// left to process.
|
||||
while (m_state != READY && m_state != FATAL_ERROR &&
|
||||
// Loop while we don't have a message ready and we still have bytes
|
||||
// left to process.
|
||||
while (m_state != READY && m_state != FATAL_ERROR &&
|
||||
(p < len || m_bytes_needed == 0))
|
||||
{
|
||||
if (m_state == HEADER_BASIC) {
|
||||
p += this->copy_basic_header_bytes(buf+p,len-p);
|
||||
|
||||
|
||||
if (m_bytes_needed > 0) {
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
ec = this->validate_incoming_basic_header(
|
||||
m_basic_header, base::m_server, !m_data_msg.msg_ptr
|
||||
);
|
||||
@@ -339,7 +339,7 @@ public:
|
||||
// extract full header size and adjust consume state accordingly
|
||||
m_state = HEADER_EXTENDED;
|
||||
m_cursor = 0;
|
||||
m_bytes_needed = frame::get_header_len(m_basic_header) -
|
||||
m_bytes_needed = frame::get_header_len(m_basic_header) -
|
||||
frame::BASIC_HEADER_LENGTH;
|
||||
} else if (m_state == HEADER_EXTENDED) {
|
||||
p += this->copy_extended_header_bytes(buf+p,len-p);
|
||||
@@ -347,25 +347,25 @@ public:
|
||||
if (m_bytes_needed > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
ec = validate_incoming_extended_header(m_basic_header,m_extended_header);
|
||||
if (ec){break;}
|
||||
|
||||
|
||||
m_state = APPLICATION;
|
||||
m_bytes_needed = static_cast<size_t>(get_payload_size(m_basic_header,m_extended_header));
|
||||
|
||||
|
||||
// check if this frame is the start of a new message and set up
|
||||
// the appropriate message metadata.
|
||||
frame::opcode::value op = frame::get_opcode(m_basic_header);
|
||||
|
||||
|
||||
// TODO: get_message failure conditions
|
||||
|
||||
|
||||
if (frame::opcode::is_control(op)) {
|
||||
m_control_msg = msg_metadata(
|
||||
m_msg_manager->get_message(op,m_bytes_needed),
|
||||
frame::get_masking_key(m_basic_header,m_extended_header)
|
||||
);
|
||||
|
||||
|
||||
m_current_msg = &m_control_msg;
|
||||
} else {
|
||||
if (!m_data_msg.msg_ptr) {
|
||||
@@ -390,17 +390,17 @@ public:
|
||||
m_state = APPLICATION;
|
||||
} else if (m_state == APPLICATION) {
|
||||
size_t bytes_to_process = std::min(m_bytes_needed,len-p);
|
||||
|
||||
|
||||
if (bytes_to_process > 0) {
|
||||
p += this->process_payload_bytes(buf+p,bytes_to_process,ec);
|
||||
|
||||
|
||||
if (ec) {break;}
|
||||
}
|
||||
|
||||
if (m_bytes_needed > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// If this was the last frame in the message set the ready flag.
|
||||
// Otherwise, reset processor state to read additional frames.
|
||||
if (frame::get_fin(m_basic_header)) {
|
||||
@@ -422,10 +422,10 @@ public:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void reset_headers() {
|
||||
m_state = HEADER_BASIC;
|
||||
m_bytes_needed = frame::BASIC_HEADER_LENGTH;
|
||||
@@ -439,12 +439,12 @@ public:
|
||||
0x00
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// Test whether or not the processor has a message ready
|
||||
bool ready() const {
|
||||
return (m_state == READY);
|
||||
}
|
||||
|
||||
|
||||
message_ptr get_message() {
|
||||
if (!ready()) {
|
||||
return message_ptr();
|
||||
@@ -457,12 +457,12 @@ public:
|
||||
} else {
|
||||
m_data_msg.msg_ptr.reset();
|
||||
}
|
||||
|
||||
|
||||
this->reset_headers();
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/// Test whether or not the processor is in a fatal error state.
|
||||
bool get_error() const {
|
||||
return m_state == FATAL_ERROR;
|
||||
@@ -474,24 +474,24 @@ public:
|
||||
|
||||
/// Prepare a user data message for writing
|
||||
/**
|
||||
* Performs validation, masking, compression, etc. will return an error if
|
||||
* Performs validation, masking, compression, etc. will return an error if
|
||||
* there was an error, otherwise msg will be ready to be written
|
||||
*
|
||||
* By default WebSocket++ performs block masking/unmasking in a manner that
|
||||
* makes assumptions about the nature of the machine and STL library used.
|
||||
* In particular the assumption is either a 32 or 64 bit word size and an
|
||||
* By default WebSocket++ performs block masking/unmasking in a manner that
|
||||
* makes assumptions about the nature of the machine and STL library used.
|
||||
* In particular the assumption is either a 32 or 64 bit word size and an
|
||||
* STL with std::string::data returning a contiguous char array.
|
||||
*
|
||||
* This method improves masking performance by 3-8x depending on the ratio
|
||||
*
|
||||
* This method improves masking performance by 3-8x depending on the ratio
|
||||
* of small to large messages and the availability of a 64 bit processor.
|
||||
*
|
||||
* To disable this optimization (for use with alternative STL
|
||||
*
|
||||
* To disable this optimization (for use with alternative STL
|
||||
* implementations or processors) define WEBSOCKETPP_STRICT_MASKING when
|
||||
* compiling the library. This will force the library to perform masking in
|
||||
* single byte chunks.
|
||||
*
|
||||
*
|
||||
* TODO: tests
|
||||
*
|
||||
*
|
||||
* @param in An unprepared message to prepare
|
||||
* @param out A message to be overwritten with the prepared message
|
||||
* @return error code
|
||||
@@ -501,42 +501,42 @@ public:
|
||||
if (!in || !out) {
|
||||
return make_error_code(error::invalid_arguments);
|
||||
}
|
||||
|
||||
|
||||
frame::opcode::value op = in->get_opcode();
|
||||
|
||||
// validate opcode: only regular data frames
|
||||
// validate opcode: only regular data frames
|
||||
if (frame::opcode::is_control(op)) {
|
||||
return make_error_code(error::invalid_opcode);
|
||||
}
|
||||
|
||||
|
||||
std::string& i = in->get_raw_payload();
|
||||
std::string& o = out->get_raw_payload();
|
||||
|
||||
|
||||
// validate payload utf8
|
||||
if (op == frame::opcode::TEXT && !utf8_validator::validate(i)) {
|
||||
return make_error_code(error::invalid_payload);
|
||||
}
|
||||
|
||||
|
||||
frame::masking_key_type key;
|
||||
bool masked = !base::m_server;
|
||||
bool compressed = m_permessage_deflate.is_enabled()
|
||||
bool compressed = m_permessage_deflate.is_enabled()
|
||||
&& in->get_compressed();
|
||||
bool fin = in->get_fin();
|
||||
|
||||
|
||||
// generate header
|
||||
frame::basic_header h(op,i.size(),fin,masked,compressed);
|
||||
|
||||
|
||||
if (masked) {
|
||||
// Generate masking key.
|
||||
key.i = m_rng();
|
||||
|
||||
|
||||
frame::extended_header e(i.size(),key.i);
|
||||
out->set_header(frame::prepare_header(h,e));
|
||||
} else {
|
||||
frame::extended_header e(i.size());
|
||||
out->set_header(frame::prepare_header(h,e));
|
||||
}
|
||||
|
||||
|
||||
// prepare payload
|
||||
if (compressed) {
|
||||
// compress and store in o after header.
|
||||
@@ -549,7 +549,7 @@ public:
|
||||
} else {
|
||||
// no compression, just copy data into the output buffer
|
||||
o.resize(i.size());
|
||||
|
||||
|
||||
// if we are masked, have the masking function write to the output
|
||||
// buffer directly to avoid another copy. If not masked, copy
|
||||
// directly without masking.
|
||||
@@ -561,7 +561,7 @@ public:
|
||||
}
|
||||
|
||||
out->set_prepared(true);
|
||||
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
@@ -574,7 +574,7 @@ public:
|
||||
return this->prepare_control(frame::opcode::PONG,in,out);
|
||||
}
|
||||
|
||||
virtual lib::error_code prepare_close(close::status::value code,
|
||||
virtual lib::error_code prepare_close(close::status::value code,
|
||||
std::string const & reason, message_ptr out) const
|
||||
{
|
||||
if (close::status::reserved(code)) {
|
||||
@@ -584,7 +584,7 @@ public:
|
||||
if (close::status::invalid(code) && code != close::status::no_status) {
|
||||
return make_error_code(error::invalid_close_code);
|
||||
}
|
||||
|
||||
|
||||
if (code == close::status::no_status && reason.size() > 0) {
|
||||
return make_error_code(error::reason_requires_code);
|
||||
}
|
||||
@@ -592,57 +592,57 @@ public:
|
||||
if (reason.size() > frame:: limits::payload_size_basic-2) {
|
||||
return make_error_code(error::control_too_big);
|
||||
}
|
||||
|
||||
|
||||
std::string payload;
|
||||
|
||||
|
||||
if (code != close::status::no_status) {
|
||||
close::code_converter val;
|
||||
val.i = htons(code);
|
||||
|
||||
payload.resize(reason.size()+2);
|
||||
|
||||
|
||||
payload[0] = val.c[0];
|
||||
payload[1] = val.c[1];
|
||||
|
||||
std::copy(reason.begin(),reason.end(),payload.begin()+2);
|
||||
}
|
||||
|
||||
|
||||
return this->prepare_control(frame::opcode::CLOSE,payload,out);
|
||||
}
|
||||
protected:
|
||||
/// Convert a client handshake key into a server response key in place
|
||||
lib::error_code process_handshake_key(std::string & key) const {
|
||||
key.append(constants::handshake_guid);
|
||||
|
||||
|
||||
sha1 sha;
|
||||
uint32_t message_digest[5];
|
||||
|
||||
|
||||
sha << key.c_str();
|
||||
|
||||
|
||||
if (sha.get_raw_digest(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]);
|
||||
}
|
||||
|
||||
|
||||
key = base64_encode(
|
||||
reinterpret_cast<unsigned char const *>(message_digest),
|
||||
20
|
||||
);
|
||||
|
||||
|
||||
return lib::error_code();
|
||||
} else {
|
||||
return error::make_error_code(error::sha1_library);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Reads bytes from buf into m_basic_header
|
||||
size_t copy_basic_header_bytes(uint8_t const * buf, size_t len) {
|
||||
if (len == 0 || m_bytes_needed == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (len > 1) {
|
||||
// have at least two bytes
|
||||
if (m_bytes_needed == 2) {
|
||||
@@ -672,7 +672,7 @@ protected:
|
||||
/// Reads bytes from buf into m_extended_header
|
||||
size_t copy_extended_header_bytes(uint8_t const * buf, size_t len) {
|
||||
size_t bytes_to_read = std::min(m_bytes_needed,len);
|
||||
|
||||
|
||||
std::copy(buf,buf+bytes_to_read,m_extended_header.bytes+m_cursor);
|
||||
m_cursor += bytes_to_read;
|
||||
m_bytes_needed -= bytes_to_read;
|
||||
@@ -682,13 +682,13 @@ protected:
|
||||
|
||||
/// Reads bytes from buf into message payload
|
||||
/**
|
||||
* This function performs unmasking and uncompression, validates the
|
||||
* This function performs unmasking and uncompression, validates the
|
||||
* decoded bytes, and writes them to the appropriate message buffer.
|
||||
*
|
||||
* This member function will use the input buffer as stratch space for its
|
||||
*
|
||||
* This member function will use the input buffer as stratch space for its
|
||||
* work. The raw input bytes will not be preserved. This applies only to the
|
||||
* bytes actually needed. At most min(m_bytes_needed,len) will be processed.
|
||||
*
|
||||
*
|
||||
* @param buf Input/working buffer
|
||||
* @param len Length of buf
|
||||
* @return Number of bytes processed or zero in case of an error
|
||||
@@ -711,17 +711,17 @@ protected:
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
std::string & out = m_current_msg->msg_ptr->get_raw_payload();
|
||||
size_t offset = out.size();
|
||||
|
||||
// decompress message if needed.
|
||||
if (m_permessage_deflate.is_enabled()
|
||||
if (m_permessage_deflate.is_enabled()
|
||||
&& frame::get_rsv1(m_basic_header))
|
||||
{
|
||||
// Decompress current buffer into the message buffer
|
||||
m_permessage_deflate.decompress(buf,len,out);
|
||||
|
||||
|
||||
// get the length of the newly uncompressed output
|
||||
offset = out.size() - offset;
|
||||
} else {
|
||||
@@ -736,34 +736,29 @@ protected:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// copy into message buffer
|
||||
/*m_current_msg->msg_ptr->append_payload(
|
||||
reinterpret_cast<char *>(buf),
|
||||
len
|
||||
);*/
|
||||
|
||||
m_bytes_needed -= len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/// Validate an incoming basic header
|
||||
/**
|
||||
* Validates an incoming hybi13 basic header.
|
||||
*
|
||||
*
|
||||
* @param h The basic header to validate
|
||||
* @param is_server Whether or not the endpoint that received this frame
|
||||
* is a server.
|
||||
* @param new_msg Whether or not this is the first frame of the message
|
||||
* @return 0 on success or a non-zero error code on failure
|
||||
*/
|
||||
lib::error_code validate_incoming_basic_header(frame::basic_header const & h,
|
||||
lib::error_code validate_incoming_basic_header(frame::basic_header const & h,
|
||||
bool is_server, bool new_msg) const
|
||||
{
|
||||
frame::opcode::value op = frame::get_opcode(h);
|
||||
|
||||
// Check control frame size limit
|
||||
if (frame::opcode::is_control(op) &&
|
||||
if (frame::opcode::is_control(op) &&
|
||||
frame::get_basic_size(h) > frame::limits::payload_size_basic)
|
||||
{
|
||||
return make_error_code(error::control_too_big);
|
||||
@@ -775,9 +770,9 @@ protected:
|
||||
// a control message.
|
||||
//
|
||||
// TODO: unit tests for this
|
||||
if (frame::get_rsv1(h) && (!m_permessage_deflate.is_enabled()
|
||||
if (frame::get_rsv1(h) && (!m_permessage_deflate.is_enabled()
|
||||
|| frame::opcode::is_control(op)))
|
||||
{
|
||||
{
|
||||
return make_error_code(error::invalid_rsv_bit);
|
||||
}
|
||||
|
||||
@@ -800,12 +795,12 @@ protected:
|
||||
if (frame::opcode::is_control(op) && !frame::get_fin(h)) {
|
||||
return make_error_code(error::fragmented_control);
|
||||
}
|
||||
|
||||
|
||||
// Check for continuation without an active message
|
||||
if (new_msg && op == frame::opcode::CONTINUATION) {
|
||||
return make_error_code(error::invalid_continuation);
|
||||
}
|
||||
|
||||
|
||||
// Check for new data frame when expecting continuation
|
||||
if (!new_msg && !frame::opcode::is_control(op) &&
|
||||
op != frame::opcode::CONTINUATION)
|
||||
@@ -823,7 +818,7 @@ protected:
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
|
||||
/// Validate an incoming extended header
|
||||
/**
|
||||
* Validates an incoming hybi13 full header.
|
||||
@@ -832,23 +827,23 @@ protected:
|
||||
*
|
||||
* @param h The basic header to validate
|
||||
* @param e The extended header to validate
|
||||
* @return An error_code, non-zero values indicate why the validation
|
||||
* @return An error_code, non-zero values indicate why the validation
|
||||
* failed
|
||||
*/
|
||||
lib::error_code validate_incoming_extended_header(frame::basic_header h,
|
||||
lib::error_code validate_incoming_extended_header(frame::basic_header h,
|
||||
frame::extended_header e) const
|
||||
{
|
||||
uint8_t basic_size = frame::get_basic_size(h);
|
||||
uint64_t payload_size = frame::get_payload_size(h,e);
|
||||
|
||||
|
||||
// Check for non-minimally encoded payloads
|
||||
if (basic_size == frame::payload_size_code_16bit &&
|
||||
if (basic_size == frame::payload_size_code_16bit &&
|
||||
payload_size <= frame::limits::payload_size_basic)
|
||||
{
|
||||
return make_error_code(error::non_minimal_encoding);
|
||||
}
|
||||
|
||||
if (basic_size == frame::payload_size_code_64bit &&
|
||||
if (basic_size == frame::payload_size_code_64bit &&
|
||||
payload_size <= frame::limits::payload_size_extended)
|
||||
{
|
||||
return make_error_code(error::non_minimal_encoding);
|
||||
@@ -861,7 +856,7 @@ protected:
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
|
||||
/// Copy and mask/unmask in one operation
|
||||
/**
|
||||
* Reads input from one string and writes unmasked output to another.
|
||||
@@ -911,29 +906,27 @@ protected:
|
||||
|
||||
frame::masking_key_type key;
|
||||
bool masked = !base::m_server;
|
||||
|
||||
|
||||
frame::basic_header h(op,payload.size(),true,masked);
|
||||
|
||||
std::string& o = out->get_raw_payload();
|
||||
std::string & o = out->get_raw_payload();
|
||||
o.resize(payload.size());
|
||||
|
||||
if (masked) {
|
||||
// Generate masking key.
|
||||
key.i = m_rng();
|
||||
|
||||
|
||||
frame::extended_header e(payload.size(),key.i);
|
||||
out->set_header(frame::prepare_header(h,e));
|
||||
this->masked_copy(payload,o,key);
|
||||
} else {
|
||||
frame::extended_header e(payload.size());
|
||||
out->set_header(frame::prepare_header(h,e));
|
||||
//std::cout << "o: " << o.size() << std::endl;
|
||||
std::copy(payload.begin(),payload.end(),o.begin());
|
||||
//std::cout << "o: " << o.size() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
out->set_prepared(true);
|
||||
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
@@ -945,14 +938,14 @@ protected:
|
||||
READY = 4,
|
||||
FATAL_ERROR = 5
|
||||
};
|
||||
|
||||
/// This data structure holds data related to processing a message, such as
|
||||
/// the buffer it is being written to, its masking key, its UTF8 validation
|
||||
|
||||
/// This data structure holds data related to processing a message, such as
|
||||
/// the buffer it is being written to, its masking key, its UTF8 validation
|
||||
/// state, and sometimes its compression state.
|
||||
struct msg_metadata {
|
||||
msg_metadata() {}
|
||||
msg_metadata(message_ptr m, size_t p) : msg_ptr(m),prepared_key(p) {}
|
||||
msg_metadata(message_ptr m, frame::masking_key_type p)
|
||||
msg_metadata(message_ptr m, frame::masking_key_type p)
|
||||
: msg_ptr(m)
|
||||
, prepared_key(prepare_masking_key(p)) {}
|
||||
|
||||
@@ -960,19 +953,19 @@ protected:
|
||||
size_t prepared_key; // prepared masking key
|
||||
utf8_validator::validator validator; // utf8 validation state
|
||||
};
|
||||
|
||||
|
||||
// Basic header of the frame being read
|
||||
frame::basic_header m_basic_header;
|
||||
|
||||
|
||||
// Pointer to a manager that can create message buffers for us.
|
||||
msg_manager_ptr m_msg_manager;
|
||||
|
||||
// Number of bytes needed to complete the current operation
|
||||
size_t m_bytes_needed;
|
||||
|
||||
|
||||
// Number of extended header bytes read
|
||||
size_t m_cursor;
|
||||
|
||||
|
||||
// Metadata for the current data msg
|
||||
msg_metadata m_data_msg;
|
||||
// Metadata for the current control msg
|
||||
@@ -980,15 +973,9 @@ protected:
|
||||
|
||||
// Pointer to the metadata associated with the frame being read
|
||||
msg_metadata * m_current_msg;
|
||||
|
||||
|
||||
// Extended header of current frame
|
||||
frame::extended_header m_extended_header;
|
||||
|
||||
|
||||
// write/prep state
|
||||
// original opcode
|
||||
// utf8 validator
|
||||
// compression state
|
||||
|
||||
rng_type & m_rng;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user