diff --git a/include/boost/beast/websocket/impl/read.hpp b/include/boost/beast/websocket/impl/read.hpp index eae78466..e5c34416 100644 --- a/include/boost/beast/websocket/impl/read.hpp +++ b/include/boost/beast/websocket/impl/read.hpp @@ -662,6 +662,7 @@ public: } impl.change_status(status::closing); + impl.update_timer(this->get_executor()); if(! impl.wr_close) { diff --git a/test/beast/websocket/read1.cpp b/test/beast/websocket/read1.cpp index a46e6d65..0b03e230 100644 --- a/test/beast/websocket/read1.cpp +++ b/test/beast/websocket/read1.cpp @@ -14,6 +14,8 @@ #include #include +#include + namespace boost { namespace beast { namespace websocket { @@ -163,10 +165,46 @@ public: } + void + testIssue2999() + { + net::io_context ioc; + + // Use handshake_timeout for the closing handshake, + // which can occur in websocket::stream::async_read_some. + stream ws1(ioc); + stream ws2(ioc); + test::connect(ws1.next_layer(), ws2.next_layer()); + ws1.async_handshake("test", "/", test::success_handler()); + ws2.async_accept(test::success_handler()); + test::run(ioc); + + flat_buffer b; + ws1.set_option(stream_base::timeout{ + std::chrono::milliseconds(50), + stream_base::none(), + false}); + // add a close frame to the input + ws1.next_layer().append(string_view{ + "\x88\x00", 2}); + ws1.async_read(b, test::fail_handler( + beast::error::timeout)); + // limit the write buffer so that writing + // the close frame will not complete during + // the call to ioc.run_one() + ws1.next_layer().write_size(1); + ioc.run_one(); + ioc.restart(); + std::this_thread::sleep_for( + std::chrono::milliseconds(100)); + test::run(ioc); + } + void run() override { testTimeout(); + testIssue2999(); } };