Fix websocket read of zero length message

fix #686
This commit is contained in:
Vinnie Falco
2017-07-27 17:36:06 -07:00
parent c7b830f37f
commit cbb47a0ffd
3 changed files with 190 additions and 165 deletions

View File

@@ -1,3 +1,9 @@
Version 90:
* Fix websocket read of zero length message
--------------------------------------------------------------------------------
Version 89: Version 89:
* Fix CONTRIBUTING.md links * Fix CONTRIBUTING.md links

View File

@@ -233,7 +233,8 @@ operator()(
// Empty non-final frame // Empty non-final frame
goto go_loop; goto go_loop;
} }
ws_.rd_.done = false; ws_.rd_.done =
ws_.rd_.remain == 0 && ws_.rd_.fh.fin;
break; break;
} }
@@ -436,6 +437,8 @@ operator()(
case do_maybe_fill: case do_maybe_fill:
if(ec) if(ec)
break; break;
if(ws_.rd_.done)
break;
dispatched_ = true; dispatched_ = true;
go_maybe_fill: go_maybe_fill:
@@ -495,6 +498,8 @@ operator()(
} }
// Read into caller's buffer // Read into caller's buffer
step_ = do_read; step_ = do_read;
BOOST_ASSERT(ws_.rd_.remain > 0);
BOOST_ASSERT(buffer_size(cb_) > 0);
return ws_.stream_.async_read_some(buffer_prefix( return ws_.stream_.async_read_some(buffer_prefix(
clamp(ws_.rd_.remain), cb_), std::move(*this)); clamp(ws_.rd_.remain), cb_), std::move(*this));
@@ -526,8 +531,8 @@ operator()(
} }
go_done: go_done:
if(ws_.rd_.remain == 0 && ws_.rd_.fh.fin) ws_.rd_.done =
ws_.rd_.done = true; ws_.rd_.remain == 0 && ws_.rd_.fh.fin;
break; break;
case do_inflate: case do_inflate:
@@ -1087,12 +1092,14 @@ loop:
// Empty non-final frame // Empty non-final frame
goto loop; goto loop;
} }
rd_.done = false; rd_.done = rd_.remain == 0 && rd_.fh.fin;
} }
else else
{ {
ec.assign(0, ec.category()); ec.assign(0, ec.category());
} }
if( ! rd_.done)
{
if(! pmd_ || ! pmd_->rd_set) if(! pmd_ || ! pmd_->rd_set)
{ {
if(rd_.buf.size() == 0 && rd_.buf.max_size() > if(rd_.buf.size() == 0 && rd_.buf.max_size() >
@@ -1140,6 +1147,8 @@ loop:
else else
{ {
// Read into caller's buffer // Read into caller's buffer
BOOST_ASSERT(rd_.remain > 0);
BOOST_ASSERT(buffer_size(buffers) > 0);
auto const bytes_transferred = auto const bytes_transferred =
stream_.read_some(buffer_prefix( stream_.read_some(buffer_prefix(
clamp(rd_.remain), buffers), ec); clamp(rd_.remain), buffers), ec);
@@ -1165,8 +1174,7 @@ loop:
bytes_written += bytes_transferred; bytes_written += bytes_transferred;
rd_.size += bytes_transferred; rd_.size += bytes_transferred;
} }
if(rd_.remain == 0 && rd_.fh.fin) rd_.done = rd_.remain == 0 && rd_.fh.fin;
rd_.done = true;
} }
else else
{ {
@@ -1287,6 +1295,7 @@ loop:
} }
} }
} }
}
return bytes_written; return bytes_written;
do_close: do_close:
if(code != close_code::none) if(code != close_code::none)

View File

@@ -1638,6 +1638,16 @@ public:
} }
c.handshake(ws, "localhost", "/"); c.handshake(ws, "localhost", "/");
// send empty message
ws.text(true);
c.write(ws, boost::asio::null_buffers{});
{
// receive echoed message
multi_buffer db;
c.read(ws, db);
BEAST_EXPECT(ws.got_text());
BEAST_EXPECT(db.size() == 0);
}
// send message // send message
ws.auto_fragment(false); ws.auto_fragment(false);
ws.binary(false); ws.binary(false);