diff options
Diffstat (limited to 'boost/beast/http/impl')
-rw-r--r-- | boost/beast/http/impl/basic_parser.ipp | 3 | ||||
-rw-r--r-- | boost/beast/http/impl/fields.ipp | 7 | ||||
-rw-r--r-- | boost/beast/http/impl/file_body_win32.ipp | 4 | ||||
-rw-r--r-- | boost/beast/http/impl/parser.ipp | 82 | ||||
-rw-r--r-- | boost/beast/http/impl/read.ipp | 22 | ||||
-rw-r--r-- | boost/beast/http/impl/serializer.ipp | 24 | ||||
-rw-r--r-- | boost/beast/http/impl/verb.ipp | 4 | ||||
-rw-r--r-- | boost/beast/http/impl/write.ipp | 179 |
8 files changed, 167 insertions, 158 deletions
diff --git a/boost/beast/http/impl/basic_parser.ipp b/boost/beast/http/impl/basic_parser.ipp index 39ad3cc68e..7a46092861 100644 --- a/boost/beast/http/impl/basic_parser.ipp +++ b/boost/beast/http/impl/basic_parser.ipp @@ -132,8 +132,7 @@ put(boost::asio::const_buffer const& buffer, { BOOST_ASSERT(state_ != state::complete); using boost::asio::buffer_size; - auto p = reinterpret_cast< - char const*>(buffer.data()); + auto p = static_cast<char const*>(buffer.data()); auto n = buffer.size(); auto const p0 = p; auto const p1 = p0 + n; diff --git a/boost/beast/http/impl/fields.ipp b/boost/beast/http/impl/fields.ipp index a07fd0fa30..aca61d2f65 100644 --- a/boost/beast/http/impl/fields.ipp +++ b/boost/beast/http/impl/fields.ipp @@ -18,6 +18,7 @@ #include <boost/beast/http/rfc7230.hpp> #include <boost/beast/http/status.hpp> #include <boost/beast/http/chunk_encode.hpp> +#include <boost/core/exchange.hpp> #include <boost/throw_exception.hpp> #include <stdexcept> #include <string> @@ -363,11 +364,9 @@ basic_fields(basic_fields&& other) noexcept std::move(other.member())) , set_(std::move(other.set_)) , list_(std::move(other.list_)) - , method_(other.method_) - , target_or_reason_(other.target_or_reason_) + , method_(boost::exchange(other.method_, {})) + , target_or_reason_(boost::exchange(other.target_or_reason_, {})) { - other.method_ = {}; - other.target_or_reason_ = {}; } template<class Allocator> diff --git a/boost/beast/http/impl/file_body_win32.ipp b/boost/beast/http/impl/file_body_win32.ipp index 627401f531..6357cf4983 100644 --- a/boost/beast/http/impl/file_body_win32.ipp +++ b/boost/beast/http/impl/file_body_win32.ipp @@ -20,6 +20,7 @@ #include <boost/asio/associated_executor.hpp> #include <boost/asio/async_result.hpp> #include <boost/asio/basic_stream_socket.hpp> +#include <boost/asio/executor_work_guard.hpp> #include <boost/asio/handler_continuation_hook.hpp> #include <boost/asio/handler_invoke_hook.hpp> #include <boost/asio/windows/overlapped_ptr.hpp> @@ -337,6 +338,8 @@ template< class write_some_win32_op { boost::asio::basic_stream_socket<Protocol>& sock_; + boost::asio::executor_work_guard<decltype(std::declval< + boost::asio::basic_stream_socket<Protocol>&>().get_executor())> wg_; serializer<isRequest, basic_file_body<file_win32>, Fields>& sr_; std::size_t bytes_transferred_ = 0; @@ -354,6 +357,7 @@ public: serializer<isRequest, basic_file_body<file_win32>,Fields>& sr) : sock_(s) + , wg_(sock_.get_executor()) , sr_(sr) , h_(std::forward<DeducedHandler>(h)) { diff --git a/boost/beast/http/impl/parser.ipp b/boost/beast/http/impl/parser.ipp index 8a6cab30af..45bef1c6ac 100644 --- a/boost/beast/http/impl/parser.ipp +++ b/boost/beast/http/impl/parser.ipp @@ -20,25 +20,6 @@ namespace http { template<bool isRequest, class Body, class Allocator> parser<isRequest, Body, Allocator>:: parser() - : parser{detail::has_deprecated_body_reader<Body>{}} -{ -} - -template<bool isRequest, class Body, class Allocator> -parser<isRequest, Body, Allocator>:: -parser(std::true_type) - : rd_(m_) -{ -#ifndef BOOST_BEAST_ALLOW_DEPRECATED - // Deprecated BodyReader Concept (v1.66) - static_assert(sizeof(Body) == 0, - BOOST_BEAST_DEPRECATION_STRING); -#endif -} - -template<bool isRequest, class Body, class Allocator> -parser<isRequest, Body, Allocator>:: -parser(std::false_type) : rd_(m_.base(), m_.body()) { } @@ -47,37 +28,8 @@ template<bool isRequest, class Body, class Allocator> template<class Arg1, class... ArgN, class> parser<isRequest, Body, Allocator>:: parser(Arg1&& arg1, ArgN&&... argn) - : parser(std::forward<Arg1>(arg1), - detail::has_deprecated_body_reader<Body>{}, - std::forward<ArgN>(argn)...) -{ -} - -// VFALCO arg1 comes before `true_type` to make -// the signature unambiguous. -template<bool isRequest, class Body, class Allocator> -template<class Arg1, class... ArgN, class> -parser<isRequest, Body, Allocator>:: -parser(Arg1&& arg1, std::true_type, ArgN&&... argn) - : m_(std::forward<Arg1>(arg1), - std::forward<ArgN>(argn)...) - , rd_(m_) -{ - m_.clear(); -#ifndef BOOST_BEAST_ALLOW_DEPRECATED - /* Deprecated BodyWriter Concept (v1.66) */ - static_assert(sizeof(Body) == 0, - BOOST_BEAST_DEPRECATION_STRING); -#endif // BOOST_BEAST_ALLOW_DEPRECATED -} - -// VFALCO arg1 comes before `false_type` to make -// the signature unambiguous. -template<bool isRequest, class Body, class Allocator> -template<class Arg1, class... ArgN, class> -parser<isRequest, Body, Allocator>:: -parser(Arg1&& arg1, std::false_type, ArgN&&... argn) - : m_(std::forward<Arg1>(arg1), + : m_( + std::forward<Arg1>(arg1), std::forward<ArgN>(argn)...) , rd_(m_.base(), m_.body()) { @@ -90,36 +42,6 @@ parser<isRequest, Body, Allocator>:: parser( parser<isRequest, OtherBody, Allocator>&& other, Args&&... args) - : parser(detail::has_deprecated_body_reader<Body>{}, - std::move(other), std::forward<Args>(args)...) -{ -} - -template<bool isRequest, class Body, class Allocator> -template<class OtherBody, class... Args, class> -parser<isRequest, Body, Allocator>:: -parser(std::true_type, - parser<isRequest, OtherBody, Allocator>&& other, - Args&&... args) - : base_type(std::move(other)) - , m_(other.release(), std::forward<Args>(args)...) - , rd_(m_) -{ - if(other.rd_inited_) - BOOST_THROW_EXCEPTION(std::invalid_argument{ - "moved-from parser has a body"}); -#ifndef BOOST_BEAST_ALLOW_DEPRECATED - // Deprecated BodyReader Concept (v1.66) - static_assert(sizeof(Body) == 0, - BOOST_BEAST_DEPRECATION_STRING); -#endif -} - -template<bool isRequest, class Body, class Allocator> -template<class OtherBody, class... Args, class> -parser<isRequest, Body, Allocator>:: -parser(std::false_type, parser<isRequest, OtherBody, Allocator>&& other, - Args&&... args) : base_type(std::move(other)) , m_(other.release(), std::forward<Args>(args)...) , rd_(m_.base(), m_.body()) diff --git a/boost/beast/http/impl/read.ipp b/boost/beast/http/impl/read.ipp index 28ff0a3c44..2ff0c3b128 100644 --- a/boost/beast/http/impl/read.ipp +++ b/boost/beast/http/impl/read.ipp @@ -21,6 +21,7 @@ #include <boost/asio/associated_allocator.hpp> #include <boost/asio/associated_executor.hpp> #include <boost/asio/coroutine.hpp> +#include <boost/asio/executor_work_guard.hpp> #include <boost/asio/handler_continuation_hook.hpp> #include <boost/asio/handler_invoke_hook.hpp> #include <boost/asio/post.hpp> @@ -43,6 +44,8 @@ class read_some_op : public boost::asio::coroutine { Stream& s_; + boost::asio::executor_work_guard<decltype( + std::declval<Stream&>().get_executor())> wg_; DynamicBuffer& b_; basic_parser<isRequest, Derived>& p_; std::size_t bytes_transferred_ = 0; @@ -57,6 +60,7 @@ public: read_some_op(DeducedHandler&& h, Stream& s, DynamicBuffer& b, basic_parser<isRequest, Derived>& p) : s_(s) + , wg_(s_.get_executor()) , b_(b) , p_(p) , h_(std::forward<DeducedHandler>(h)) @@ -170,10 +174,13 @@ operator()( upcall: if(! cont_) - return boost::asio::post( + { + BOOST_ASIO_CORO_YIELD + boost::asio::post( s_.get_executor(), - bind_handler(std::move(h_), + bind_handler(std::move(*this), ec, bytes_transferred_)); + } h_(ec, bytes_transferred_); } } @@ -209,6 +216,8 @@ class read_op : public boost::asio::coroutine { Stream& s_; + boost::asio::executor_work_guard<decltype( + std::declval<Stream&>().get_executor())> wg_; DynamicBuffer& b_; basic_parser<isRequest, Derived>& p_; std::size_t bytes_transferred_ = 0; @@ -224,6 +233,7 @@ public: DynamicBuffer& b, basic_parser<isRequest, Derived>& p) : s_(s) + , wg_(s_.get_executor()) , b_(b) , p_(p) , h_(std::forward<DeducedHandler>(h)) @@ -327,6 +337,8 @@ class read_msg_op struct data { Stream& s; + boost::asio::executor_work_guard<decltype( + std::declval<Stream&>().get_executor())> wg; DynamicBuffer& b; message_type& m; parser_type p; @@ -336,6 +348,7 @@ class read_msg_op data(Handler const&, Stream& s_, DynamicBuffer& b_, message_type& m_) : s(s_) + , wg(s.get_executor()) , b(b_) , m(m_) , p(std::move(m)) @@ -432,7 +445,10 @@ operator()( } upcall: bytes_transferred = d.bytes_transferred; - d_.invoke(ec, bytes_transferred); + { + auto wg = std::move(d.wg); + d_.invoke(ec, bytes_transferred); + } } } diff --git a/boost/beast/http/impl/serializer.ipp b/boost/beast/http/impl/serializer.ipp index b37856567f..b9e7d26bdb 100644 --- a/boost/beast/http/impl/serializer.ipp +++ b/boost/beast/http/impl/serializer.ipp @@ -57,21 +57,7 @@ do_visit(error_code& ec, Visit& visit) template< bool isRequest, class Body, class Fields> serializer<isRequest, Body, Fields>:: -serializer(value_type& m, std::true_type) - : m_(m) - , wr_(m_) -{ -#ifndef BOOST_BEAST_ALLOW_DEPRECATED - // Deprecated BodyWriter Concept (v1.66) - static_assert(sizeof(Body) == 0, - BOOST_BEAST_DEPRECATION_STRING); -#endif -} - -template< - bool isRequest, class Body, class Fields> -serializer<isRequest, Body, Fields>:: -serializer(value_type& m, std::false_type) +serializer(value_type& m) : m_(m) , wr_(m_.base(), m_.body()) { @@ -79,14 +65,6 @@ serializer(value_type& m, std::false_type) template< bool isRequest, class Body, class Fields> -serializer<isRequest, Body, Fields>:: -serializer(value_type& m) - : serializer(m, detail::has_deprecated_body_writer<Body>{}) -{ -} - -template< - bool isRequest, class Body, class Fields> template<class Visit> void serializer<isRequest, Body, Fields>:: diff --git a/boost/beast/http/impl/verb.ipp b/boost/beast/http/impl/verb.ipp index 8f8b2e33bf..bfd703d05e 100644 --- a/boost/beast/http/impl/verb.ipp +++ b/boost/beast/http/impl/verb.ipp @@ -72,10 +72,6 @@ verb_to_string(verb v) } BOOST_THROW_EXCEPTION(std::invalid_argument{"unknown verb"}); - - // Help some compilers which don't know the next line is - // unreachable, otherwise spurious warnings are generated. - return "<unknown>"; } template<class = void> diff --git a/boost/beast/http/impl/write.ipp b/boost/beast/http/impl/write.ipp index af31cd9be9..bbada07024 100644 --- a/boost/beast/http/impl/write.ipp +++ b/boost/beast/http/impl/write.ipp @@ -18,6 +18,8 @@ #include <boost/beast/core/detail/config.hpp> #include <boost/asio/associated_allocator.hpp> #include <boost/asio/associated_executor.hpp> +#include <boost/asio/coroutine.hpp> +#include <boost/asio/executor_work_guard.hpp> #include <boost/asio/handler_continuation_hook.hpp> #include <boost/asio/handler_invoke_hook.hpp> #include <boost/asio/post.hpp> @@ -38,6 +40,8 @@ template< class write_some_op { Stream& s_; + boost::asio::executor_work_guard<decltype( + std::declval<Stream&>().get_executor())> wg_; serializer<isRequest,Body, Fields>& sr_; Handler h_; @@ -74,6 +78,7 @@ public: write_some_op(DeducedHandler&& h, Stream& s, serializer<isRequest, Body, Fields>& sr) : s_(s) + , wg_(s_.get_executor()) , sr_(sr) , h_(std::forward<DeducedHandler>(h)) { @@ -202,13 +207,15 @@ struct serializer_is_done template< class Stream, class Handler, class Predicate, bool isRequest, class Body, class Fields> -class write_op +class write_op : public boost::asio::coroutine { - int state_ = 0; Stream& s_; + boost::asio::executor_work_guard<decltype( + std::declval<Stream&>().get_executor())> wg_; serializer<isRequest, Body, Fields>& sr_; std::size_t bytes_transferred_ = 0; Handler h_; + bool cont_; public: write_op(write_op&&) = default; @@ -218,8 +225,15 @@ public: write_op(DeducedHandler&& h, Stream& s, serializer<isRequest, Body, Fields>& sr) : s_(s) + , wg_(s_.get_executor()) , sr_(sr) , h_(std::forward<DeducedHandler>(h)) + , cont_([&] + { + using boost::asio::asio_handler_is_continuation; + return asio_handler_is_continuation( + std::addressof(h_)); + }()) { } @@ -250,10 +264,7 @@ public: friend bool asio_handler_is_continuation(write_op* op) { - using boost::asio::asio_handler_is_continuation; - return op->state_ >= 3 || - asio_handler_is_continuation( - std::addressof(op->h_)); + return op->cont_; } template<class Function> @@ -272,44 +283,34 @@ void write_op<Stream, Handler, Predicate, isRequest, Body, Fields>:: operator()( - error_code ec, std::size_t bytes_transferred) + error_code ec, + std::size_t bytes_transferred) { - if(ec) - goto upcall; - switch(state_) - { - case 0: + BOOST_ASIO_CORO_REENTER(*this) { if(Predicate{}(sr_)) { - state_ = 1; - return boost::asio::post( + BOOST_ASIO_CORO_YIELD + boost::asio::post( s_.get_executor(), - bind_handler(std::move(*this), ec, 0)); - } - state_ = 2; - return beast::http::async_write_some( - s_, sr_, std::move(*this)); - } - - case 1: - goto upcall; - - case 2: - state_ = 3; - BOOST_FALLTHROUGH; - - case 3: - { - bytes_transferred_ += bytes_transferred; - if(Predicate{}(sr_)) + bind_handler(std::move(*this))); goto upcall; - return beast::http::async_write_some( - s_, sr_, std::move(*this)); - } + } + for(;;) + { + BOOST_ASIO_CORO_YIELD + beast::http::async_write_some( + s_, sr_, std::move(*this)); + bytes_transferred_ += bytes_transferred; + if(ec) + goto upcall; + if(Predicate{}(sr_)) + break; + cont_ = true; + } + upcall: + h_(ec, bytes_transferred_); } -upcall: - h_(ec, bytes_transferred_); } //------------------------------------------------------------------------------ @@ -321,11 +322,22 @@ class write_msg_op struct data { Stream& s; + boost::asio::executor_work_guard<decltype( + std::declval<Stream&>().get_executor())> wg; serializer<isRequest, Body, Fields> sr; data(Handler const&, Stream& s_, message< isRequest, Body, Fields>& m_) : s(s_) + , wg(s.get_executor()) + , sr(m_) + { + } + + data(Handler const&, Stream& s_, message< + isRequest, Body, Fields> const& m_) + : s(s_) + , wg(s.get_executor()) , sr(m_) { } @@ -405,6 +417,7 @@ write_msg_op< Stream, Handler, isRequest, Body, Fields>:: operator()(error_code ec, std::size_t bytes_transferred) { + auto wg = std::move(d_->wg); d_.invoke(ec, bytes_transferred); } @@ -746,7 +759,33 @@ async_write( template< class SyncWriteStream, bool isRequest, class Body, class Fields> -std::size_t +typename std::enable_if< + is_mutable_body_writer<Body>::value, + std::size_t>::type +write( + SyncWriteStream& stream, + message<isRequest, Body, Fields>& msg) +{ + static_assert(is_sync_write_stream<SyncWriteStream>::value, + "SyncWriteStream requirements not met"); + static_assert(is_body<Body>::value, + "Body requirements not met"); + static_assert(is_body_writer<Body>::value, + "BodyWriter requirements not met"); + error_code ec; + auto const bytes_transferred = + write(stream, msg, ec); + if(ec) + BOOST_THROW_EXCEPTION(system_error{ec}); + return bytes_transferred; +} + +template< + class SyncWriteStream, + bool isRequest, class Body, class Fields> +typename std::enable_if< + ! is_mutable_body_writer<Body>::value, + std::size_t>::type write( SyncWriteStream& stream, message<isRequest, Body, Fields> const& msg) @@ -768,7 +807,30 @@ write( template< class SyncWriteStream, bool isRequest, class Body, class Fields> -std::size_t +typename std::enable_if< + is_mutable_body_writer<Body>::value, + std::size_t>::type +write( + SyncWriteStream& stream, + message<isRequest, Body, Fields>& msg, + error_code& ec) +{ + static_assert(is_sync_write_stream<SyncWriteStream>::value, + "SyncWriteStream requirements not met"); + static_assert(is_body<Body>::value, + "Body requirements not met"); + static_assert(is_body_writer<Body>::value, + "BodyWriter requirements not met"); + serializer<isRequest, Body, Fields> sr{msg}; + return write(stream, sr, ec); +} + +template< + class SyncWriteStream, + bool isRequest, class Body, class Fields> +typename std::enable_if< + ! is_mutable_body_writer<Body>::value, + std::size_t>::type write( SyncWriteStream& stream, message<isRequest, Body, Fields> const& msg, @@ -788,8 +850,10 @@ template< class AsyncWriteStream, bool isRequest, class Body, class Fields, class WriteHandler> -BOOST_ASIO_INITFN_RESULT_TYPE( - WriteHandler, void(error_code, std::size_t)) +typename std::enable_if< + is_mutable_body_writer<Body>::value, + BOOST_ASIO_INITFN_RESULT_TYPE( + WriteHandler, void(error_code, std::size_t))>::type async_write( AsyncWriteStream& stream, message<isRequest, Body, Fields>& msg, @@ -813,6 +877,37 @@ async_write( return init.result.get(); } +template< + class AsyncWriteStream, + bool isRequest, class Body, class Fields, + class WriteHandler> +typename std::enable_if< + ! is_mutable_body_writer<Body>::value, + BOOST_ASIO_INITFN_RESULT_TYPE( + WriteHandler, void(error_code, std::size_t))>::type +async_write( + AsyncWriteStream& stream, + message<isRequest, Body, Fields> const& msg, + WriteHandler&& handler) +{ + static_assert( + is_async_write_stream<AsyncWriteStream>::value, + "AsyncWriteStream requirements not met"); + static_assert(is_body<Body>::value, + "Body requirements not met"); + static_assert(is_body_writer<Body>::value, + "BodyWriter requirements not met"); + BOOST_BEAST_HANDLER_INIT( + WriteHandler, void(error_code, std::size_t)); + detail::write_msg_op< + AsyncWriteStream, + BOOST_ASIO_HANDLER_TYPE(WriteHandler, + void(error_code, std::size_t)), + isRequest, Body, Fields>{ + std::move(init.completion_handler), stream, msg}(); + return init.result.get(); +} + //------------------------------------------------------------------------------ namespace detail { @@ -842,7 +937,7 @@ public: std::size_t bytes_transferred = 0; for(auto b : buffers_range(buffers)) { - os_.write(reinterpret_cast<char const*>( + os_.write(static_cast<char const*>( b.data()), b.size()); if(os_.fail()) return; |