mirror of
https://github.com/boostorg/beast.git
synced 2026-05-05 12:14:23 +02:00
New BodyReader and BodyWriter constructors (API Change):
fix #884 * BodyReader and BodyWriter constructors now require the header and body elements to be passed as distinct header and value_type objects. This enables the composition of body types, for example: http::response<compressed_body<http::string_body>> res; * The previous single-argument constructors are deprecated and will be removed in a subsequent version. Actions Required: * Change user-defined instances of BodyReader or BodyWriter constructor signatures to the two-argument form. OR * Define the macro BOOST_BEAST_ALLOW_DEPRECATED in the project (which will accept both the new and the deprecated signatures).
This commit is contained in:
committed by
Vinnie Falco
parent
d796319476
commit
b76ab4450a
@@ -70,9 +70,8 @@ struct basic_dynamic_body
|
||||
public:
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
reader(message<isRequest,
|
||||
basic_dynamic_body, Fields>& msg)
|
||||
: body_(msg.body())
|
||||
reader(header<isRequest, Fields>&, value_type& b)
|
||||
: body_(b)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -140,9 +139,8 @@ struct basic_dynamic_body
|
||||
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
writer(message<isRequest,
|
||||
basic_dynamic_body, Fields> const& m)
|
||||
: body_(m.body())
|
||||
writer(header<isRequest, Fields> const&, value_type const& b)
|
||||
: body_(b)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -239,8 +239,8 @@ public:
|
||||
|
||||
// Constructor.
|
||||
//
|
||||
// `m` holds the message we are serializing, which will
|
||||
// always have the `basic_file_body` as the body type.
|
||||
// `h` holds the headers of the message we are
|
||||
// serializing, while `b` holds the body.
|
||||
//
|
||||
// Note that the message is passed by non-const reference.
|
||||
// This is intentional, because reading from the file
|
||||
@@ -262,8 +262,7 @@ public:
|
||||
// a time.
|
||||
//
|
||||
template<bool isRequest, class Fields>
|
||||
writer(message<
|
||||
isRequest, basic_file_body, Fields>& m);
|
||||
writer(header<isRequest, Fields>& h, value_type& b);
|
||||
|
||||
// Initializer
|
||||
//
|
||||
@@ -296,9 +295,11 @@ template<class File>
|
||||
template<bool isRequest, class Fields>
|
||||
basic_file_body<File>::
|
||||
writer::
|
||||
writer(message<isRequest, basic_file_body, Fields>& m)
|
||||
: body_(m.body())
|
||||
writer(header<isRequest, Fields>& h, value_type& b)
|
||||
: body_(b)
|
||||
{
|
||||
boost::ignore_unused(h);
|
||||
|
||||
// The file must already be open
|
||||
BOOST_ASSERT(body_.file_.is_open());
|
||||
|
||||
@@ -398,13 +399,12 @@ public:
|
||||
//
|
||||
// This is called after the header is parsed and
|
||||
// indicates that a non-zero sized body may be present.
|
||||
// `m` holds the message we are receiving, which will
|
||||
// always have the `basic_file_body` as the body type.
|
||||
// `h` holds the received message headers.
|
||||
// `b` is an instance of `basic_file_body`.
|
||||
//
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
reader(
|
||||
message<isRequest, basic_file_body, Fields>& m);
|
||||
reader(header<isRequest, Fields>&h, value_type& b);
|
||||
|
||||
// Initializer
|
||||
//
|
||||
@@ -447,9 +447,10 @@ template<class File>
|
||||
template<bool isRequest, class Fields>
|
||||
basic_file_body<File>::
|
||||
reader::
|
||||
reader(message<isRequest, basic_file_body, Fields>& m)
|
||||
: body_(m.body())
|
||||
reader(header<isRequest, Fields>& h, value_type& body)
|
||||
: body_(body)
|
||||
{
|
||||
boost::ignore_unused(h);
|
||||
}
|
||||
|
||||
template<class File>
|
||||
|
||||
@@ -105,8 +105,8 @@ struct buffer_body
|
||||
public:
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
reader(message<isRequest, buffer_body, Fields>& m)
|
||||
: body_(m.body())
|
||||
reader(header<isRequest, Fields>&, value_type& b)
|
||||
: body_(b)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -167,9 +167,8 @@ struct buffer_body
|
||||
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
writer(message<isRequest,
|
||||
buffer_body, Fields> const& msg)
|
||||
: body_(msg.body())
|
||||
writer(header<isRequest, Fields> const&, value_type const& b)
|
||||
: body_(b)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -194,6 +194,22 @@ struct is_fields_helper : T
|
||||
t10::value && t11::value && t12::value>;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
using has_deprecated_body_writer =
|
||||
std::integral_constant<bool,
|
||||
std::is_constructible<typename T::writer,
|
||||
message<true, T, detail::fields_model>&>::value &&
|
||||
std::is_constructible<typename T::writer,
|
||||
message<false, T, detail::fields_model>&>::value>;
|
||||
|
||||
template<class T>
|
||||
using has_deprecated_body_reader =
|
||||
std::integral_constant<bool,
|
||||
std::is_constructible<typename T::reader,
|
||||
message<true, T, detail::fields_model>&>::value &&
|
||||
std::is_constructible<typename T::reader,
|
||||
message<false, T, detail::fields_model>&>::value>;
|
||||
|
||||
} // detail
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
@@ -63,7 +63,7 @@ struct empty_body
|
||||
{
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
reader(message<isRequest, empty_body, Fields>&)
|
||||
reader(header<isRequest, Fields>&, value_type&)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -104,8 +104,7 @@ struct empty_body
|
||||
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
writer(message<isRequest,
|
||||
empty_body, Fields> const&)
|
||||
writer(header<isRequest, Fields> const&, value_type const&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -123,9 +123,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 +166,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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -20,26 +20,87 @@ 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())
|
||||
{
|
||||
}
|
||||
|
||||
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),
|
||||
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(
|
||||
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_)
|
||||
@@ -47,6 +108,25 @@ parser(parser<isRequest, OtherBody, Allocator>&& other,
|
||||
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())
|
||||
{
|
||||
if(other.rd_inited_)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument{
|
||||
"moved-from parser has a body"});
|
||||
}
|
||||
|
||||
} // http
|
||||
|
||||
@@ -57,10 +57,32 @@ 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)
|
||||
, 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>{})
|
||||
{
|
||||
}
|
||||
|
||||
template<
|
||||
|
||||
@@ -303,6 +303,39 @@ public:
|
||||
private:
|
||||
friend class basic_parser<isRequest, parser>;
|
||||
|
||||
parser(std::true_type);
|
||||
parser(std::false_type);
|
||||
|
||||
template<class OtherBody, class... Args,
|
||||
class = typename std::enable_if<
|
||||
! std::is_same<Body, OtherBody>::value>::type>
|
||||
parser(
|
||||
std::true_type,
|
||||
parser<isRequest, OtherBody, Allocator>&& parser,
|
||||
Args&&... args);
|
||||
|
||||
template<class OtherBody, class... Args,
|
||||
class = typename std::enable_if<
|
||||
! std::is_same<Body, OtherBody>::value>::type>
|
||||
parser(
|
||||
std::false_type,
|
||||
parser<isRequest, OtherBody, Allocator>&& parser,
|
||||
Args&&... args);
|
||||
|
||||
template<class Arg1, class... ArgN,
|
||||
class = typename std::enable_if<
|
||||
! detail::is_parser<typename
|
||||
std::decay<Arg1>::type>::value>::type>
|
||||
explicit
|
||||
parser(Arg1&& arg1, std::true_type, ArgN&&... argn);
|
||||
|
||||
template<class Arg1, class... ArgN,
|
||||
class = typename std::enable_if<
|
||||
! detail::is_parser<typename
|
||||
std::decay<Arg1>::type>::value>::type>
|
||||
explicit
|
||||
parser(Arg1&& arg1, std::false_type, ArgN&&... argn);
|
||||
|
||||
void
|
||||
on_request_impl(
|
||||
verb method,
|
||||
|
||||
@@ -71,14 +71,20 @@ public:
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
using value_type = implementation_defined;
|
||||
#else
|
||||
using value_type =
|
||||
typename std::conditional<
|
||||
std::is_constructible<typename Body::writer,
|
||||
message<isRequest, Body, Fields>&>::value &&
|
||||
! std::is_constructible<typename Body::writer,
|
||||
message<isRequest, Body, Fields> const&>::value,
|
||||
message<isRequest, Body, Fields>,
|
||||
message<isRequest, Body, Fields> const>::type;
|
||||
using value_type = typename std::conditional<
|
||||
(std::is_constructible<typename Body::writer,
|
||||
header<isRequest, Fields>&,
|
||||
typename Body::value_type&>::value &&
|
||||
! std::is_constructible<typename Body::writer,
|
||||
header<isRequest, Fields> const&,
|
||||
typename Body::value_type const&>::value) ||
|
||||
// Deprecated BodyWriter Concept (v1.66)
|
||||
(std::is_constructible<typename Body::writer,
|
||||
message<isRequest, Body, Fields>&>::value &&
|
||||
! std::is_constructible<typename Body::writer,
|
||||
message<isRequest, Body, Fields> const&>::value),
|
||||
message<isRequest, Body, Fields>,
|
||||
message<isRequest, Body, Fields> const>::type;
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -188,6 +194,8 @@ private:
|
||||
bool header_done_ = false;
|
||||
bool more_;
|
||||
|
||||
serializer(value_type& msg, std::true_type);
|
||||
serializer(value_type& msg, std::false_type);
|
||||
public:
|
||||
/// Constructor
|
||||
serializer(serializer&&) = default;
|
||||
|
||||
@@ -73,9 +73,8 @@ public:
|
||||
public:
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
reader(message<isRequest,
|
||||
span_body, Fields>& m)
|
||||
: body_(m.body())
|
||||
reader(header<isRequest, Fields>&, value_type& b)
|
||||
: body_(b)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -138,9 +137,8 @@ public:
|
||||
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
writer(message<isRequest,
|
||||
span_body, Fields> const& msg)
|
||||
: body_(msg.body())
|
||||
writer(header<isRequest, Fields> const&, value_type const& b)
|
||||
: body_(b)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -81,9 +81,8 @@ public:
|
||||
public:
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
reader(message<isRequest,
|
||||
basic_string_body, Fields>& m)
|
||||
: body_(m.body())
|
||||
reader(header<isRequest, Fields>&, value_type& b)
|
||||
: body_(b)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -166,9 +165,8 @@ public:
|
||||
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
writer(message<isRequest,
|
||||
basic_string_body, Fields> const& msg)
|
||||
: body_(msg.body())
|
||||
writer(header<isRequest, Fields> const&, value_type const& b)
|
||||
: body_(b)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -89,11 +89,19 @@ struct is_body_writer<T, beast::detail::void_t<
|
||||
std::declval<typename T::writer>().get(std::declval<error_code&>()),
|
||||
(void)0)>> : std::integral_constant<bool,
|
||||
boost::asio::is_const_buffer_sequence<
|
||||
typename T::writer::const_buffers_type>::value &&
|
||||
typename T::writer::const_buffers_type>::value && (
|
||||
(std::is_constructible<typename T::writer,
|
||||
header<true, detail::fields_model>&,
|
||||
typename T::value_type&>::value &&
|
||||
std::is_constructible<typename T::writer,
|
||||
header<false, detail::fields_model>&,
|
||||
typename T::value_type&>::value) ||
|
||||
// Deprecated BodyWriter Concept (v1.66)
|
||||
(std::is_constructible<typename T::writer,
|
||||
message<true, T, detail::fields_model>&>::value &&
|
||||
std::is_constructible<typename T::writer,
|
||||
message<false, T, detail::fields_model>&>::value
|
||||
message<false, T, detail::fields_model>&>::value)
|
||||
)
|
||||
> {};
|
||||
#endif
|
||||
|
||||
@@ -136,11 +144,18 @@ struct is_body_reader<T, beast::detail::void_t<decltype(
|
||||
std::declval<typename T::reader&>().finish(
|
||||
std::declval<error_code&>()),
|
||||
(void)0)>> : std::integral_constant<bool,
|
||||
(std::is_constructible<typename T::reader,
|
||||
header<true, detail::fields_model>&,
|
||||
typename T::value_type&>::value &&
|
||||
std::is_constructible<typename T::reader,
|
||||
header<false,detail::fields_model>&,
|
||||
typename T::value_type&>::value) ||
|
||||
// Deprecated BodyReader Concept (v1.66)
|
||||
(std::is_constructible<typename T::reader,
|
||||
message<true, T, detail::fields_model>&>::value &&
|
||||
std::is_constructible<typename T::reader,
|
||||
message<false, T, detail::fields_model>&>::value
|
||||
>
|
||||
message<false, T, detail::fields_model>&>::value)
|
||||
>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -76,9 +76,8 @@ public:
|
||||
public:
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
reader(message<isRequest,
|
||||
vector_body, Fields>& m)
|
||||
: body_(m.body())
|
||||
reader(header<isRequest, Fields>&, value_type& b)
|
||||
: body_(b)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -155,9 +154,8 @@ public:
|
||||
|
||||
template<bool isRequest, class Fields>
|
||||
explicit
|
||||
writer(message<isRequest,
|
||||
vector_body, Fields> const& msg)
|
||||
: body_(msg.body())
|
||||
writer(header<isRequest, Fields> const&, value_type const& b)
|
||||
: body_(b)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user