From 5f5507f647b157706f91d5c224a5999a24d0e3a8 Mon Sep 17 00:00:00 2001 From: Mohammad Nejati Date: Mon, 5 Aug 2024 15:41:57 +0000 Subject: [PATCH] Initiating functions no longer perform mutating operations Using `asio::deferred` as a completion token defers the initiation of operations and creates a lazy operation which might even be discarded. We need to move mutating operations to the initiator function objects or the constructor of operation objects, which are guaranteed to run when the deferred operation is launched. --- include/boost/beast/http/impl/write.hpp | 17 ++++++++++------- include/boost/beast/websocket/impl/accept.hpp | 4 +--- .../boost/beast/websocket/impl/handshake.hpp | 3 ++- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/include/boost/beast/http/impl/write.hpp b/include/boost/beast/http/impl/write.hpp index 1e6a132d..36fd9cae 100644 --- a/include/boost/beast/http/impl/write.hpp +++ b/include/boost/beast/http/impl/write.hpp @@ -190,13 +190,15 @@ public: write_op( Handler_&& h, Stream& s, - serializer& sr) + serializer& sr, + bool split) : async_base< Handler, beast::executor_type>( std::forward(h), s.get_executor()) , s_(s) , sr_(sr) { + sr.split(split); (*this)(); } @@ -358,7 +360,8 @@ struct run_write_op operator()( WriteHandler&& h, Predicate const&, - serializer* sr) + serializer* sr, + bool split) { // If you get an error on the following line it means // that your handler does not meet the documented type @@ -374,7 +377,7 @@ struct run_write_op AsyncWriteStream, Predicate, isRequest, Body, Fields>( - std::forward(h), *stream, *sr); + std::forward(h), *stream, *sr, split); } }; @@ -686,14 +689,14 @@ async_write_header( "Body type requirements not met"); static_assert(is_body_writer::value, "BodyWriter type requirements not met"); - sr.split(true); return net::async_initiate< WriteHandler, void(error_code, std::size_t)>( detail::run_write_op{&stream}, handler, detail::serializer_is_header_done{}, - &sr); + &sr, + true); } //------------------------------------------------------------------------------ @@ -758,14 +761,14 @@ async_write( "Body type requirements not met"); static_assert(is_body_writer::value, "BodyWriter type requirements not met"); - sr.split(false); return net::async_initiate< WriteHandler, void(error_code, std::size_t)>( detail::run_write_op{&stream}, handler, detail::serializer_is_done{}, - &sr); + &sr, + false); } //------------------------------------------------------------------------------ diff --git a/include/boost/beast/websocket/impl/accept.hpp b/include/boost/beast/websocket/impl/accept.hpp index 7591713c..0fab245d 100644 --- a/include/boost/beast/websocket/impl/accept.hpp +++ b/include/boost/beast/websocket/impl/accept.hpp @@ -296,6 +296,7 @@ public: , d_(decorator) { auto& impl = *sp; + impl.reset(); error_code ec; auto const mb = beast::detail::dynamic_buffer_prepare( @@ -629,7 +630,6 @@ async_accept( { static_assert(is_async_stream::value, "AsyncStream type requirements not met"); - impl_->reset(); return net::async_initiate< AcceptHandler, void(error_code)>( @@ -661,7 +661,6 @@ async_accept( static_assert(net::is_const_buffer_sequence< ConstBufferSequence>::value, "ConstBufferSequence type requirements not met"); - impl_->reset(); return net::async_initiate< AcceptHandler, void(error_code)>( @@ -683,7 +682,6 @@ async_accept( { static_assert(is_async_stream::value, "AsyncStream type requirements not met"); - impl_->reset(); return net::async_initiate< AcceptHandler, void(error_code)>( diff --git a/include/boost/beast/websocket/impl/handshake.hpp b/include/boost/beast/websocket/impl/handshake.hpp index eb471ed0..f5bfb6c4 100644 --- a/include/boost/beast/websocket/impl/handshake.hpp +++ b/include/boost/beast/websocket/impl/handshake.hpp @@ -80,6 +80,8 @@ public: *this, std::move(req))) { sp->reset(); // VFALCO I don't like this + if(res_p) + res_p->result(http::status::internal_server_error); (*this)({}, 0, false); } @@ -342,7 +344,6 @@ async_handshake( detail::sec_ws_key_type key; auto req = impl_->build_request( key, host, target, &default_decorate_req); - res.result(http::status::internal_server_error); return net::async_initiate< HandshakeHandler, void(error_code)>(