unfinished send api work

This commit is contained in:
Peter Thorson
2011-12-21 17:22:28 -06:00
parent 4d03909d58
commit d19ee815b8
4 changed files with 87 additions and 6 deletions

View File

@@ -28,6 +28,7 @@
#include "data.hpp"
#include "../processors/processor.hpp"
#include "../processors/hybi_header.hpp"
using websocketpp::message::data;
@@ -97,7 +98,7 @@ void data::process_character(unsigned char c) {
void data::reset(frame::opcode::value opcode) {
m_opcode = opcode;
m_masking_index = 0;
m_masking_index = M_NOT_MASKED; // -1 indicates do not mask/unmask
m_payload.resize(0);
m_validator.reset();
}
@@ -112,5 +113,30 @@ void data::complete() {
void data::set_masking_key(int32_t key) {
*reinterpret_cast<int32_t*>(m_masking_key) = key;
m_masking_index = (key == 0 ? -1 : 0);
}
// -2 indicates a masked frame whose key is zero.
m_masking_index = (key == 0 ? M_MASK_KEY_ZERO : M_BYTE_0);
}
// This could be further optimized using methods that write directly into the
// m_payload buffer
void data::set_payload(const std::string& payload) {
m_payload.reserve(payload.size());
std::copy(payload.begin(), payload.end(), m_payload.begin());
}
void data::process() {
websocketpp::processor::hybi_header header;
header.set_fin(true);
header.set_opcode(m_opcode);
// set opcode
// set
// mask
if (m_masking_index >= 0) {
for (std::string::iterator it = m_payload.begin(); it != m_payload.end(); it++) {
(*it) = *it ^ m_masking_key[(m_masking_index++)%4];
}
}
}

View File

@@ -41,18 +41,44 @@ class data {
public:
data();
void reset(frame::opcode::value opcode);
frame::opcode::value get_opcode() const;
const std::string& get_payload() const;
// ##reading##
// sets the masking key to be used to unmask as bytes are read.
void set_masking_key(int32_t key);
// read at most size bytes from a payload stream and perform unmasking/utf8
// validation. Returns number of bytes read.
// 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 reset(frame::opcode::value opcode);
void complete();
void set_masking_key(int32_t key);
// ##writing##
// sets the payload to payload. Performs max size and UTF8 validation
// immediately and throws processor::exception if it fails
void set_payload(const std::string& payload);
// Performs masking and header generation if it has not been done already.
void process();
private:
static const uint64_t PAYLOAD_SIZE_INIT = 1000; // 1KB
static const uint64_t PAYLOAD_SIZE_MAX = 100000000;// 100MB
enum index_value {
M_MASK_KEY_ZERO = -2,
M_NOT_MASKED = -1,
M_BYTE_0 = 0,
M_BYTE_1 = 1,
M_BYTE_2 = 2,
M_BYTE_3 = 3
};
// Message state
frame::opcode::value m_opcode;
@@ -61,9 +87,11 @@ private:
// Masking state
unsigned char m_masking_key[4];
int m_masking_index;
// m_masking_index can take on
index_value m_masking_index;
// Message buffers
std::string m_header;
std::string m_payload;
};

View File

@@ -199,6 +199,31 @@ size_t hybi_header::get_payload_size() const {
return m_payload_size;
}
void hybi_header::set_payload_size(size_t size) {
if (size <= frame::limits::PAYLOAD_SIZE_BASIC) {
// encode in byte 2
m_header[1] &= (size & BPB1_PAYLOAD);
} else if (size <= frame::limits::PAYLOAD_SIZE_EXTENDED) {
// encode two byte
m_header[1] &= (BASIC_PAYLOAD_16BIT_CODE & BPB1_PAYLOAD);
if (get_masked()) {
}
*(reinterpret_cast<uint16_t*>(&m_header[BASIC_HEADER_LENGTH])) = htons(size);
} else if (size <= frame::limits::PAYLOAD_SIZE_EXTENDED) {
// encode two byte
m_header[1] &= (BASIC_PAYLOAD_64BIT_CODE & BPB1_PAYLOAD);
} else {
throw processor::exception("Client attempted to send a message that was too big",processor::error::MESSAGE_TOO_BIG);
}
}
bool hybi_header::is_control() const {
return (frame::opcode::is_control(get_opcode()));
}

View File

@@ -72,6 +72,8 @@ public:
uint8_t get_basic_size() const;
size_t get_payload_size() const;
void set_payload_size(size_t size);
bool is_control() const;
void process_basic_header();