summaryrefslogtreecommitdiff
path: root/boost/beast/http/message.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/beast/http/message.hpp')
-rw-r--r--boost/beast/http/message.hpp999
1 files changed, 999 insertions, 0 deletions
diff --git a/boost/beast/http/message.hpp b/boost/beast/http/message.hpp
new file mode 100644
index 0000000000..5cf5d94dc9
--- /dev/null
+++ b/boost/beast/http/message.hpp
@@ -0,0 +1,999 @@
+//
+// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/beast
+//
+
+#ifndef BOOST_BEAST_HTTP_MESSAGE_HPP
+#define BOOST_BEAST_HTTP_MESSAGE_HPP
+
+#include <boost/beast/core/detail/config.hpp>
+#include <boost/beast/http/fields.hpp>
+#include <boost/beast/http/verb.hpp>
+#include <boost/beast/http/status.hpp>
+#include <boost/beast/http/type_traits.hpp>
+#include <boost/beast/core/string.hpp>
+#include <boost/beast/core/detail/empty_base_optimization.hpp>
+#include <boost/beast/core/detail/integer_sequence.hpp>
+#include <boost/assert.hpp>
+#include <boost/optional.hpp>
+#include <boost/throw_exception.hpp>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <tuple>
+#include <utility>
+
+namespace boost {
+namespace beast {
+namespace http {
+
+/** A container for an HTTP request or response header.
+
+ This container is derived from the `Fields` template type.
+ To understand all of the members of this class it is necessary
+ to view the declaration for the `Fields` type. When using
+ the default fields container, those declarations are in
+ @ref fields.
+
+ Newly constructed header objects have version set to
+ HTTP/1.1. Newly constructed response objects also have
+ result code set to @ref status::ok.
+
+ A `header` includes the start-line and header-fields.
+*/
+#if BOOST_BEAST_DOXYGEN
+template<bool isRequest, class Fields = fields>
+struct header : Fields
+
+#else
+template<bool isRequest, class Fields = fields>
+struct header;
+
+template<class Fields>
+struct header<true, Fields> : Fields
+#endif
+{
+ static_assert(is_fields<Fields>::value,
+ "Fields requirements not met");
+
+ /// Indicates if the header is a request or response.
+#if BOOST_BEAST_DOXYGEN
+ using is_request = std::integral_constant<bool, isRequest>;
+#else
+ using is_request = std::true_type;
+#endif
+
+ /// The type representing the fields.
+ using fields_type = Fields;
+
+ /// Constructor
+ header() = default;
+
+ /// Constructor
+ header(header&&) = default;
+
+ /// Constructor
+ header(header const&) = default;
+
+ /// Assignment
+ header& operator=(header&&) = default;
+
+ /// Assignment
+ header& operator=(header const&) = default;
+
+ /** Return the HTTP-version.
+
+ This holds both the major and minor version numbers,
+ using these formulas:
+ @code
+ unsigned major = version / 10;
+ unsigned minor = version % 10;
+ @endcode
+
+ Newly constructed headers will use HTTP/1.1 by default.
+ */
+ unsigned version() const noexcept
+ {
+ return version_;
+ }
+
+ /** Set the HTTP-version.
+
+ This holds both the major and minor version numbers,
+ using these formulas:
+ @code
+ unsigned major = version / 10;
+ unsigned minor = version % 10;
+ @endcode
+
+ Newly constructed headers will use HTTP/1.1 by default.
+
+ @param value The version number to use
+ */
+ void version(unsigned value) noexcept
+ {
+ BOOST_ASSERT(value > 0 && value < 100);
+ version_ = value;
+ }
+
+ /** Return the request-method verb.
+
+ If the request-method is not one of the recognized verbs,
+ @ref verb::unknown is returned. Callers may use @ref method_string
+ to retrieve the exact text.
+
+ @note This function is only available when `isRequest == true`.
+
+ @see @ref method_string
+ */
+ verb
+ method() const;
+
+ /** Set the request-method.
+
+ This function will set the method for requests to a known verb.
+
+ @param v The request method verb to set.
+ This may not be @ref verb::unknown.
+
+ @throws std::invalid_argument when `v == verb::unknown`.
+
+ @note This function is only available when `isRequest == true`.
+ */
+ void
+ method(verb v);
+
+ /** Return the request-method as a string.
+
+ @note This function is only available when `isRequest == true`.
+
+ @see @ref method
+ */
+ string_view
+ method_string() const;
+
+ /** Set the request-method.
+
+ This function will set the request-method a known verb
+ if the string matches, otherwise it will store a copy of
+ the passed string.
+
+ @param s A string representing the request-method.
+
+ @note This function is only available when `isRequest == true`.
+ */
+ void
+ method_string(string_view s);
+
+ /** Returns the request-target string.
+
+ The request target string returned is the same string which
+ was received from the network or stored. In particular, it will
+ contain url-encoded characters and should follow the syntax
+ rules for URIs used with HTTP.
+
+ @note This function is only available when `isRequest == true`.
+ */
+ string_view
+ target() const;
+
+ /** Set the request-target string.
+
+ It is the caller's responsibility to ensure that the request
+ target string follows the syntax rules for URIs used with
+ HTTP. In particular, reserved or special characters must be
+ url-encoded. The implementation does not perform syntax checking
+ on the passed string.
+
+ @param s A string representing the request-target.
+
+ @note This function is only available when `isRequest == true`.
+ */
+ void
+ target(string_view s);
+
+ // VFALCO Don't rearrange these declarations or
+ // ifdefs, or else the documentation will break.
+
+ /** Constructor
+
+ @param args Arguments forwarded to the `Fields`
+ base class constructor.
+
+ @note This constructor participates in overload
+ resolution if and only if the first parameter is
+ not convertible to @ref header, @ref verb, or
+ @ref status.
+ */
+#if BOOST_BEAST_DOXYGEN
+ template<class... Args>
+ explicit
+ header(Args&&... args);
+
+#else
+ template<class Arg1, class... ArgN,
+ class = typename std::enable_if<
+ ! std::is_convertible<typename
+ std::decay<Arg1>::type, header>::value &&
+ ! std::is_convertible<typename
+ std::decay<Arg1>::type, verb>::value &&
+ ! std::is_convertible<typename
+ std::decay<Arg1>::type, header>::value
+ >::type>
+ explicit
+ header(Arg1&& arg1, ArgN&&... argn);
+
+private:
+ template<bool, class, class>
+ friend struct message;
+
+ template<class T>
+ friend
+ void
+ swap(header<true, T>& m1, header<true, T>& m2);
+
+ template<class... FieldsArgs>
+ header(
+ verb method,
+ string_view target_,
+ unsigned version_value,
+ FieldsArgs&&... fields_args)
+ : Fields(std::forward<FieldsArgs>(fields_args)...)
+ , method_(method)
+ {
+ version(version_value);
+ target(target_);
+ }
+
+ unsigned version_ = 11;
+ verb method_ = verb::unknown;
+};
+
+/** A container for an HTTP request or response header.
+
+ A `header` includes the start-line and header-fields.
+*/
+template<class Fields>
+struct header<false, Fields> : Fields
+{
+ static_assert(is_fields<Fields>::value,
+ "Fields requirements not met");
+
+ /// Indicates if the header is a request or response.
+ using is_request = std::false_type;
+
+ /// The type representing the fields.
+ using fields_type = Fields;
+
+ /// Constructor.
+ header() = default;
+
+ /// Constructor
+ header(header&&) = default;
+
+ /// Constructor
+ header(header const&) = default;
+
+ /// Assignment
+ header& operator=(header&&) = default;
+
+ /// Assignment
+ header& operator=(header const&) = default;
+
+ /** Constructor
+
+ @param args Arguments forwarded to the `Fields`
+ base class constructor.
+
+ @note This constructor participates in overload
+ resolution if and only if the first parameter is
+ not convertible to @ref header, @ref verb, or
+ @ref status.
+ */
+ template<class Arg1, class... ArgN,
+ class = typename std::enable_if<
+ ! std::is_convertible<typename
+ std::decay<Arg1>::type, status>::value &&
+ ! std::is_convertible<typename
+ std::decay<Arg1>::type, header>::value
+ >::type>
+ explicit
+ header(Arg1&& arg1, ArgN&&... argn);
+
+ /** Return the HTTP-version.
+
+ This holds both the major and minor version numbers,
+ using these formulas:
+ @code
+ unsigned major = version / 10;
+ unsigned minor = version % 10;
+ @endcode
+
+ Newly constructed headers will use HTTP/1.1 by default.
+ */
+ unsigned version() const noexcept
+ {
+ return version_;
+ }
+
+ /** Set the HTTP-version.
+
+ This holds both the major and minor version numbers,
+ using these formulas:
+ @code
+ unsigned major = version / 10;
+ unsigned minor = version % 10;
+ @endcode
+
+ Newly constructed headers will use HTTP/1.1 by default.
+
+ @param value The version number to use
+ */
+ void version(unsigned value) noexcept
+ {
+ BOOST_ASSERT(value > 0 && value < 100);
+ version_ = value;
+ }
+#endif
+
+ /** The response status-code result.
+
+ If the actual status code is not a known code, this
+ function returns @ref status::unknown. Use @ref result_int
+ to return the raw status code as a number.
+
+ @note This member is only available when `isRequest == false`.
+ */
+ status
+ result() const;
+
+ /** Set the response status-code.
+
+ @param v The code to set.
+
+ @note This member is only available when `isRequest == false`.
+ */
+ void
+ result(status v);
+
+ /** Set the response status-code as an integer.
+
+ This sets the status code to the exact number passed in.
+ If the number does not correspond to one of the known
+ status codes, the function @ref result will return
+ @ref status::unknown. Use @ref result_int to obtain the
+ original raw status-code.
+
+ @param v The status-code integer to set.
+
+ @throws std::invalid_argument if `v > 999`.
+ */
+ void
+ result(unsigned v);
+
+ /** The response status-code expressed as an integer.
+
+ This returns the raw status code as an integer, even
+ when that code is not in the list of known status codes.
+
+ @note This member is only available when `isRequest == false`.
+ */
+ unsigned
+ result_int() const;
+
+ /** Return the response reason-phrase.
+
+ The reason-phrase is obsolete as of rfc7230.
+
+ @note This function is only available when `isRequest == false`.
+ */
+ string_view
+ reason() const;
+
+ /** Set the response reason-phrase (deprecated)
+
+ This function sets a custom reason-phrase to a copy of
+ the string passed in. Normally it is not necessary to set
+ the reason phrase on an outgoing response object; the
+ implementation will automatically use the standard reason
+ text for the corresponding status code.
+
+ To clear a previously set custom phrase, pass an empty
+ string. This will restore the default standard reason text
+ based on the status code used when serializing.
+
+ The reason-phrase is obsolete as of rfc7230.
+
+ @param s The string to use for the reason-phrase.
+
+ @note This function is only available when `isRequest == false`.
+ */
+ void
+ reason(string_view s);
+
+private:
+#if ! BOOST_BEAST_DOXYGEN
+ template<bool, class, class>
+ friend struct message;
+
+ template<class T>
+ friend
+ void
+ swap(header<false, T>& m1, header<false, T>& m2);
+
+ template<class... FieldsArgs>
+ header(
+ status result,
+ unsigned version_value,
+ FieldsArgs&&... fields_args)
+ : Fields(std::forward<FieldsArgs>(fields_args)...)
+ , result_(result)
+ {
+ version(version_value);
+ }
+
+ unsigned version_ = 11;
+ status result_ = status::ok;
+#endif
+};
+
+/// A typical HTTP request header
+template<class Fields = fields>
+using request_header = header<true, Fields>;
+
+/// A typical HTTP response header
+template<class Fields = fields>
+using response_header = header<false, Fields>;
+
+#if defined(BOOST_MSVC)
+// Workaround for MSVC bug with private base classes
+namespace detail {
+template<class T>
+using value_type_t = typename T::value_type;
+} // detail
+#endif
+
+/** A container for a complete HTTP message.
+
+ This container is derived from the `Fields` template type.
+ To understand all of the members of this class it is necessary
+ to view the declaration for the `Fields` type. When using
+ the default fields container, those declarations are in
+ @ref fields.
+
+ A message can be a request or response, depending on the
+ `isRequest` template argument value. Requests and responses
+ have different types; functions may be overloaded based on
+ the type if desired.
+
+ The `Body` template argument type determines the model used
+ to read or write the content body of the message.
+
+ Newly constructed messages objects have version set to
+ HTTP/1.1. Newly constructed response objects also have
+ result code set to @ref status::ok.
+
+ @tparam isRequest `true` if this represents a request,
+ or `false` if this represents a response. Some class data
+ members are conditionally present depending on this value.
+
+ @tparam Body A type meeting the requirements of Body.
+
+ @tparam Fields The type of container used to hold the
+ field value pairs.
+*/
+template<bool isRequest, class Body, class Fields = fields>
+struct message
+ : header<isRequest, Fields>
+#if ! BOOST_BEAST_DOXYGEN
+ , beast::detail::empty_base_optimization<
+ typename Body::value_type>
+#endif
+{
+ /// The base class used to hold the header portion of the message.
+ using header_type = header<isRequest, Fields>;
+
+ /** The type providing the body traits.
+
+ The @ref message::body member will be of type `body_type::value_type`.
+ */
+ using body_type = Body;
+
+ /// Constructor
+ message() = default;
+
+ /// Constructor
+ message(message&&) = default;
+
+ /// Constructor
+ message(message const&) = default;
+
+ /// Assignment
+ message& operator=(message&&) = default;
+
+ /// Assignment
+ message& operator=(message const&) = default;
+
+ /** Constructor
+
+ @param h The header to move construct from.
+
+ @param body_args Optional arguments forwarded
+ to the `body` constructor.
+ */
+ template<class... BodyArgs>
+ explicit
+ message(header_type&& h, BodyArgs&&... body_args);
+
+ /** Constructor.
+
+ @param h The header to copy construct from.
+
+ @param body_args Optional arguments forwarded
+ to the `body` constructor.
+ */
+ template<class... BodyArgs>
+ explicit
+ message(header_type const& h, BodyArgs&&... body_args);
+
+ /** Constructor
+
+ @param method The request-method to use
+
+ @param target The request-target.
+
+ @param version The HTTP-version
+
+ @note This function is only available when `isRequest == true`.
+ */
+#if BOOST_BEAST_DOXYGEN
+ message(verb method, string_view target, unsigned version);
+#else
+ template<class Version,
+ class = typename std::enable_if<isRequest &&
+ std::is_convertible<Version, unsigned>::value>::type>
+ message(verb method, string_view target, Version version);
+#endif
+
+ /** Constructor
+
+ @param method The request-method to use
+
+ @param target The request-target.
+
+ @param version The HTTP-version
+
+ @param body_arg An argument forwarded to the `body` constructor.
+
+ @note This function is only available when `isRequest == true`.
+ */
+#if BOOST_BEAST_DOXYGEN
+ template<class BodyArg>
+ message(verb method, string_view target,
+ unsigned version, BodyArg&& body_arg);
+#else
+ template<class Version, class BodyArg,
+ class = typename std::enable_if<isRequest &&
+ std::is_convertible<Version, unsigned>::value>::type>
+ message(verb method, string_view target,
+ Version version, BodyArg&& body_arg);
+#endif
+
+ /** Constructor
+
+ @param method The request-method to use
+
+ @param target The request-target.
+
+ @param version The HTTP-version
+
+ @param body_arg An argument forwarded to the `body` constructor.
+
+ @param fields_arg An argument forwarded to the `Fields` constructor.
+
+ @note This function is only available when `isRequest == true`.
+ */
+#if BOOST_BEAST_DOXYGEN
+ template<class BodyArg, class FieldsArg>
+ message(verb method, string_view target, unsigned version,
+ BodyArg&& body_arg, FieldsArg&& fields_arg);
+#else
+ template<class Version, class BodyArg, class FieldsArg,
+ class = typename std::enable_if<isRequest &&
+ std::is_convertible<Version, unsigned>::value>::type>
+ message(verb method, string_view target, Version version,
+ BodyArg&& body_arg, FieldsArg&& fields_arg);
+#endif
+
+ /** Constructor
+
+ @param result The status-code for the response
+
+ @param version The HTTP-version
+
+ @note This member is only available when `isRequest == false`.
+ */
+#if BOOST_BEAST_DOXYGEN
+ message(status result, unsigned version);
+#else
+ template<class Version,
+ class = typename std::enable_if<! isRequest &&
+ std::is_convertible<Version, unsigned>::value>::type>
+ message(status result, Version version);
+#endif
+
+ /** Constructor
+
+ @param result The status-code for the response
+
+ @param version The HTTP-version
+
+ @param body_arg An argument forwarded to the `body` constructor.
+
+ @note This member is only available when `isRequest == false`.
+ */
+#if BOOST_BEAST_DOXYGEN
+ template<class BodyArg>
+ message(status result, unsigned version, BodyArg&& body_arg);
+#else
+ template<class Version, class BodyArg,
+ class = typename std::enable_if<! isRequest &&
+ std::is_convertible<Version, unsigned>::value>::type>
+ message(status result, Version version, BodyArg&& body_arg);
+#endif
+
+ /** Constructor
+
+ @param result The status-code for the response
+
+ @param version The HTTP-version
+
+ @param body_arg An argument forwarded to the `body` constructor.
+
+ @param fields_arg An argument forwarded to the `Fields` base class constructor.
+
+ @note This member is only available when `isRequest == false`.
+ */
+#if BOOST_BEAST_DOXYGEN
+ template<class BodyArg, class FieldsArg>
+ message(status result, unsigned version,
+ BodyArg&& body_arg, FieldsArg&& fields_arg);
+#else
+ template<class Version, class BodyArg, class FieldsArg,
+ class = typename std::enable_if<! isRequest &&
+ std::is_convertible<Version, unsigned>::value>::type>
+ message(status result, Version version,
+ BodyArg&& body_arg, FieldsArg&& fields_arg);
+#endif
+
+ /** Constructor
+
+ The header and body are default-constructed.
+ */
+ explicit
+ message(std::piecewise_construct_t);
+
+ /** Construct a message.
+
+ @param body_args A tuple forwarded as a parameter
+ pack to the body constructor.
+ */
+ template<class... BodyArgs>
+ message(std::piecewise_construct_t,
+ std::tuple<BodyArgs...> body_args);
+
+ /** Construct a message.
+
+ @param body_args A tuple forwarded as a parameter
+ pack to the body constructor.
+
+ @param fields_args A tuple forwarded as a parameter
+ pack to the `Fields` constructor.
+ */
+ template<class... BodyArgs, class... FieldsArgs>
+ message(std::piecewise_construct_t,
+ std::tuple<BodyArgs...> body_args,
+ std::tuple<FieldsArgs...> fields_args);
+
+ /// Returns the header portion of the message
+ header_type const&
+ base() const
+ {
+ return *this;
+ }
+
+ /// Returns the header portion of the message
+ header_type&
+ base()
+ {
+ return *this;
+ }
+
+ /// Returns `true` if the chunked Transfer-Encoding is specified
+ bool
+ chunked() const
+ {
+ return this->get_chunked_impl();
+ }
+
+ /** Set or clear the chunked Transfer-Encoding
+
+ This function will set or removed the "chunked" transfer
+ encoding as the last item in the list of encodings in the
+ field.
+
+ If the result of removing the chunked token results in an
+ empty string, the field is erased.
+
+ The Content-Length field is erased unconditionally.
+ */
+ void
+ chunked(bool value);
+
+ /** Returns `true` if the Content-Length field is present.
+
+ This function inspects the fields and returns `true` if
+ the Content-Length field is present. The properties of the
+ body are not checked, this only looks for the field.
+ */
+ bool
+ has_content_length() const
+ {
+ return this->has_content_length_impl();
+ }
+
+ /** Set or clear the Content-Length field
+
+ This function adjusts the Content-Length field as follows:
+
+ @li If `value` specifies a value, the Content-Length field
+ is set to the value. Otherwise
+
+ @li The Content-Length field is erased.
+
+ If "chunked" token appears as the last item in the
+ Transfer-Encoding field it is unconditionally removed.
+
+ @param value The value to set for Content-Length.
+ */
+ void
+ content_length(boost::optional<std::uint64_t> const& value);
+
+ /** Returns `true` if the message semantics indicate keep-alive
+
+ The value depends on the version in the message, which must
+ be set to the final value before this function is called or
+ else the return value is unreliable.
+ */
+ bool
+ keep_alive() const
+ {
+ return this->get_keep_alive_impl(this->version());
+ }
+
+ /** Set the keep-alive message semantic option
+
+ This function adjusts the Connection field to indicate
+ whether or not the connection should be kept open after
+ the corresponding response. The result depends on the
+ version set on the message, which must be set to the
+ final value before making this call.
+
+ @param value `true` if the connection should persist.
+ */
+ void
+ keep_alive(bool value)
+ {
+ this->set_keep_alive_impl(this->version(), value);
+ }
+
+ /** Returns `true` if the message semantics require an end of file.
+
+ For HTTP requests, this function returns the logical
+ NOT of a call to @ref keep_alive.
+
+ For HTTP responses, this function returns the logical NOT
+ of a call to @ref keep_alive if any of the following are true:
+
+ @li @ref has_content_length would return `true`
+
+ @li @ref chunked would return `true`
+
+ @li @ref result returns @ref status::no_content
+
+ @li @ref result returns @ref status::not_modified
+
+ @li @ref result returns any informational status class (100 to 199)
+
+ Otherwise, the function returns `true`.
+
+ @see https://tools.ietf.org/html/rfc7230#section-3.3
+ */
+ bool
+ need_eof() const
+ {
+ return need_eof(typename header_type::is_request{});
+ }
+
+ /** Returns the payload size of the body in octets if possible.
+
+ This function invokes the @b Body algorithm to measure
+ the number of octets in the serialized body container. If
+ there is no body, this will return zero. Otherwise, if the
+ body exists but is not known ahead of time, `boost::none`
+ is returned (usually indicating that a chunked Transfer-Encoding
+ will be used).
+
+ @note The value of the Content-Length field in the message
+ is not inspected.
+ */
+ boost::optional<std::uint64_t>
+ payload_size() const;
+
+ /** Prepare the message payload fields for the body.
+
+ This function will adjust the Content-Length and
+ Transfer-Encoding field values based on the properties
+ of the body.
+
+ @par Example
+ @code
+ request<string_body> req{verb::post, "/"};
+ req.set(field::user_agent, "Beast");
+ req.body() = "Hello, world!";
+ req.prepare_payload();
+ @endcode
+ */
+ void
+ prepare_payload()
+ {
+ prepare_payload(typename header_type::is_request{});
+ }
+
+ /// Returns the body
+#if BOOST_BEAST_DOXYGEN || ! defined(BOOST_MSVC)
+ typename body_type::value_type&
+#else
+ detail::value_type_t<Body>&
+#endif
+ body()& noexcept
+ {
+ return this->member();
+ }
+
+ /// Returns the body
+#if BOOST_BEAST_DOXYGEN || ! defined(BOOST_MSVC)
+ typename body_type::value_type&&
+#else
+ detail::value_type_t<Body>&&
+#endif
+ body()&& noexcept
+ {
+ return std::move(this->member());
+ }
+
+ /// Returns the body
+#if BOOST_BEAST_DOXYGEN || ! defined(BOOST_MSVC)
+ typename body_type::value_type const&
+#else
+ detail::value_type_t<Body> const&
+#endif
+ body() const& noexcept
+ {
+ return this->member();
+ }
+
+private:
+ static_assert(is_body<Body>::value,
+ "Body requirements not met");
+
+ template<
+ class... BodyArgs,
+ std::size_t... IBodyArgs>
+ message(
+ std::piecewise_construct_t,
+ std::tuple<BodyArgs...>& body_args,
+ beast::detail::index_sequence<IBodyArgs...>)
+ : beast::detail::empty_base_optimization<
+ typename Body::value_type>(
+ std::forward<BodyArgs>(
+ std::get<IBodyArgs>(body_args))...)
+ {
+ boost::ignore_unused(body_args);
+ }
+
+ template<
+ class... BodyArgs,
+ class... FieldsArgs,
+ std::size_t... IBodyArgs,
+ std::size_t... IFieldsArgs>
+ message(
+ std::piecewise_construct_t,
+ std::tuple<BodyArgs...>& body_args,
+ std::tuple<FieldsArgs...>& fields_args,
+ beast::detail::index_sequence<IBodyArgs...>,
+ beast::detail::index_sequence<IFieldsArgs...>)
+ : header_type(std::forward<FieldsArgs>(
+ std::get<IFieldsArgs>(fields_args))...)
+ , beast::detail::empty_base_optimization<
+ typename Body::value_type>(
+ std::forward<BodyArgs>(
+ std::get<IBodyArgs>(body_args))...)
+ {
+ boost::ignore_unused(body_args);
+ boost::ignore_unused(fields_args);
+ }
+
+ bool
+ need_eof(std::true_type) const
+ {
+ return ! keep_alive();
+ }
+
+ bool
+ need_eof(std::false_type) const;
+
+ boost::optional<std::uint64_t>
+ payload_size(std::true_type) const
+ {
+ return Body::size(this->body());
+ }
+
+ boost::optional<std::uint64_t>
+ payload_size(std::false_type) const
+ {
+ return boost::none;
+ }
+
+ void
+ prepare_payload(std::true_type);
+
+ void
+ prepare_payload(std::false_type);
+};
+
+/// A typical HTTP request
+template<class Body, class Fields = fields>
+using request = message<true, Body, Fields>;
+
+/// A typical HTTP response
+template<class Body, class Fields = fields>
+using response = message<false, Body, Fields>;
+
+//------------------------------------------------------------------------------
+
+#if BOOST_BEAST_DOXYGEN
+/** Swap two header objects.
+
+ @par Requirements
+ `Fields` is @b Swappable.
+*/
+template<bool isRequest, class Fields>
+void
+swap(
+ header<isRequest, Fields>& m1,
+ header<isRequest, Fields>& m2);
+#endif
+
+/** Swap two message objects.
+
+ @par Requirements:
+ `Body::value_type` and `Fields` are @b Swappable.
+*/
+template<bool isRequest, class Body, class Fields>
+void
+swap(
+ message<isRequest, Body, Fields>& m1,
+ message<isRequest, Body, Fields>& m2);
+
+} // http
+} // beast
+} // boost
+
+#include <boost/beast/http/impl/message.ipp>
+
+#endif