summaryrefslogtreecommitdiff
path: root/boost/beast/http/impl
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:12:59 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:12:59 +0900
commitb8cf34c691623e4ec329053cbbf68522a855882d (patch)
tree34da08632a99677f6b79ecb65e5b655a5b69a67f /boost/beast/http/impl
parent3fdc3e5ee96dca5b11d1694975a65200787eab86 (diff)
downloadboost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.gz
boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.bz2
boost-b8cf34c691623e4ec329053cbbf68522a855882d.zip
Imported Upstream version 1.67.0upstream/1.67.0
Diffstat (limited to 'boost/beast/http/impl')
-rw-r--r--boost/beast/http/impl/basic_parser.ipp10
-rw-r--r--boost/beast/http/impl/field.ipp3
-rw-r--r--boost/beast/http/impl/fields.ipp143
-rw-r--r--boost/beast/http/impl/file_body_win32.ipp79
-rw-r--r--boost/beast/http/impl/parser.ipp88
-rw-r--r--boost/beast/http/impl/read.ipp307
-rw-r--r--boost/beast/http/impl/serializer.ipp88
-rw-r--r--boost/beast/http/impl/status.ipp8
-rw-r--r--boost/beast/http/impl/verb.ipp10
-rw-r--r--boost/beast/http/impl/write.ipp83
10 files changed, 495 insertions, 324 deletions
diff --git a/boost/beast/http/impl/basic_parser.ipp b/boost/beast/http/impl/basic_parser.ipp
index 355a76fb16..39ad3cc68e 100644
--- a/boost/beast/http/impl/basic_parser.ipp
+++ b/boost/beast/http/impl/basic_parser.ipp
@@ -148,7 +148,7 @@ loop:
return 0;
}
state_ = state::start_line;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case state::start_line:
{
@@ -179,7 +179,7 @@ loop:
ec = error::need_more;
goto done;
}
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
}
case state::fields:
@@ -212,7 +212,7 @@ loop:
if(ec)
goto done;
state_ = state::body;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case state::body:
BOOST_ASSERT(! skip_);
@@ -227,7 +227,7 @@ loop:
if(ec)
goto done;
state_ = state::body_to_eof;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case state::body_to_eof:
BOOST_ASSERT(! skip_);
@@ -241,7 +241,7 @@ loop:
if(ec)
goto done;
state_ = state::chunk_header;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case state::chunk_header:
parse_chunk_header(p, n, ec);
diff --git a/boost/beast/http/impl/field.ipp b/boost/beast/http/impl/field.ipp
index 8da470ff24..467a40aeee 100644
--- a/boost/beast/http/impl/field.ipp
+++ b/boost/beast/http/impl/field.ipp
@@ -26,7 +26,7 @@ namespace detail {
struct field_table
{
using array_type =
- std::array<string_view, 352>;
+ std::array<string_view, 353>;
struct hash
{
@@ -104,6 +104,7 @@ struct field_table
"Access-Control-Allow-Headers",
"Access-Control-Allow-Methods",
"Access-Control-Allow-Origin",
+ "Access-Control-Expose-Headers",
"Access-Control-Max-Age",
"Access-Control-Request-Headers",
"Access-Control-Request-Method",
diff --git a/boost/beast/http/impl/fields.ipp b/boost/beast/http/impl/fields.ipp
index 67d7cc45b4..a07fd0fa30 100644
--- a/boost/beast/http/impl/fields.ipp
+++ b/boost/beast/http/impl/fields.ipp
@@ -272,8 +272,10 @@ writer(basic_fields const& f,
template<class Allocator>
basic_fields<Allocator>::
value_type::
-value_type(field name,
- string_view sname, string_view value)
+value_type(
+ field name,
+ string_view sname,
+ string_view value)
: off_(static_cast<off_t>(sname.size() + 2))
, len_(static_cast<off_t>(value.size()))
, f_(name)
@@ -285,13 +287,13 @@ value_type(field name,
p[off_-1] = ' ';
p[off_ + len_] = '\r';
p[off_ + len_ + 1] = '\n';
- std::memcpy(p, sname.data(), sname.size());
- std::memcpy(p + off_, value.data(), value.size());
+ sname.copy(p, sname.size());
+ value.copy(p + off_, value.size());
}
template<class Allocator>
inline
-field const
+field
basic_fields<Allocator>::
value_type::
name() const
@@ -349,30 +351,31 @@ basic_fields<Allocator>::
template<class Allocator>
basic_fields<Allocator>::
-basic_fields(Allocator const& alloc)
- : alloc_(alloc)
+basic_fields(Allocator const& alloc) noexcept
+ : beast::detail::empty_base_optimization<Allocator>(alloc)
{
}
template<class Allocator>
basic_fields<Allocator>::
-basic_fields(basic_fields&& other)
- : alloc_(std::move(other.alloc_))
+basic_fields(basic_fields&& other) noexcept
+ : beast::detail::empty_base_optimization<Allocator>(
+ std::move(other.member()))
, set_(std::move(other.set_))
, list_(std::move(other.list_))
, method_(other.method_)
, target_or_reason_(other.target_or_reason_)
{
- other.method_.clear();
- other.target_or_reason_.clear();
+ other.method_ = {};
+ other.target_or_reason_ = {};
}
template<class Allocator>
basic_fields<Allocator>::
basic_fields(basic_fields&& other, Allocator const& alloc)
- : alloc_(alloc)
+ : beast::detail::empty_base_optimization<Allocator>(alloc)
{
- if(alloc_ != other.alloc_)
+ if(this->member() != other.member())
{
copy_all(other);
other.clear_all();
@@ -389,8 +392,8 @@ basic_fields(basic_fields&& other, Allocator const& alloc)
template<class Allocator>
basic_fields<Allocator>::
basic_fields(basic_fields const& other)
- : alloc_(alloc_traits::
- select_on_container_copy_construction(other.alloc_))
+ : beast::detail::empty_base_optimization<Allocator>(alloc_traits::
+ select_on_container_copy_construction(other.member()))
{
copy_all(other);
}
@@ -399,7 +402,7 @@ template<class Allocator>
basic_fields<Allocator>::
basic_fields(basic_fields const& other,
Allocator const& alloc)
- : alloc_(alloc)
+ : beast::detail::empty_base_optimization<Allocator>(alloc)
{
copy_all(other);
}
@@ -417,7 +420,7 @@ template<class OtherAlloc>
basic_fields<Allocator>::
basic_fields(basic_fields<OtherAlloc> const& other,
Allocator const& alloc)
- : alloc_(alloc)
+ : beast::detail::empty_base_optimization<Allocator>(alloc)
{
copy_all(other);
}
@@ -425,9 +428,12 @@ basic_fields(basic_fields<OtherAlloc> const& other,
template<class Allocator>
auto
basic_fields<Allocator>::
-operator=(basic_fields&& other) ->
- basic_fields&
+operator=(basic_fields&& other) noexcept(
+ alloc_traits::propagate_on_container_move_assignment::value)
+ -> basic_fields&
{
+ static_assert(is_nothrow_move_assignable<Allocator>::value,
+ "Allocator must be noexcept assignable.");
if(this == &other)
return *this;
move_assign(other, std::integral_constant<bool,
@@ -605,11 +611,11 @@ basic_fields<Allocator>::
erase(const_iterator pos) ->
const_iterator
{
- auto next = pos.iter();
+ auto next = pos;
auto& e = *next++;
set_.erase(e);
- list_.erase(e);
- delete_element(e);
+ list_.erase(pos);
+ delete_element(const_cast<value_type&>(e));
return next;
}
@@ -1014,13 +1020,13 @@ set_chunked_impl(bool value)
// Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437
std::string s;
#else
- using rebind_type =
+ using A =
typename beast::detail::allocator_traits<
Allocator>::template rebind_alloc<char>;
std::basic_string<
char,
std::char_traits<char>,
- rebind_type> s{rebind_type{alloc_}};
+ A> s{A{this->member()}};
#endif
s.reserve(it->value().size() + 9);
s.append(it->value().data(), it->value().size());
@@ -1051,13 +1057,13 @@ set_chunked_impl(bool value)
// Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437
std::string s;
#else
- using rebind_type =
+ using A =
typename beast::detail::allocator_traits<
Allocator>::template rebind_alloc<char>;
std::basic_string<
char,
std::char_traits<char>,
- rebind_type> s{rebind_type{alloc_}};
+ A> s{A{this->member()}};
#endif
s.reserve(it->value().size());
detail::filter_token_list_last(s, it->value(),
@@ -1108,13 +1114,13 @@ set_keep_alive_impl(
// Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437
std::string s;
#else
- using rebind_type =
+ using A =
typename beast::detail::allocator_traits<
Allocator>::template rebind_alloc<char>;
std::basic_string<
char,
std::char_traits<char>,
- rebind_type> s{rebind_type{alloc_}};
+ A> s{A{this->member()}};
#endif
s.reserve(value.size());
detail::keep_alive_impl(
@@ -1148,13 +1154,14 @@ new_element(field name,
static_cast<off_t>(sname.size() + 2);
std::uint16_t const len =
static_cast<off_t>(value.size());
- auto const p = alloc_traits::allocate(alloc_,
- 1 + (off + len + 2 + sizeof(value_type) - 1) /
- sizeof(value_type));
+ auto a = rebind_type{this->member()};
+ auto const p = alloc_traits::allocate(a,
+ (sizeof(value_type) + off + len + 2 + sizeof(align_type) - 1) /
+ sizeof(align_type));
// VFALCO allocator can't call the constructor because its private
- //alloc_traits::construct(alloc_, p, name, sname, value);
+ //alloc_traits::construct(a, p, name, sname, value);
new(p) value_type{name, sname, value};
- return *p;
+ return *reinterpret_cast<value_type*>(p);
}
template<class Allocator>
@@ -1162,10 +1169,14 @@ void
basic_fields<Allocator>::
delete_element(value_type& e)
{
- auto const n = 1 + (e.off_ + e.len_ + 2 +
- sizeof(value_type) - 1) / sizeof(value_type);
- alloc_traits::destroy(alloc_, &e);
- alloc_traits::deallocate(alloc_, &e, n);
+ auto a = rebind_type{this->member()};
+ auto const n =
+ (sizeof(value_type) + e.off_ + e.len_ + 2 + sizeof(align_type) - 1) /
+ sizeof(align_type);
+ //alloc_traits::destroy(a, &e);
+ e.~value_type();
+ alloc_traits::deallocate(a,
+ reinterpret_cast<align_type*>(&e), n);
}
template<class Allocator>
@@ -1207,19 +1218,20 @@ realloc_string(string_view& dest, string_view s)
return;
auto a = typename beast::detail::allocator_traits<
Allocator>::template rebind_alloc<
- char>(alloc_);
- if(! dest.empty())
+ char>(this->member());
+ char* p = nullptr;
+ if(! s.empty())
{
+ p = a.allocate(s.size());
+ s.copy(p, s.size());
+ }
+ if(! dest.empty())
a.deallocate(const_cast<char*>(
dest.data()), dest.size());
- dest.clear();
- }
- if(! s.empty())
- {
- auto const p = a.allocate(s.size());
- std::memcpy(p, s.data(), s.size());
+ if(p)
dest = {p, s.size()};
- }
+ else
+ dest = {};
}
template<class Allocator>
@@ -1235,20 +1247,21 @@ realloc_target(
return;
auto a = typename beast::detail::allocator_traits<
Allocator>::template rebind_alloc<
- char>(alloc_);
- if(! dest.empty())
- {
- a.deallocate(const_cast<char*>(
- dest.data()), dest.size());
- dest.clear();
- }
+ char>(this->member());
+ char* p = nullptr;
if(! s.empty())
{
- auto const p = a.allocate(1 + s.size());
+ p = a.allocate(1 + s.size());
p[0] = ' ';
- std::memcpy(p + 1, s.data(), s.size());
- dest = {p, 1 + s.size()};
+ s.copy(p + 1, s.size());
}
+ if(! dest.empty())
+ a.deallocate(const_cast<char*>(
+ dest.data()), dest.size());
+ if(p)
+ dest = {p, 1 + s.size()};
+ else
+ dest = {};
}
template<class Allocator>
@@ -1296,9 +1309,9 @@ move_assign(basic_fields& other, std::true_type)
list_ = std::move(other.list_);
method_ = other.method_;
target_or_reason_ = other.target_or_reason_;
- other.method_.clear();
- other.target_or_reason_.clear();
- alloc_ = other.alloc_;
+ other.method_ = {};
+ other.target_or_reason_ = {};
+ this->member() = other.member();
}
template<class Allocator>
@@ -1308,7 +1321,7 @@ basic_fields<Allocator>::
move_assign(basic_fields& other, std::false_type)
{
clear_all();
- if(alloc_ != other.alloc_)
+ if(this->member() != other.member())
{
copy_all(other);
other.clear_all();
@@ -1319,8 +1332,8 @@ move_assign(basic_fields& other, std::false_type)
list_ = std::move(other.list_);
method_ = other.method_;
target_or_reason_ = other.target_or_reason_;
- other.method_.clear();
- other.target_or_reason_.clear();
+ other.method_ = {};
+ other.target_or_reason_ = {};
}
}
@@ -1331,7 +1344,7 @@ basic_fields<Allocator>::
copy_assign(basic_fields const& other, std::true_type)
{
clear_all();
- alloc_ = other.alloc_;
+ this->member() = other.member();
copy_all(other);
}
@@ -1352,7 +1365,7 @@ basic_fields<Allocator>::
swap(basic_fields& other, std::true_type)
{
using std::swap;
- swap(alloc_, other.alloc_);
+ swap(this->member(), other.member());
swap(set_, other.set_);
swap(list_, other.list_);
swap(method_, other.method_);
@@ -1365,7 +1378,7 @@ void
basic_fields<Allocator>::
swap(basic_fields& other, std::false_type)
{
- BOOST_ASSERT(alloc_ == other.alloc_);
+ BOOST_ASSERT(this->member() == other.member());
using std::swap;
swap(set_, other.set_);
swap(list_, other.list_);
diff --git a/boost/beast/http/impl/file_body_win32.ipp b/boost/beast/http/impl/file_body_win32.ipp
index e11c443ed2..627401f531 100644
--- a/boost/beast/http/impl/file_body_win32.ipp
+++ b/boost/beast/http/impl/file_body_win32.ipp
@@ -21,10 +21,12 @@
#include <boost/asio/async_result.hpp>
#include <boost/asio/basic_stream_socket.hpp>
#include <boost/asio/handler_continuation_hook.hpp>
+#include <boost/asio/handler_invoke_hook.hpp>
#include <boost/asio/windows/overlapped_ptr.hpp>
#include <boost/make_unique.hpp>
#include <boost/smart_ptr/make_shared_array.hpp>
#include <boost/winapi/basic_types.hpp>
+#include <boost/winapi/get_last_error.hpp>
#include <algorithm>
#include <cstring>
@@ -123,9 +125,8 @@ struct basic_file_body<file_win32>
boost::asio::const_buffer;
template<bool isRequest, class Fields>
- writer(message<isRequest,
- basic_file_body<file_win32>, Fields>& m)
- : body_(m.body())
+ writer(header<isRequest, Fields>&, value_type& b)
+ : body_(b)
{
}
@@ -167,8 +168,8 @@ struct basic_file_body<file_win32>
public:
template<bool isRequest, class Fields>
explicit
- reader(message<isRequest, basic_file_body, Fields>& m)
- : body_(m.body())
+ reader(header<isRequest, Fields>&, value_type& b)
+ : body_(b)
{
}
@@ -344,7 +345,7 @@ class write_some_win32_op
public:
write_some_win32_op(write_some_win32_op&&) = default;
- write_some_win32_op(write_some_win32_op const&) = default;
+ write_some_win32_op(write_some_win32_op const&) = delete;
template<class DeducedHandler>
write_some_win32_op(
@@ -364,7 +365,7 @@ public:
allocator_type
get_allocator() const noexcept
{
- return boost::asio::get_associated_allocator(h_);
+ return (boost::asio::get_associated_allocator)(h_);
}
using executor_type =
@@ -374,7 +375,7 @@ public:
executor_type
get_executor() const noexcept
{
- return boost::asio::get_associated_executor(
+ return (boost::asio::get_associated_executor)(
h_, sock_.get_executor());
}
@@ -393,6 +394,14 @@ public:
return asio_handler_is_continuation(
std::addressof(op->h_));
}
+
+ template<class Function>
+ friend
+ void asio_handler_invoke(Function&& f, write_some_win32_op* op)
+ {
+ using boost::asio::asio_handler_invoke;
+ asio_handler_invoke(f, std::addressof(op->h_));
+ }
};
template<
@@ -407,25 +416,28 @@ operator()()
{
header_ = true;
sr_.split(true);
- return detail::async_write_some(
+ return detail::async_write_some_impl(
sock_, sr_, std::move(*this));
}
if(sr_.get().chunked())
{
- return detail::async_write_some(
+ return detail::async_write_some_impl(
sock_, sr_, std::move(*this));
}
- auto& r = sr_.reader_impl();
+ auto& w = sr_.writer_impl();
boost::winapi::DWORD_ const nNumberOfBytesToWrite =
static_cast<boost::winapi::DWORD_>(
(std::min<std::uint64_t>)(
- (std::min<std::uint64_t>)(r.body_.last_ - r.pos_, sr_.limit()),
+ (std::min<std::uint64_t>)(w.body_.last_ - w.pos_, sr_.limit()),
(std::numeric_limits<boost::winapi::DWORD_>::max)()));
boost::asio::windows::overlapped_ptr overlapped{
- sock_.get_executor().context(), *this};
+ sock_.get_executor().context(), std::move(*this)};
+ // Note that we have moved *this, so we cannot access
+ // the handler since it is now moved-from. We can still
+ // access simple things like references and built-in types.
auto& ov = *overlapped.get();
- ov.Offset = lowPart(r.pos_);
- ov.OffsetHigh = highPart(r.pos_);
+ ov.Offset = lowPart(w.pos_);
+ ov.OffsetHigh = highPart(w.pos_);
auto const bSuccess = ::TransmitFile(
sock_.native_handle(),
sr_.get().body().file_.native_handle(),
@@ -434,14 +446,13 @@ operator()()
overlapped.get(),
nullptr,
0);
- auto const dwError = ::GetLastError();
+ auto const dwError = boost::winapi::GetLastError();
if(! bSuccess && dwError !=
boost::winapi::ERROR_IO_PENDING_)
{
// VFALCO This needs review, is 0 the right number?
// completed immediately (with error?)
- overlapped.complete(error_code{static_cast<int>(
- boost::winapi::GetLastError()),
+ overlapped.complete(error_code{static_cast<int>(dwError),
system_category()}, 0);
return;
}
@@ -465,10 +476,10 @@ operator()(
header_ = false;
return (*this)();
}
- auto& r = sr_.reader_impl();
- r.pos_ += bytes_transferred;
- BOOST_ASSERT(r.pos_ <= r.body_.last_);
- if(r.pos_ >= r.body_.last_)
+ auto& w = sr_.writer_impl();
+ w.pos_ += bytes_transferred;
+ BOOST_ASSERT(w.pos_ <= w.body_.last_);
+ if(w.pos_ >= w.body_.last_)
{
sr_.next(ec, null_lambda{});
BOOST_ASSERT(! ec);
@@ -496,7 +507,7 @@ write_some(
{
sr.split(true);
auto const bytes_transferred =
- detail::write_some(sock, sr, ec);
+ detail::write_some_impl(sock, sr, ec);
if(ec)
return bytes_transferred;
return bytes_transferred;
@@ -504,23 +515,23 @@ write_some(
if(sr.get().chunked())
{
auto const bytes_transferred =
- detail::write_some(sock, sr, ec);
+ detail::write_some_impl(sock, sr, ec);
if(ec)
return bytes_transferred;
return bytes_transferred;
}
- auto& r = sr.reader_impl();
- r.body_.file_.seek(r.pos_, ec);
+ auto& w = sr.writer_impl();
+ w.body_.file_.seek(w.pos_, ec);
if(ec)
return 0;
boost::winapi::DWORD_ const nNumberOfBytesToWrite =
static_cast<boost::winapi::DWORD_>(
(std::min<std::uint64_t>)(
- (std::min<std::uint64_t>)(r.body_.last_ - r.pos_, sr.limit()),
+ (std::min<std::uint64_t>)(w.body_.last_ - w.pos_, sr.limit()),
(std::numeric_limits<boost::winapi::DWORD_>::max)()));
auto const bSuccess = ::TransmitFile(
sock.native_handle(),
- r.body_.file_.native_handle(),
+ w.body_.file_.native_handle(),
nNumberOfBytesToWrite,
0,
nullptr,
@@ -533,9 +544,9 @@ write_some(
system_category());
return 0;
}
- r.pos_ += nNumberOfBytesToWrite;
- BOOST_ASSERT(r.pos_ <= r.body_.last_);
- if(r.pos_ < r.body_.last_)
+ w.pos_ += nNumberOfBytesToWrite;
+ BOOST_ASSERT(w.pos_ <= w.body_.last_);
+ if(w.pos_ < w.body_.last_)
{
ec.assign(0, ec.category());
}
@@ -562,14 +573,14 @@ async_write_some(
basic_file_body<file_win32>, Fields>& sr,
WriteHandler&& handler)
{
- boost::asio::async_completion<WriteHandler,
- void(error_code)> init{handler};
+ BOOST_BEAST_HANDLER_INIT(
+ WriteHandler, void(error_code, std::size_t));
detail::write_some_win32_op<
Protocol,
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
void(error_code, std::size_t)),
isRequest, Fields>{
- init.completion_handler, sock, sr}();
+ std::move(init.completion_handler), sock, sr}();
return init.result.get();
}
diff --git a/boost/beast/http/impl/parser.ipp b/boost/beast/http/impl/parser.ipp
index 99745da3f0..8a6cab30af 100644
--- a/boost/beast/http/impl/parser.ipp
+++ b/boost/beast/http/impl/parser.ipp
@@ -20,7 +20,26 @@ namespace http {
template<bool isRequest, class Body, class Allocator>
parser<isRequest, Body, Allocator>::
parser()
- : wr_(m_)
+ : 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())
{
}
@@ -28,21 +47,82 @@ 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)...)
- , wr_(m_)
+ , 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),
+ std::forward<ArgN>(argn)...)
+ , rd_(m_.base(), m_.body())
+{
+ m_.clear();
+}
+
+template<bool isRequest, class Body, class Allocator>
+template<class OtherBody, class... Args, class>
+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(parser<isRequest, OtherBody, Allocator>&& other,
+parser(std::false_type, parser<isRequest, OtherBody, Allocator>&& other,
Args&&... args)
: base_type(std::move(other))
, m_(other.release(), std::forward<Args>(args)...)
- , wr_(m_)
+ , rd_(m_.base(), m_.body())
{
if(other.rd_inited_)
BOOST_THROW_EXCEPTION(std::invalid_argument{
diff --git a/boost/beast/http/impl/read.ipp b/boost/beast/http/impl/read.ipp
index 5ecfae7d8b..28ff0a3c44 100644
--- a/boost/beast/http/impl/read.ipp
+++ b/boost/beast/http/impl/read.ipp
@@ -20,7 +20,9 @@
#include <boost/beast/core/type_traits.hpp>
#include <boost/asio/associated_allocator.hpp>
#include <boost/asio/associated_executor.hpp>
+#include <boost/asio/coroutine.hpp>
#include <boost/asio/handler_continuation_hook.hpp>
+#include <boost/asio/handler_invoke_hook.hpp>
#include <boost/asio/post.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
@@ -38,19 +40,18 @@ namespace detail {
template<class Stream, class DynamicBuffer,
bool isRequest, class Derived, class Handler>
class read_some_op
+ : public boost::asio::coroutine
{
- int state_ = 0;
Stream& s_;
DynamicBuffer& b_;
basic_parser<isRequest, Derived>& p_;
- boost::optional<typename
- DynamicBuffer::mutable_buffers_type> mb_;
std::size_t bytes_transferred_ = 0;
Handler h_;
+ bool cont_ = false;
public:
read_some_op(read_some_op&&) = default;
- read_some_op(read_some_op const&) = default;
+ read_some_op(read_some_op const&) = delete;
template<class DeducedHandler>
read_some_op(DeducedHandler&& h, Stream& s,
@@ -68,7 +69,7 @@ public:
allocator_type
get_allocator() const noexcept
{
- return boost::asio::get_associated_allocator(h_);
+ return (boost::asio::get_associated_allocator)(h_);
}
using executor_type = boost::asio::associated_executor_t<
@@ -77,23 +78,32 @@ public:
executor_type
get_executor() const noexcept
{
- return boost::asio::get_associated_executor(
+ return (boost::asio::get_associated_executor)(
h_, s_.get_executor());
}
void
operator()(
- error_code ec = {},
- std::size_t bytes_transferred = 0);
+ error_code ec,
+ std::size_t bytes_transferred = 0,
+ bool cont = true);
friend
bool asio_handler_is_continuation(read_some_op* op)
{
using boost::asio::asio_handler_is_continuation;
- return op->state_ >= 2 ? true :
+ return op->cont_ ? true :
asio_handler_is_continuation(
std::addressof(op->h_));
}
+
+ template<class Function>
+ friend
+ void asio_handler_invoke(Function&& f, read_some_op* op)
+ {
+ using boost::asio::asio_handler_invoke;
+ asio_handler_invoke(f, std::addressof(op->h_));
+ }
};
template<class Stream, class DynamicBuffer,
@@ -103,75 +113,69 @@ read_some_op<Stream, DynamicBuffer,
isRequest, Derived, Handler>::
operator()(
error_code ec,
- std::size_t bytes_transferred)
+ std::size_t bytes_transferred,
+ bool cont)
{
- switch(state_)
+ cont_ = cont;
+ boost::optional<typename
+ DynamicBuffer::mutable_buffers_type> mb;
+ BOOST_ASIO_CORO_REENTER(*this)
{
- case 0:
- state_ = 1;
if(b_.size() == 0)
goto do_read;
- goto do_parse;
-
- case 1:
- state_ = 2;
- case 2:
- if(ec == boost::asio::error::eof)
+ for(;;)
{
- BOOST_ASSERT(bytes_transferred == 0);
- if(p_.got_some())
+ // parse
{
- // caller sees EOF on next read
- ec.assign(0, ec.category());
- p_.put_eof(ec);
- if(ec)
- goto upcall;
- BOOST_ASSERT(p_.is_done());
- goto upcall;
+ auto const used = p_.put(b_.data(), ec);
+ bytes_transferred_ += used;
+ b_.consume(used);
}
- ec = error::end_of_stream;
- goto upcall;
- }
- if(ec)
- goto upcall;
- b_.commit(bytes_transferred);
-
- do_parse:
- {
- auto const used = p_.put(b_.data(), ec);
- bytes_transferred_ += used;
- b_.consume(used);
- if(! ec || ec != http::error::need_more)
- goto do_upcall;
- ec.assign(0, ec.category());
- }
+ if(ec != http::error::need_more)
+ break;
- do_read:
- try
- {
- mb_.emplace(b_.prepare(
- read_size_or_throw(b_, 65536)));
- }
- catch(std::length_error const&)
- {
- ec = error::buffer_overflow;
- goto do_upcall;
+ do_read:
+ try
+ {
+ mb.emplace(b_.prepare(
+ read_size_or_throw(b_, 65536)));
+ }
+ catch(std::length_error const&)
+ {
+ ec = error::buffer_overflow;
+ break;
+ }
+ BOOST_ASIO_CORO_YIELD
+ s_.async_read_some(*mb, std::move(*this));
+ if(ec == boost::asio::error::eof)
+ {
+ BOOST_ASSERT(bytes_transferred == 0);
+ if(p_.got_some())
+ {
+ // caller sees EOF on next read
+ ec.assign(0, ec.category());
+ p_.put_eof(ec);
+ if(ec)
+ goto upcall;
+ BOOST_ASSERT(p_.is_done());
+ goto upcall;
+ }
+ ec = error::end_of_stream;
+ break;
+ }
+ if(ec)
+ break;
+ b_.commit(bytes_transferred);
}
- return s_.async_read_some(*mb_, std::move(*this));
- do_upcall:
- if(state_ >= 2)
- goto upcall;
- state_ = 3;
- return boost::asio::post(
- s_.get_executor(),
- bind_handler(std::move(*this), ec, 0));
-
- case 3:
- break;
+ upcall:
+ if(! cont_)
+ return boost::asio::post(
+ s_.get_executor(),
+ bind_handler(std::move(h_),
+ ec, bytes_transferred_));
+ h_(ec, bytes_transferred_);
}
-upcall:
- h_(ec, bytes_transferred_);
}
//------------------------------------------------------------------------------
@@ -202,17 +206,18 @@ template<class Stream, class DynamicBuffer,
bool isRequest, class Derived, class Condition,
class Handler>
class read_op
+ : public boost::asio::coroutine
{
- int state_ = 0;
Stream& s_;
DynamicBuffer& b_;
basic_parser<isRequest, Derived>& p_;
std::size_t bytes_transferred_ = 0;
Handler h_;
+ bool cont_ = false;
public:
read_op(read_op&&) = default;
- read_op(read_op const&) = default;
+ read_op(read_op const&) = delete;
template<class DeducedHandler>
read_op(DeducedHandler&& h, Stream& s,
@@ -231,7 +236,7 @@ public:
allocator_type
get_allocator() const noexcept
{
- return boost::asio::get_associated_allocator(h_);
+ return (boost::asio::get_associated_allocator)(h_);
}
using executor_type = boost::asio::associated_executor_t<
@@ -240,23 +245,32 @@ public:
executor_type
get_executor() const noexcept
{
- return boost::asio::get_associated_executor(
+ return (boost::asio::get_associated_executor)(
h_, s_.get_executor());
}
void
operator()(
- error_code ec = {},
- std::size_t bytes_transferred = 0);
+ error_code ec,
+ std::size_t bytes_transferred = 0,
+ bool cont = true);
friend
bool asio_handler_is_continuation(read_op* op)
{
using boost::asio::asio_handler_is_continuation;
- return op->state_ >= 3 ? true :
+ return op->cont_ ? true :
asio_handler_is_continuation(
std::addressof(op->h_));
}
+
+ template<class Function>
+ friend
+ void asio_handler_invoke(Function&& f, read_op* op)
+ {
+ using boost::asio::asio_handler_invoke;
+ asio_handler_invoke(f, std::addressof(op->h_));
+ }
};
template<class Stream, class DynamicBuffer,
@@ -267,39 +281,33 @@ read_op<Stream, DynamicBuffer,
isRequest, Derived, Condition, Handler>::
operator()(
error_code ec,
- std::size_t bytes_transferred)
+ std::size_t bytes_transferred,
+ bool cont)
{
- switch(state_)
+ cont_ = cont;
+ BOOST_ASIO_CORO_REENTER(*this)
{
- case 0:
if(Condition{}(p_))
{
- state_ = 1;
- return boost::asio::post(
- s_.get_executor(),
+ BOOST_ASIO_CORO_YIELD
+ boost::asio::post(s_.get_executor(),
bind_handler(std::move(*this), ec));
- }
- state_ = 2;
-
- do_read:
- return async_read_some(
- s_, b_, p_, std::move(*this));
-
- case 1:
- goto upcall;
-
- case 2:
- case 3:
- if(ec)
- goto upcall;
- bytes_transferred_ += bytes_transferred;
- if(Condition{}(p_))
goto upcall;
- state_ = 3;
- goto do_read;
+ }
+ for(;;)
+ {
+ BOOST_ASIO_CORO_YIELD
+ async_read_some(
+ s_, b_, p_, std::move(*this));
+ if(ec)
+ goto upcall;
+ bytes_transferred_ += bytes_transferred;
+ if(Condition{}(p_))
+ goto upcall;
+ }
+ upcall:
+ h_(ec, bytes_transferred_);
}
-upcall:
- h_(ec, bytes_transferred_);
}
//------------------------------------------------------------------------------
@@ -308,6 +316,7 @@ template<class Stream, class DynamicBuffer,
bool isRequest, class Body, class Allocator,
class Handler>
class read_msg_op
+ : public boost::asio::coroutine
{
using parser_type =
parser<isRequest, Body, Allocator>;
@@ -317,14 +326,14 @@ class read_msg_op
struct data
{
- int state = 0;
Stream& s;
DynamicBuffer& b;
message_type& m;
parser_type p;
std::size_t bytes_transferred = 0;
+ bool cont = false;
- data(Handler&, Stream& s_,
+ data(Handler const&, Stream& s_,
DynamicBuffer& b_, message_type& m_)
: s(s_)
, b(b_)
@@ -339,7 +348,7 @@ class read_msg_op
public:
read_msg_op(read_msg_op&&) = default;
- read_msg_op(read_msg_op const&) = default;
+ read_msg_op(read_msg_op const&) = delete;
template<class DeducedHandler, class... Args>
read_msg_op(DeducedHandler&& h, Stream& s, Args&&... args)
@@ -354,7 +363,7 @@ public:
allocator_type
get_allocator() const noexcept
{
- return boost::asio::get_associated_allocator(d_.handler());
+ return (boost::asio::get_associated_allocator)(d_.handler());
}
using executor_type = boost::asio::associated_executor_t<
@@ -363,23 +372,32 @@ public:
executor_type
get_executor() const noexcept
{
- return boost::asio::get_associated_executor(
+ return (boost::asio::get_associated_executor)(
d_.handler(), d_->s.get_executor());
}
void
operator()(
- error_code ec = {},
- std::size_t bytes_transferred = 0);
+ error_code ec,
+ std::size_t bytes_transferred = 0,
+ bool cont = true);
friend
bool asio_handler_is_continuation(read_msg_op* op)
{
using boost::asio::asio_handler_is_continuation;
- return op->d_->state >= 2 ? true :
+ return op->d_->cont ? true :
asio_handler_is_continuation(
std::addressof(op->d_.handler()));
}
+
+ template<class Function>
+ friend
+ void asio_handler_invoke(Function&& f, read_msg_op* op)
+ {
+ using boost::asio::asio_handler_invoke;
+ asio_handler_invoke(f, std::addressof(op->d_.handler()));
+ }
};
template<class Stream, class DynamicBuffer,
@@ -390,35 +408,32 @@ read_msg_op<Stream, DynamicBuffer,
isRequest, Body, Allocator, Handler>::
operator()(
error_code ec,
- std::size_t bytes_transferred)
+ std::size_t bytes_transferred,
+ bool cont)
{
auto& d = *d_;
- switch(d.state)
+ d.cont = cont;
+ BOOST_ASIO_CORO_REENTER(*this)
{
- case 0:
- d.state = 1;
-
- do_read:
- return async_read_some(
- d.s, d.b, d.p, std::move(*this));
-
- case 1:
- case 2:
- if(ec)
- goto upcall;
- d.bytes_transferred +=
- bytes_transferred;
- if(d.p.is_done())
+ for(;;)
{
- d.m = d.p.release();
- goto upcall;
+ BOOST_ASIO_CORO_YIELD
+ async_read_some(
+ d.s, d.b, d.p, std::move(*this));
+ if(ec)
+ goto upcall;
+ d.bytes_transferred +=
+ bytes_transferred;
+ if(d.p.is_done())
+ {
+ d.m = d.p.release();
+ goto upcall;
+ }
}
- d.state = 2;
- goto do_read;
+ upcall:
+ bytes_transferred = d.bytes_transferred;
+ d_.invoke(ec, bytes_transferred);
}
-upcall:
- bytes_transferred = d.bytes_transferred;
- d_.invoke(ec, bytes_transferred);
}
} // detail
@@ -536,12 +551,13 @@ async_read_some(
boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
"DynamicBuffer requirements not met");
BOOST_ASSERT(! parser.is_done());
- boost::asio::async_completion<ReadHandler,
- void(error_code, std::size_t)> init{handler};
+ BOOST_BEAST_HANDLER_INIT(
+ ReadHandler, void(error_code, std::size_t));
detail::read_some_op<AsyncReadStream,
DynamicBuffer, isRequest, Derived, BOOST_ASIO_HANDLER_TYPE(
ReadHandler, void(error_code, std::size_t))>{
- init.completion_handler, stream, buffer, parser}();
+ std::move(init.completion_handler), stream, buffer, parser}(
+ {}, 0, false);
return init.result.get();
}
@@ -623,12 +639,13 @@ async_read_header(
boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
"DynamicBuffer requirements not met");
parser.eager(false);
- boost::asio::async_completion<ReadHandler,
- void(error_code, std::size_t)> init{handler};
+ BOOST_BEAST_HANDLER_INIT(
+ ReadHandler, void(error_code, std::size_t));
detail::read_op<AsyncReadStream, DynamicBuffer,
isRequest, Derived, detail::parser_is_header_done,
BOOST_ASIO_HANDLER_TYPE(ReadHandler, void(error_code, std::size_t))>{
- init.completion_handler, stream, buffer, parser}();
+ std::move(init.completion_handler), stream,
+ buffer, parser}({}, 0, false);
return init.result.get();
}
@@ -710,13 +727,13 @@ async_read(
boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
"DynamicBuffer requirements not met");
parser.eager(true);
- boost::asio::async_completion<
- ReadHandler,
- void(error_code, std::size_t)> init{handler};
+ BOOST_BEAST_HANDLER_INIT(
+ ReadHandler, void(error_code, std::size_t));
detail::read_op<AsyncReadStream, DynamicBuffer,
isRequest, Derived, detail::parser_is_done,
BOOST_ASIO_HANDLER_TYPE(ReadHandler, void(error_code, std::size_t))>{
- init.completion_handler, stream, buffer, parser}();
+ std::move(init.completion_handler), stream, buffer, parser}(
+ {}, 0, false);
return init.result.get();
}
@@ -801,16 +818,16 @@ async_read(
"Body requirements not met");
static_assert(is_body_reader<Body>::value,
"BodyReader requirements not met");
- boost::asio::async_completion<
- ReadHandler,
- void(error_code, std::size_t)> init{handler};
+ BOOST_BEAST_HANDLER_INIT(
+ ReadHandler, void(error_code, std::size_t));
detail::read_msg_op<
AsyncReadStream,
DynamicBuffer,
isRequest, Body, Allocator,
BOOST_ASIO_HANDLER_TYPE(
ReadHandler, void(error_code, std::size_t))>{
- init.completion_handler, stream, buffer, msg}();
+ std::move(init.completion_handler), stream, buffer, msg}(
+ {}, 0, false);
return init.result.get();
}
diff --git a/boost/beast/http/impl/serializer.ipp b/boost/beast/http/impl/serializer.ipp
index 11cf857845..b37856567f 100644
--- a/boost/beast/http/impl/serializer.ipp
+++ b/boost/beast/http/impl/serializer.ipp
@@ -25,18 +25,18 @@ template<
bool isRequest, class Body, class Fields>
void
serializer<isRequest, Body, Fields>::
-frdinit(std::true_type)
+fwrinit(std::true_type)
{
- frd_.emplace(m_, m_.version(), m_.method());
+ fwr_.emplace(m_, m_.version(), m_.method());
}
template<
bool isRequest, class Body, class Fields>
void
serializer<isRequest, Body, Fields>::
-frdinit(std::false_type)
+fwrinit(std::false_type)
{
- frd_.emplace(m_, m_.version(), m_.result_int());
+ fwr_.emplace(m_, m_.version(), m_.result_int());
}
template<
@@ -57,9 +57,31 @@ do_visit(error_code& ec, Visit& visit)
template<
bool isRequest, class Body, class Fields>
serializer<isRequest, Body, Fields>::
-serializer(value_type& m)
+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)
: m_(m)
- , rd_(m_)
+ , wr_(m_.base(), m_.body())
+{
+}
+
+template<
+ bool isRequest, class Body, class Fields>
+serializer<isRequest, Body, Fields>::
+serializer(value_type& m)
+ : serializer(m, detail::has_deprecated_body_writer<Body>{})
{
}
@@ -75,22 +97,22 @@ next(error_code& ec, Visit&& visit)
{
case do_construct:
{
- frdinit(std::integral_constant<bool,
+ fwrinit(std::integral_constant<bool,
isRequest>{});
if(m_.chunked())
goto go_init_c;
s_ = do_init;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
}
case do_init:
{
- rd_.init(ec);
+ wr_.init(ec);
if(ec)
return;
if(split_)
goto go_header_only;
- auto result = rd_.get(ec);
+ auto result = wr_.get(ec);
if(ec == error::need_more)
goto go_header_only;
if(ec)
@@ -100,10 +122,10 @@ next(error_code& ec, Visit&& visit)
more_ = result->second;
v_.template emplace<2>(
boost::in_place_init,
- frd_->get(),
+ fwr_->get(),
result->first);
s_ = do_header;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
}
case do_header:
@@ -111,20 +133,20 @@ next(error_code& ec, Visit&& visit)
break;
go_header_only:
- v_.template emplace<1>(frd_->get());
+ v_.template emplace<1>(fwr_->get());
s_ = do_header_only;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case do_header_only:
do_visit<1>(ec, visit);
break;
case do_body:
s_ = do_body + 1;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case do_body + 1:
{
- auto result = rd_.get(ec);
+ auto result = wr_.get(ec);
if(ec)
return;
if(! result)
@@ -132,7 +154,7 @@ next(error_code& ec, Visit&& visit)
more_ = result->second;
v_.template emplace<3>(result->first);
s_ = do_body + 2;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
}
case do_body + 2:
@@ -143,15 +165,15 @@ next(error_code& ec, Visit&& visit)
go_init_c:
s_ = do_init_c;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case do_init_c:
{
- rd_.init(ec);
+ wr_.init(ec);
if(ec)
return;
if(split_)
goto go_header_only_c;
- auto result = rd_.get(ec);
+ auto result = wr_.get(ec);
if(ec == error::need_more)
goto go_header_only_c;
if(ec)
@@ -164,7 +186,7 @@ next(error_code& ec, Visit&& visit)
// do it all in one buffer
v_.template emplace<7>(
boost::in_place_init,
- frd_->get(),
+ fwr_->get(),
buffer_size(result->first),
boost::asio::const_buffer{nullptr, 0},
chunk_crlf{},
@@ -177,14 +199,14 @@ next(error_code& ec, Visit&& visit)
}
v_.template emplace<4>(
boost::in_place_init,
- frd_->get(),
+ fwr_->get(),
buffer_size(result->first),
boost::asio::const_buffer{nullptr, 0},
chunk_crlf{},
result->first,
chunk_crlf{});
s_ = do_header_c;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
}
case do_header_c:
@@ -192,19 +214,21 @@ next(error_code& ec, Visit&& visit)
break;
go_header_only_c:
- v_.template emplace<1>(frd_->get());
+ v_.template emplace<1>(fwr_->get());
s_ = do_header_only_c;
+ BOOST_FALLTHROUGH;
+
case do_header_only_c:
do_visit<1>(ec, visit);
break;
case do_body_c:
s_ = do_body_c + 1;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case do_body_c + 1:
{
- auto result = rd_.get(ec);
+ auto result = wr_.get(ec);
if(ec)
return;
if(! result)
@@ -233,7 +257,7 @@ next(error_code& ec, Visit&& visit)
result->first,
chunk_crlf{});
s_ = do_body_c + 2;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
}
case do_body_c + 2:
@@ -242,14 +266,14 @@ next(error_code& ec, Visit&& visit)
go_body_final_c:
s_ = do_body_final_c;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case do_body_final_c:
do_visit<6>(ec, visit);
break;
go_all_c:
s_ = do_all_c;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case do_all_c:
do_visit<7>(ec, visit);
break;
@@ -262,7 +286,7 @@ next(error_code& ec, Visit&& visit)
boost::asio::const_buffer{nullptr, 0},
chunk_crlf{});
s_ = do_final_c + 1;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case do_final_c + 1:
do_visit<8>(ec, visit);
@@ -309,7 +333,7 @@ consume(std::size_t n)
v_.template get<1>().consume(n);
if(buffer_size(v_.template get<1>()) > 0)
break;
- frd_ = boost::none;
+ fwr_ = boost::none;
header_done_ = true;
if(! split_)
goto go_complete;
@@ -353,7 +377,7 @@ consume(std::size_t n)
v_.template get<1>().consume(n);
if(buffer_size(v_.template get<1>()) > 0)
break;
- frd_ = boost::none;
+ fwr_ = boost::none;
header_done_ = true;
if(! split_)
{
diff --git a/boost/beast/http/impl/status.ipp b/boost/beast/http/impl/status.ipp
index 1cc8f34b63..7d37919423 100644
--- a/boost/beast/http/impl/status.ipp
+++ b/boost/beast/http/impl/status.ipp
@@ -28,7 +28,7 @@ int_to_status(unsigned v)
case status::continue_:
case status::switching_protocols:
case status::processing:
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
// 2xx
case status::ok:
@@ -41,7 +41,7 @@ int_to_status(unsigned v)
case status::multi_status:
case status::already_reported:
case status::im_used:
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
// 3xx
case status::multiple_choices:
@@ -52,7 +52,7 @@ int_to_status(unsigned v)
case status::use_proxy:
case status::temporary_redirect:
case status::permanent_redirect:
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
// 4xx
case status::bad_request:
@@ -84,7 +84,7 @@ int_to_status(unsigned v)
case status::connection_closed_without_response:
case status::unavailable_for_legal_reasons:
case status::client_closed_request:
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
// 5xx
case status::internal_server_error:
diff --git a/boost/beast/http/impl/verb.ipp b/boost/beast/http/impl/verb.ipp
index 820609165b..8f8b2e33bf 100644
--- a/boost/beast/http/impl/verb.ipp
+++ b/boost/beast/http/impl/verb.ipp
@@ -72,6 +72,10 @@ 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>
@@ -159,7 +163,7 @@ string_to_verb(string_view v)
return verb::connect;
if(eq(v, "PY"))
return verb::copy;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
default:
break;
@@ -220,7 +224,7 @@ string_to_verb(string_view v)
case 'O':
if(eq(v, "VE"))
return verb::move;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
default:
break;
@@ -264,7 +268,7 @@ string_to_verb(string_view v)
return verb::purge;
if(eq(v, "T"))
return verb::put;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
default:
break;
diff --git a/boost/beast/http/impl/write.ipp b/boost/beast/http/impl/write.ipp
index 9d5be277ec..af31cd9be9 100644
--- a/boost/beast/http/impl/write.ipp
+++ b/boost/beast/http/impl/write.ipp
@@ -19,6 +19,7 @@
#include <boost/asio/associated_allocator.hpp>
#include <boost/asio/associated_executor.hpp>
#include <boost/asio/handler_continuation_hook.hpp>
+#include <boost/asio/handler_invoke_hook.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/write.hpp>
#include <boost/optional.hpp>
@@ -67,7 +68,7 @@ class write_some_op
public:
write_some_op(write_some_op&&) = default;
- write_some_op(write_some_op const&) = default;
+ write_some_op(write_some_op const&) = delete;
template<class DeducedHandler>
write_some_op(DeducedHandler&& h, Stream& s,
@@ -84,7 +85,7 @@ public:
allocator_type
get_allocator() const noexcept
{
- return boost::asio::get_associated_allocator(h_);
+ return (boost::asio::get_associated_allocator)(h_);
}
using executor_type = boost::asio::associated_executor_t<
@@ -93,7 +94,7 @@ public:
executor_type
get_executor() const noexcept
{
- return boost::asio::get_associated_executor(
+ return (boost::asio::get_associated_executor)(
h_, s_.get_executor());
}
@@ -112,6 +113,14 @@ public:
return asio_handler_is_continuation(
std::addressof(op->h_));
}
+
+ template<class Function>
+ friend
+ void asio_handler_invoke(Function&& f, write_some_op* op)
+ {
+ using boost::asio::asio_handler_invoke;
+ asio_handler_invoke(f, std::addressof(op->h_));
+ }
};
template<
@@ -203,7 +212,7 @@ class write_op
public:
write_op(write_op&&) = default;
- write_op(write_op const&) = default;
+ write_op(write_op const&) = delete;
template<class DeducedHandler>
write_op(DeducedHandler&& h, Stream& s,
@@ -220,7 +229,7 @@ public:
allocator_type
get_allocator() const noexcept
{
- return boost::asio::get_associated_allocator(h_);
+ return (boost::asio::get_associated_allocator)(h_);
}
using executor_type = boost::asio::associated_executor_t<
@@ -229,7 +238,7 @@ public:
executor_type
get_executor() const noexcept
{
- return boost::asio::get_associated_executor(
+ return (boost::asio::get_associated_executor)(
h_, s_.get_executor());
}
@@ -246,6 +255,14 @@ public:
asio_handler_is_continuation(
std::addressof(op->h_));
}
+
+ template<class Function>
+ friend
+ void asio_handler_invoke(Function&& f, write_op* op)
+ {
+ using boost::asio::asio_handler_invoke;
+ asio_handler_invoke(f, std::addressof(op->h_));
+ }
};
template<
@@ -280,7 +297,7 @@ operator()(
case 2:
state_ = 3;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case 3:
{
@@ -306,7 +323,7 @@ class write_msg_op
Stream& s;
serializer<isRequest, Body, Fields> sr;
- data(Handler&, Stream& s_, message<
+ data(Handler const&, Stream& s_, message<
isRequest, Body, Fields>& m_)
: s(s_)
, sr(m_)
@@ -318,7 +335,7 @@ class write_msg_op
public:
write_msg_op(write_msg_op&&) = default;
- write_msg_op(write_msg_op const&) = default;
+ write_msg_op(write_msg_op const&) = delete;
template<class DeducedHandler, class... Args>
write_msg_op(DeducedHandler&& h, Stream& s, Args&&... args)
@@ -333,7 +350,7 @@ public:
allocator_type
get_allocator() const noexcept
{
- return boost::asio::get_associated_allocator(d_.handler());
+ return (boost::asio::get_associated_allocator)(d_.handler());
}
using executor_type = boost::asio::associated_executor_t<
@@ -342,7 +359,7 @@ public:
executor_type
get_executor() const noexcept
{
- return boost::asio::get_associated_executor(
+ return (boost::asio::get_associated_executor)(
d_.handler(), d_->s.get_executor());
}
@@ -360,6 +377,14 @@ public:
return asio_handler_is_continuation(
std::addressof(op->d_.handler()));
}
+
+ template<class Function>
+ friend
+ void asio_handler_invoke(Function&& f, write_msg_op* op)
+ {
+ using boost::asio::asio_handler_invoke;
+ asio_handler_invoke(f, std::addressof(op->d_.handler()));
+ }
};
template<class Stream, class Handler,
@@ -441,7 +466,7 @@ template<
class SyncWriteStream,
bool isRequest, class Body, class Fields>
std::size_t
-write_some(
+write_some_impl(
SyncWriteStream& stream,
serializer<isRequest, Body, Fields>& sr,
error_code& ec)
@@ -466,20 +491,19 @@ template<
class WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(
WriteHandler, void(error_code, std::size_t))
-async_write_some(
+async_write_some_impl(
AsyncWriteStream& stream,
serializer<isRequest, Body, Fields>& sr,
WriteHandler&& handler)
{
- boost::asio::async_completion<
- WriteHandler,
- void(error_code, std::size_t)> init{handler};
+ BOOST_BEAST_HANDLER_INIT(
+ WriteHandler, void(error_code, std::size_t));
detail::write_some_op<
AsyncWriteStream,
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
void(error_code, std::size_t)),
isRequest, Body, Fields>{
- init.completion_handler, stream, sr}();
+ std::move(init.completion_handler), stream, sr}();
return init.result.get();
}
@@ -524,7 +548,7 @@ write_some(
"Body requirements not met");
static_assert(is_body_writer<Body>::value,
"BodyWriter requirements not met");
- return detail::write_some(stream, sr, ec);
+ return detail::write_some_impl(stream, sr, ec);
}
template<
@@ -545,7 +569,7 @@ async_write_some(
"Body requirements not met");
static_assert(is_body_writer<Body>::value,
"BodyWriter requirements not met");
- return detail::async_write_some(stream, sr,
+ return detail::async_write_some_impl(stream, sr,
std::forward<WriteHandler>(handler));
}
@@ -629,16 +653,15 @@ async_write_header(
static_assert(is_body_writer<Body>::value,
"BodyWriter requirements not met");
sr.split(true);
- boost::asio::async_completion<
- WriteHandler,
- void(error_code, std::size_t)> init{handler};
+ BOOST_BEAST_HANDLER_INIT(
+ WriteHandler, void(error_code, std::size_t));
detail::write_op<
AsyncWriteStream,
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
void(error_code, std::size_t)),
detail::serializer_is_header_done,
isRequest, Body, Fields>{
- init.completion_handler, stream, sr}();
+ std::move(init.completion_handler), stream, sr}();
return init.result.get();
}
@@ -706,16 +729,15 @@ async_write(
static_assert(is_body_writer<Body>::value,
"BodyWriter requirements not met");
sr.split(false);
- boost::asio::async_completion<
- WriteHandler,
- void(error_code, std::size_t)> init{handler};
+ BOOST_BEAST_HANDLER_INIT(
+ WriteHandler, void(error_code, std::size_t));
detail::write_op<
AsyncWriteStream,
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
void(error_code, std::size_t)),
detail::serializer_is_done,
isRequest, Body, Fields>{
- init.completion_handler, stream, sr}();
+ std::move(init.completion_handler), stream, sr}();
return init.result.get();
}
@@ -780,15 +802,14 @@ async_write(
"Body requirements not met");
static_assert(is_body_writer<Body>::value,
"BodyWriter requirements not met");
- boost::asio::async_completion<
- WriteHandler,
- void(error_code, std::size_t)> init{handler};
+ 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>{
- init.completion_handler, stream, msg}();
+ std::move(init.completion_handler), stream, msg}();
return init.result.get();
}