diff --git a/src/processors/hybi.hpp b/src/processors/hybi.hpp index db6e696f5b..0cc2a366d4 100644 --- a/src/processors/hybi.hpp +++ b/src/processors/hybi.hpp @@ -390,7 +390,7 @@ public: 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, diff --git a/src/processors/hybi_header.cpp b/src/processors/hybi_header.cpp index 690d024b38..36462091c9 100644 --- a/src/processors/hybi_header.cpp +++ b/src/processors/hybi_header.cpp @@ -27,19 +27,45 @@ #include "hybi_header.hpp" +#include + +using websocketpp::processor::hybi_header_writer; + +hybi_header_writer::hybi_header_writer() { + reset(); +} + +void hybi_header_writer::reset() { + memset(m_header, 0x00, MAX_HEADER_LENGTH); +} + +std::string hybi_header_writer::get_header_bytes() const { + return std::string(m_header); +} + + + + + + + using websocketpp::processor::hybi_header; -hybi_header::hybi_header() { - reset(); +hybi_header::hybi_header(bool reading) { + reset(reading); } uint64_t hybi_header::get_bytes_needed() const { return m_bytes_needed; } -void hybi_header::reset() { - m_state = STATE_BASIC_HEADER; - m_bytes_needed = BASIC_HEADER_LENGTH; +void hybi_header::reset(bool reading) { + if (reading) { + m_state = STATE_BASIC_HEADER; + m_bytes_needed = BASIC_HEADER_LENGTH; + } else { + m_state = STATE_WRITE; + } } bool hybi_header::ready() const { diff --git a/src/processors/hybi_header.hpp b/src/processors/hybi_header.hpp index f9fd789c8b..b3d0f7957e 100644 --- a/src/processors/hybi_header.hpp +++ b/src/processors/hybi_header.hpp @@ -34,45 +34,91 @@ namespace websocketpp { namespace processor { +class hybi_header_writer { +public: + hybi_header_writer(); + void reset(); + + void set_fin(bool fin); + void set_rsv1(bool b); + void set_rsv2(bool b); + void set_rsv3(bool b); + void set_opcode(frame::opcode::value op); + void set_masked(bool masked,int32_t key); + void set_payload_size(size_t size); + + std::string get_header_bytes() const; +private: + // 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 = 15; + + char m_header[MAX_HEADER_LENGTH]; +}; + + +// hybi header can be used for the following two tasks: +// - parse a sequence of bytes into a complete header and read fields +// - set fields and then generate a sequence of header bytes + class hybi_header { public: - hybi_header(); - - uint64_t get_bytes_needed() const; - - void reset(); - - bool ready() const; + // constructs/resets a hybi_header for the purpose of either reading or writing + hybi_header(bool reading = true); + void reset(bool reading = true); + // Reading interface (Parse a byte stream) void consume(std::istream& input); - + uint64_t get_bytes_needed() const; + bool ready() const; + + bool get_fin() const; + bool get_rsv1() const; + bool get_rsv2() const; + bool get_rsv3() const; + frame::opcode::value get_opcode() const; + bool get_masked() const; + + // Writing interface (Set fields directly) + void set_fin(bool fin); + void set_rsv1(bool b); + void set_rsv2(bool b); + void set_rsv3(bool b); + void set_opcode(frame::opcode::value op); + void set_masked(bool masked,int32_t key); + void set_payload_size(size_t size); + + std::string get_header_bytes() const; + + unsigned int get_header_len() const; int32_t get_masking_key(); // get and set header bits - bool get_fin() const; - void set_fin(bool fin); - bool get_rsv1() const; - void set_rsv1(bool b); - bool get_rsv2() const; - void set_rsv2(bool b); - bool get_rsv3() const; - void set_rsv3(bool b); - frame::opcode::value get_opcode() const; - void set_opcode(frame::opcode::value op); - bool get_masked() const; - void set_masked(bool masked,int32_t key); + + uint8_t get_basic_size() const; size_t get_payload_size() const; - void set_payload_size(size_t size); + bool is_control() const; @@ -103,6 +149,7 @@ private: 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;