diff --git a/test/processors/hybi00.cpp b/test/processors/hybi00.cpp index 09042915a6..d22edc4579 100644 --- a/test/processors/hybi00.cpp +++ b/test/processors/hybi00.cpp @@ -225,6 +225,48 @@ BOOST_AUTO_TEST_CASE( prepare_data_frame ) { unsigned char raw_header[1] = {0x00}; unsigned char raw_payload[4] = {0x66,0x6f,0x6f,0xff}; + BOOST_CHECK( !env.ec ); BOOST_CHECK_EQUAL( out->get_header(), std::string(reinterpret_cast(raw_header),1) ); BOOST_CHECK_EQUAL( out->get_payload(), std::string(reinterpret_cast(raw_payload),4) ); } + + +BOOST_AUTO_TEST_CASE( empty_consume ) { + uint8_t frame[2] = {0x00,0x00}; + + processor_setup env(true); + + size_t ret = env.p.consume(frame,0,env.ec); + + BOOST_CHECK_EQUAL( ret, 0); + BOOST_CHECK( !env.ec ); + BOOST_CHECK_EQUAL( env.p.ready(), false ); +} + +BOOST_AUTO_TEST_CASE( empty_frame ) { + uint8_t frame[2] = {0x00, 0xff}; + + processor_setup env(true); + + size_t ret = env.p.consume(frame,2,env.ec); + + BOOST_CHECK_EQUAL( ret, 2); + BOOST_CHECK( !env.ec ); + BOOST_CHECK_EQUAL( env.p.ready(), true ); + BOOST_CHECK_EQUAL( env.p.get_message()->get_payload(), "" ); + BOOST_CHECK_EQUAL( env.p.ready(), false ); +} + +BOOST_AUTO_TEST_CASE( short_frame ) { + uint8_t frame[5] = {0x00, 0x66, 0x6f, 0x6f, 0xff}; + + processor_setup env(true); + + size_t ret = env.p.consume(frame,5,env.ec); + + BOOST_CHECK_EQUAL( ret, 5); + BOOST_CHECK( !env.ec ); + BOOST_CHECK_EQUAL( env.p.ready(), true ); + BOOST_CHECK_EQUAL( env.p.get_message()->get_payload(), "foo" ); + BOOST_CHECK_EQUAL( env.p.ready(), false ); +} diff --git a/websocketpp/processors/hybi00.hpp b/websocketpp/processors/hybi00.hpp index 319e42d1df..86976510a6 100644 --- a/websocketpp/processors/hybi00.hpp +++ b/websocketpp/processors/hybi00.hpp @@ -40,6 +40,8 @@ #include #include +#include + #include namespace websocketpp { @@ -63,7 +65,11 @@ public: typedef typename config::con_msg_manager_type::ptr msg_manager_ptr; explicit hybi00(bool secure, bool server, msg_manager_ptr manager) - : processor(secure, server) {} + : processor(secure, server) + , msg_hdr(0x00) + , msg_ftr(0xff) + , m_state(HEADER) + , m_msg_manager(manager) {} int get_version() const { return 0; @@ -196,12 +202,65 @@ public: /// Process new websocket connection bytes size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) { - ec = make_error_code(error::not_implimented); - return 0; + // if in state header we are expecting a 0x00 byte, if we don't get one + // it is a fatal error + size_t p = 0; // bytes processed + size_t l = 0; + + ec = lib::error_code(); + + while (p < len) { + if (m_state == HEADER) { + if (buf[p] == msg_hdr) { + p++; + m_msg_ptr = m_msg_manager->get_message(frame::opcode::text,1); + + if (!m_msg_ptr) { + ec = make_error_code(websocketpp::error::no_incoming_buffers); + m_state = FATAL_ERROR; + } else { + m_state = PAYLOAD; + } + } else { + ec = make_error_code(error::protocol_violation); + m_state = FATAL_ERROR; + } + } else if (m_state == PAYLOAD) { + uint8_t *it = std::find(buf+p,buf+len,uint8_t(msg_ftr)); + + // 0 1 2 3 4 5 + // 0x00 0x23 0x23 0x23 0xff 0xXX + + // Copy payload bytes into message + l = it-(buf+p); + m_msg_ptr->append_payload(buf+p,l); + p += l; + + if (it != buf+len) { + // message is done, copy it and the trailing + p++; + // TODO: validation + m_state = READY; + } + } else { + // TODO + break; + } + } + // If we get one, we create a new message and move to application state + + // if in state application we are copying bytes into the output message + // and validating them for UTF8 until we hit a 0xff byte. Once we hit + // 0x00, the message is complete and is dispatched. Then we go back to + // header state. + + //ec = make_error_code(error::not_implimented); + return p; } bool ready() const { - return false; + std::cout << "state: " << m_state << std::endl; + return (m_state == READY); } bool get_error() const { @@ -209,7 +268,10 @@ public: } message_ptr get_message() { - return message_ptr(); + message_ptr ret = m_msg_ptr; + m_msg_ptr = message_ptr(); + m_state = HEADER; + return ret; } /// Prepare a message for writing @@ -239,13 +301,11 @@ public: } // generate header - char h = 0x00; - char f = 0xff; - out->set_header(std::string(&h,1)); + out->set_header(std::string(&msg_hdr,1)); // process payload out->set_payload(i); - out->append_payload(std::string(&f,1)); + out->append_payload(std::string(&msg_ftr,1)); // hybi00 doesn't support compression // hybi00 doesn't have masking @@ -295,6 +355,22 @@ private: std::fill(result,result+4,0); } } + + enum state { + HEADER = 0, + PAYLOAD = 1, + READY = 2, + FATAL_ERROR = 3 + }; + + const char msg_hdr; + const char msg_ftr; + + state m_state; + + msg_manager_ptr m_msg_manager; + message_ptr m_msg_ptr; + utf8_validator::validator m_validator; };