From 66b657a85f330c01c93fe12210aea985401469a1 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sun, 13 Aug 2017 17:25:48 -0700 Subject: [PATCH] Autobahn|Testsuite fixes --- CHANGELOG.md | 1 + .../server/fast/websocket_server_fast.cpp | 1 - include/boost/beast/websocket/impl/read.ipp | 53 +++++++++++-------- include/boost/beast/websocket/impl/stream.ipp | 28 +++++----- include/boost/beast/websocket/stream.hpp | 4 +- 5 files changed, 47 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efac9c57..8e60874b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ WebSocket: * Refactor close_op * Refactor read_op + fail_op * Websocket close will automatically drain +* Autobahn|Testsuite fixes -------------------------------------------------------------------------------- diff --git a/example/websocket/server/fast/websocket_server_fast.cpp b/example/websocket/server/fast/websocket_server_fast.cpp index 0c704707..0fb28a2f 100644 --- a/example/websocket/server/fast/websocket_server_fast.cpp +++ b/example/websocket/server/fast/websocket_server_fast.cpp @@ -104,7 +104,6 @@ do_sync_session(tcp::socket& socket) break; if(ec) return fail(ec, "read"); - ws.text(ws.got_text()); ws.write(buffer.data(), ec); if(ec) diff --git a/include/boost/beast/websocket/impl/read.ipp b/include/boost/beast/websocket/impl/read.ipp index dec46d89..ce2655b9 100644 --- a/include/boost/beast/websocket/impl/read.ipp +++ b/include/boost/beast/websocket/impl/read.ipp @@ -210,17 +210,21 @@ operator()( ws_.rd_.key); if(detail::is_control(ws_.rd_.fh.op)) { + // Clear this otherwise the next + // frame will be considered final. + ws_.rd_.fh.fin = false; + // Handle ping frame if(ws_.rd_.fh.op == detail::opcode::ping) { { - auto const cb = buffer_prefix( + auto const b = buffer_prefix( clamp(ws_.rd_.fh.len), ws_.rd_.buf.data()); - auto const len = buffer_size(cb); + auto const len = buffer_size(b); BOOST_ASSERT(len == ws_.rd_.fh.len); ping_data payload; - detail::read_ping(payload, cb); + detail::read_ping(payload, b); ws_.rd_.buf.consume(len); // Ignore ping when closing if(ws_.wr_close_) @@ -356,11 +360,9 @@ operator()( // get fewer bytes at the cost of one I/O. BOOST_ASIO_CORO_YIELD ws_.stream_.async_read_some( - ws_.rd_.buf.prepare( - read_size( - ws_.rd_.buf, - ws_.rd_.buf.max_size())), - std::move(*this)); + ws_.rd_.buf.prepare(read_size( + ws_.rd_.buf, ws_.rd_.buf.max_size())), + std::move(*this)); dispatched_ = true; ws_.failed_ = !!ec; if(ws_.failed_) @@ -954,15 +956,20 @@ loop: if(detail::is_control(rd_.fh.op)) { // Get control frame payload - auto const cb = buffer_prefix( + auto const b = buffer_prefix( clamp(rd_.fh.len), rd_.buf.data()); - auto const len = buffer_size(cb); + auto const len = buffer_size(b); BOOST_ASSERT(len == rd_.fh.len); - // Process control frame + + // Clear this otherwise the next + // frame will be considered final. + rd_.fh.fin = false; + + // Handle ping frame if(rd_.fh.op == detail::opcode::ping) { ping_data payload; - detail::read_ping(payload, cb); + detail::read_ping(payload, b); rd_.buf.consume(len); if(wr_close_) { @@ -980,21 +987,23 @@ loop: return bytes_written; goto loop; } - else if(rd_.fh.op == detail::opcode::pong) + // Handle pong frame + if(rd_.fh.op == detail::opcode::pong) { ping_data payload; - detail::read_ping(payload, cb); + detail::read_ping(payload, b); rd_.buf.consume(len); if(ctrl_cb_) ctrl_cb_(frame_type::pong, payload); goto loop; } + // Handle close frame BOOST_ASSERT(rd_.fh.op == detail::opcode::close); { BOOST_ASSERT(! rd_close_); rd_close_ = true; close_reason cr; - detail::read_close(cr, cb, code); + detail::read_close(cr, b, code); if(code != close_code::none) { // _Fail the WebSocket Connection_ @@ -1040,18 +1049,16 @@ loop: { // Fill the read buffer first, otherwise we // get fewer bytes at the cost of one I/O. - auto const mb = rd_.buf.prepare( - read_size(rd_.buf, rd_.buf.max_size())); - auto const bytes_transferred = - stream_.read_some(mb, ec); + rd_.buf.commit(stream_.read_some( + rd_.buf.prepare(read_size(rd_.buf, + rd_.buf.max_size())), ec)); failed_ = !!ec; if(failed_) return bytes_written; if(rd_.fh.mask) - detail::mask_inplace(buffer_prefix( - clamp(rd_.remain), mb), rd_.key); - // VFALCO Do this before masking for symmetry with the async version - rd_.buf.commit(bytes_transferred); + detail::mask_inplace( + buffer_prefix(clamp(rd_.remain), + rd_.buf.data()), rd_.key); } if(rd_.buf.size() > 0) { diff --git a/include/boost/beast/websocket/impl/stream.ipp b/include/boost/beast/websocket/impl/stream.ipp index 7c3e95b7..b62cecf7 100644 --- a/include/boost/beast/websocket/impl/stream.ipp +++ b/include/boost/beast/websocket/impl/stream.ipp @@ -304,10 +304,10 @@ parse_fh( consuming_buffers cb{ b.data()}; + std::size_t need; { std::uint8_t tmp[2]; cb.consume(buffer_copy(buffer(tmp), cb)); - std::size_t need; fh.len = tmp[1] & 0x7f; switch(fh.len) { @@ -393,7 +393,7 @@ parse_fh( if(role_ == role_type::client && fh.mask) return err(close_code::protocol_error); if(detail::is_control(fh.op) && - buffer_size(cb) < fh.len) + buffer_size(cb) < need + fh.len) { // Make the entire control frame payload // get read in before we return `true` @@ -489,24 +489,24 @@ write_close(DynamicBuffer& db, close_reason const& cr) if(fh.mask) detail::prepare_key(key, fh.key); { - std::uint8_t b[2]; - ::new(&b[0]) big_uint16_buf_t{ + std::uint8_t tmp[2]; + ::new(&tmp[0]) big_uint16_buf_t{ (std::uint16_t)cr.code}; - auto d = db.prepare(2); - boost::asio::buffer_copy(d, - boost::asio::buffer(b)); + auto mb = db.prepare(2); + boost::asio::buffer_copy(mb, + boost::asio::buffer(tmp)); if(fh.mask) - detail::mask_inplace(d, key); + detail::mask_inplace(mb, key); db.commit(2); } if(! cr.reason.empty()) { - auto d = db.prepare(cr.reason.size()); - boost::asio::buffer_copy(d, + auto mb = db.prepare(cr.reason.size()); + boost::asio::buffer_copy(mb, boost::asio::const_buffer( cr.reason.data(), cr.reason.size())); if(fh.mask) - detail::mask_inplace(d, key); + detail::mask_inplace(mb, key); db.commit(cr.reason.size()); } } @@ -535,12 +535,12 @@ write_ping(DynamicBuffer& db, detail::prepared_key key; if(fh.mask) detail::prepare_key(key, fh.key); - auto d = db.prepare(data.size()); - boost::asio::buffer_copy(d, + auto mb = db.prepare(data.size()); + boost::asio::buffer_copy(mb, boost::asio::const_buffers_1( data.data(), data.size())); if(fh.mask) - detail::mask_inplace(d, key); + detail::mask_inplace(mb, key); db.commit(data.size()); } diff --git a/include/boost/beast/websocket/stream.hpp b/include/boost/beast/websocket/stream.hpp index fb693063..63639c8e 100644 --- a/include/boost/beast/websocket/stream.hpp +++ b/include/boost/beast/websocket/stream.hpp @@ -3766,11 +3766,11 @@ private: template void - write_close(DynamicBuffer& db, close_reason const& rc); + write_close(DynamicBuffer& b, close_reason const& rc); template void - write_ping(DynamicBuffer& db, + write_ping(DynamicBuffer& b, detail::opcode op, ping_data const& data); template