// // Copyright (c) 2013-2016 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) // #ifndef BEAST_HTTP_MESSAGE_HPP #define BEAST_HTTP_MESSAGE_HPP #include #include #include #include #include #include namespace beast { namespace http { #if GENERATING_DOCS /** A container for HTTP request or response headers. The container includes the headers, as well as the request method and URL. Objects of this type may be used to represent incoming or outgoing requests for which the body is not yet known or generated. For example, when receiving a request with the header value "Expect: 100-continue". */ template struct message_headers #else template struct message_headers; template struct message_headers #endif { /// Indicates if the message headers are a request or response. #if GENERATING_DOCS static bool constexpr is_request = isRequest; #else static bool constexpr is_request = true; #endif /// The type representing the headers. using headers_type = Headers; /** The HTTP version. This holds both the major and minor version numbers, using these formulas: @code major = version / 10; minor = version % 10; @endcode */ int version; /** The Request Method @note This field is present only if `isRequest == true`. */ std::string method; /** The Request URI @note This field is present only if `isRequest == true`. */ std::string url; /// The HTTP field values. Headers headers; /// Default constructor message_headers() = default; /// Move constructor message_headers(message_headers&&) = default; /// Copy constructor message_headers(message_headers const&) = default; /// Move assignment message_headers& operator=(message_headers&&) = default; /// Copy assignment message_headers& operator=(message_headers const&) = default; /** Construct message headers. All arguments are forwarded to the constructor of the `headers` member. @note This constructor participates in overload resolution if and only if the first parameter is not convertible to `message_headers`. */ #if GENERATING_DOCS template explicit message_headers(Args&&... args); #else template 0) || ! std::is_convertible< typename std::decay::type, message_headers>::value>::type> explicit message_headers(Arg1&& arg1, ArgN&&... argn) : headers(std::forward(arg1), std::forward(argn)...) { } }; /** A container for HTTP request or response headers. The container includes the headers, as well as the response status and reasons. Objects of this type may be used to represent incoming or outgoing responses for which the body is not yet known or generated. For example, when responding to a HEAD request. */ template struct message_headers { /// Indicates if the message headers are a request or response. static bool constexpr is_request = false; /// The type representing the headers. using headers_type = Headers; /** The HTTP version. This holds both the major and minor version numbers, using these formulas: @code major = version / 10; minor = version % 10; @endcode */ int version; /// The HTTP field values. Headers headers; /// Default constructor message_headers() = default; /// Move constructor message_headers(message_headers&&) = default; /// Copy constructor message_headers(message_headers const&) = default; /// Move assignment message_headers& operator=(message_headers&&) = default; /// Copy assignment message_headers& operator=(message_headers const&) = default; /** Construct message headers. All arguments are forwarded to the constructor of the `headers` member. @note This constructor participates in overload resolution if and only if the first parameter is not convertible to `message_headers`. */ template 0) || ! std::is_convertible< typename std::decay::type, message_headers>::value>::type> explicit message_headers(Arg1&& arg1, ArgN&&... argn) : headers(std::forward(arg1), std::forward(argn)...) { } #endif /** The Response Status-Code. @note This field is present only if `isRequest == false`. */ int status; /** The Response Reason-Phrase. The Reason-Phrase is obsolete as of rfc7230. @note This field is present only if `isRequest == false`. */ std::string reason; }; /** A container for a complete HTTP message. A message can be a request or response, depending on the `isRequest` template argument value. Requests and responses have different types, so functions may be overloaded on them if desired. The `Body` template argument type determines the model used to read or write the content body of the message. @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 Headers The type of container used to hold the field value pairs. */ template struct message : message_headers { /// The base class used to hold the request or response headers using base_type = message_headers; /** The type providing the body traits. The `body` member will be of type `body_type::value_type`. */ using body_type = Body; /// A value representing the body. typename Body::value_type body; /// Default constructor message() = default; /** Construct a message from message headers. Additional arguments, if any, are forwarded to the constructor of the body member. */ template explicit message(base_type&& base, Args&&... args) : base_type(std::move(base)) , body(std::forward(args)...) { } /** Construct a message from message headers. Additional arguments, if any, are forwarded to the constructor of the body member. */ template explicit message(base_type const& base, Args&&... args) : base_type(base) , body(std::forward(args)...) { } /** Construct a message. @param u An argument forwarded to the body constructor. @note This constructor participates in overload resolution only if `u` is not convertible to `base_type`. */ template::type, base_type>::value> #endif > explicit message(U&& u) : body(std::forward(u)) { } /** Construct a message. @param u An argument forwarded to the body constructor. @param v An argument forwarded to the headers constructor. @note This constructor participates in overload resolution only if `u` is not convertible to `base_type`. */ template::type, base_type>::value> #endif > message(U&& u, V&& v) : base_type(std::forward(v)) , body(std::forward(u)) { } /** Construct a message. @param un A tuple forwarded as a parameter pack to the body constructor. */ template message(std::piecewise_construct_t, std::tuple un) : message(std::piecewise_construct, un, beast::detail::make_index_sequence{}) { } /** Construct a message. @param un A tuple forwarded as a parameter pack to the body constructor. @param vn A tuple forwarded as a parameter pack to the headers constructor. */ template message(std::piecewise_construct_t, std::tuple&& un, std::tuple&& vn) : message(std::piecewise_construct, un, vn, beast::detail::make_index_sequence{}, beast::detail::make_index_sequence{}) { } /// Returns the message headers portion of the message base_type& base() { return *this; } /// Returns the message headers portion of the message base_type const& base() const { return *this; } private: template message(std::piecewise_construct_t, std::tuple& tu, beast::detail::index_sequence) : body(std::forward(std::get(tu))...) { } template message(std::piecewise_construct_t, std::tuple& tu, std::tuple& tv, beast::detail::index_sequence, beast::detail::index_sequence) : base_type(std::forward(std::get(tv))...) , body(std::forward(std::get(tu))...) { } }; //------------------------------------------------------------------------------ #if GENERATING_DOCS /** Swap two HTTP message headers. @par Requirements `Headers` is @b Swappable. */ template void swap( message_headers& m1, message_headers& m2); #endif /** Swap two HTTP messages. @par Requirements: `Body` and `Headers` are @b Swappable. */ template void swap( message& m1, message& m2); /// Message headers for a typical HTTP request using request_headers = message_headers>>; /// Message headers for a typical HTTP response using response_headers = message_headers>>; /// A typical HTTP request message template>> using request = message; /// A typical HTTP response message template>> using response = message; //------------------------------------------------------------------------------ /** Returns `true` if a HTTP/1 message indicates a keep alive. Undefined behavior if version is greater than 11. */ template bool is_keep_alive(message const& msg); /** Returns `true` if a HTTP/1 message indicates an Upgrade request or response. Undefined behavior if version is greater than 11. */ template bool is_upgrade(message const& msg); /** HTTP/1 connection prepare options. @note These values are used with @ref prepare. */ enum class connection { /// Specify Connection: close. close, /// Specify Connection: keep-alive where possible. keep_alive, /// Specify Connection: upgrade. upgrade }; /** Prepare a HTTP message. This function will adjust the Content-Length, Transfer-Encoding, and Connection headers of the message based on the properties of the body and the options passed in. @param msg The message to prepare. The headers may be modified. @param options A list of prepare options. */ template< bool isRequest, class Body, class Headers, class... Options> void prepare(message& msg, Options&&... options); } // http } // beast #include #endif