Add const and non-const overloads for message based http writes:

fix #1113

This solves a problem where the message-oriented synchronous
HTTP write algorithms do not support messages whose body
writer requires a non-const reference to the message in
order to construct.

In addition, the message-oriented async_write algorithm is
modified to support messages passed by const reference when
possible, based on the body writer attributes.
This commit is contained in:
Vinnie Falco
2018-05-06 19:57:25 -07:00
parent 07aead170a
commit 24bbda7b0d
4 changed files with 373 additions and 8 deletions
+94 -4
View File
@@ -333,6 +333,14 @@ class write_msg_op
, sr(m_)
{
}
data(Handler const&, Stream& s_, message<
isRequest, Body, Fields> const& m_)
: s(s_)
, wg(s.get_executor())
, sr(m_)
{
}
};
handler_ptr<data, Handler> d_;
@@ -751,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)
@@ -773,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,
@@ -793,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,
@@ -818,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 {