mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
Refactor message and message_headers declarations:
message_headers is now a set of partial class template specializations instead of a template class alias. This solves a problem where template functions taking message_headers as a parameter could not deduce argument types, since std::conditional obscured the deduced context. Both classes are refactored to share declarations using an #ifdef, to eliminate an ugly set of extra declarations needed when building the documentation. Copy and move class special members are added. A new function message::base() is provided which returns the message_headers portion of a message.
This commit is contained in:
@ -1,10 +1,16 @@
|
||||
1.0.0-b19
|
||||
|
||||
HTTP
|
||||
|
||||
WebSocket
|
||||
|
||||
* Optimize utf8 validation
|
||||
* Optimize mask operations
|
||||
|
||||
API Changes:
|
||||
|
||||
* Refactor message and message_headers declarations
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
1.0.0-b18
|
||||
|
@ -1052,10 +1052,26 @@
|
||||
</xsl:for-each>
|
||||
<xsl:text>]
</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="count(sectiondef[@kind='public-attrib' or @kind='public-static-attrib']) > 0">
|
||||
<xsl:if test="count(sectiondef[@kind='public-static-attrib']) > 0">
|
||||
<xsl:text>[heading Static Data Members]
</xsl:text>
|
||||
<xsl:text>[table
 [[Name][Description]]
</xsl:text>
|
||||
<xsl:for-each select="sectiondef[@kind='public-static-attrib']/memberdef" mode="class-table">
|
||||
<xsl:sort select="name"/>
|
||||
<xsl:text> [
</xsl:text>
|
||||
<xsl:text> [[link beast.ref.</xsl:text>
|
||||
<xsl:value-of select="$class-id"/>.<xsl:value-of select="name"/>
|
||||
<xsl:text> [*</xsl:text>
|
||||
<xsl:value-of select="name"/>
|
||||
<xsl:text>]]]
 [
 </xsl:text>
|
||||
<xsl:value-of select="briefdescription"/>
|
||||
<xsl:text>
 ]
 ]
</xsl:text>
|
||||
</xsl:for-each>
|
||||
<xsl:text>]
</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="count(sectiondef[@kind='public-attrib']) > 0">
|
||||
<xsl:text>[heading Data Members]
</xsl:text>
|
||||
<xsl:text>[table
 [[Name][Description]]
</xsl:text>
|
||||
<xsl:for-each select="sectiondef[@kind='public-attrib' or @kind='public-static-attrib']/memberdef" mode="class-table">
|
||||
<xsl:for-each select="sectiondef[@kind='public-attrib']/memberdef" mode="class-table">
|
||||
<xsl:sort select="name"/>
|
||||
<xsl:text> [
</xsl:text>
|
||||
<xsl:text> [[link beast.ref.</xsl:text>
|
||||
|
@ -20,6 +20,43 @@
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
template<class Headers>
|
||||
void
|
||||
swap(
|
||||
message_headers<true, Headers>& m1,
|
||||
message_headers<true, Headers>& m2)
|
||||
{
|
||||
using std::swap;
|
||||
swap(m1.version, m2.version);
|
||||
swap(m1.method, m2.method);
|
||||
swap(m1.url, m2.url);
|
||||
swap(m1.headers, m2.headers);
|
||||
}
|
||||
|
||||
template<class Headers>
|
||||
void
|
||||
swap(
|
||||
message_headers<false, Headers>& a,
|
||||
message_headers<false, Headers>& b)
|
||||
{
|
||||
using std::swap;
|
||||
swap(a.version, b.version);
|
||||
swap(a.status, b.status);
|
||||
swap(a.reason, b.reason);
|
||||
swap(a.headers, b.headers);
|
||||
}
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
swap(
|
||||
message<isRequest, Body, Headers>& m1,
|
||||
message<isRequest, Body, Headers>& m2)
|
||||
{
|
||||
using std::swap;
|
||||
swap(m1.base(), m2.base());
|
||||
swap(m1.body, m2.body);
|
||||
}
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
bool
|
||||
is_keep_alive(message<isRequest, Body, Headers> const& msg)
|
||||
|
@ -18,7 +18,8 @@
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** A container for HTTP request headers.
|
||||
#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
|
||||
@ -27,12 +28,24 @@ namespace http {
|
||||
example, when receiving a request with the header value
|
||||
"Expect: 100-continue".
|
||||
*/
|
||||
template<bool isRequest, class Headers>
|
||||
struct message_headers
|
||||
|
||||
#else
|
||||
template<bool isRequest, class Headers>
|
||||
struct message_headers;
|
||||
|
||||
template<class Headers>
|
||||
struct request_headers
|
||||
struct message_headers<true, Headers>
|
||||
#endif
|
||||
{
|
||||
/// Indicates if the message is a request.
|
||||
using is_request =
|
||||
std::integral_constant<bool, true>;
|
||||
/// 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;
|
||||
@ -48,57 +61,65 @@ struct request_headers
|
||||
*/
|
||||
int version;
|
||||
|
||||
/// The Request Method.
|
||||
/** The Request Method
|
||||
|
||||
@note This field is present only if `isRequest == true`.
|
||||
*/
|
||||
std::string method;
|
||||
|
||||
/// The Request URI.
|
||||
/** The Request URI
|
||||
|
||||
@note This field is present only if `isRequest == true`.
|
||||
*/
|
||||
std::string url;
|
||||
|
||||
/// The HTTP headers.
|
||||
/// The HTTP field values.
|
||||
Headers headers;
|
||||
|
||||
/** Construct HTTP request headers.
|
||||
/// Default constructor
|
||||
message_headers() = default;
|
||||
|
||||
Arguments, if any, are forwarded to the constructor
|
||||
of the headers member.
|
||||
/// 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`.
|
||||
*/
|
||||
/** @{ */
|
||||
request_headers() = default;
|
||||
#if GENERATING_DOCS
|
||||
template<class... Args>
|
||||
explicit
|
||||
message_headers(Args&&... args);
|
||||
|
||||
#else
|
||||
template<class Arg1, class... ArgN,
|
||||
class = typename std::enable_if<
|
||||
(sizeof...(ArgN) > 0) || ! std::is_convertible<
|
||||
typename std::decay<Arg1>::type,
|
||||
request_headers>::value>::type>
|
||||
message_headers>::value>::type>
|
||||
explicit
|
||||
request_headers(Arg1&& arg1, ArgN&&... argn)
|
||||
message_headers(Arg1&& arg1, ArgN&&... argn)
|
||||
: headers(std::forward<Arg1>(arg1),
|
||||
std::forward<ArgN>(argn)...)
|
||||
{
|
||||
}
|
||||
/** @} */
|
||||
};
|
||||
|
||||
/** Swap two HTTP request headers.
|
||||
|
||||
Requirements:
|
||||
|
||||
Headers is Swappable.
|
||||
*/
|
||||
template<class Headers>
|
||||
void
|
||||
swap(
|
||||
request_headers<Headers>& a,
|
||||
request_headers<Headers>& b)
|
||||
{
|
||||
using std::swap;
|
||||
swap(a.version, b.version);
|
||||
swap(a.method, b.method);
|
||||
swap(a.url, b.url);
|
||||
swap(a.headers, b.headers);
|
||||
}
|
||||
|
||||
/** A container for HTTP response headers.
|
||||
/** 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
|
||||
@ -107,11 +128,10 @@ swap(
|
||||
example, when responding to a HEAD request.
|
||||
*/
|
||||
template<class Headers>
|
||||
struct response_headers
|
||||
struct message_headers<false, Headers>
|
||||
{
|
||||
/// Indicates if the message is a response.
|
||||
using is_request =
|
||||
std::integral_constant<bool, false>;
|
||||
/// 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;
|
||||
@ -127,94 +147,45 @@ struct response_headers
|
||||
*/
|
||||
int version;
|
||||
|
||||
/// The Response Status-Code.
|
||||
int status;
|
||||
|
||||
/** The Response Reason-Phrase.
|
||||
|
||||
The Reason-Phrase is obsolete as of rfc7230.
|
||||
*/
|
||||
std::string reason;
|
||||
|
||||
/// The HTTP headers.
|
||||
/// The HTTP field values.
|
||||
Headers headers;
|
||||
|
||||
/** Construct HTTP request headers.
|
||||
/// Default constructor
|
||||
message_headers() = default;
|
||||
|
||||
Arguments, if any, are forwarded to the constructor
|
||||
of the headers member.
|
||||
/// 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`.
|
||||
*/
|
||||
/** @{ */
|
||||
response_headers() = default;
|
||||
|
||||
template<class Arg1, class... ArgN,
|
||||
class = typename std::enable_if<
|
||||
(sizeof...(ArgN) > 0) || ! std::is_convertible<
|
||||
typename std::decay<Arg1>::type,
|
||||
response_headers>::value>::type>
|
||||
message_headers>::value>::type>
|
||||
explicit
|
||||
response_headers(Arg1&& arg1, ArgN&&... argn)
|
||||
message_headers(Arg1&& arg1, ArgN&&... argn)
|
||||
: headers(std::forward<Arg1>(arg1),
|
||||
std::forward<ArgN>(argn)...)
|
||||
{
|
||||
}
|
||||
/** @} */
|
||||
};
|
||||
|
||||
/** Swap two HTTP response headers.
|
||||
|
||||
Requirements:
|
||||
|
||||
Headers is Swappable.
|
||||
*/
|
||||
template<class Headers>
|
||||
void
|
||||
swap(
|
||||
response_headers<Headers>& a,
|
||||
response_headers<Headers>& b)
|
||||
{
|
||||
using std::swap;
|
||||
swap(a.version, b.version);
|
||||
swap(a.status, b.status);
|
||||
swap(a.reason, b.reason);
|
||||
swap(a.headers, b.headers);
|
||||
}
|
||||
|
||||
/** A container for HTTP request or response headers.
|
||||
*/
|
||||
#if GENERATING_DOCS
|
||||
template<bool isRequest, class Headers>
|
||||
struct message_headers
|
||||
{
|
||||
/// Indicates if the message is a request.
|
||||
using is_request =
|
||||
std::integral_constant<bool, isRequest>;
|
||||
|
||||
/// 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;
|
||||
#endif
|
||||
|
||||
/** The Response Status-Code.
|
||||
|
||||
@ -229,29 +200,9 @@ struct message_headers
|
||||
@note This field is present only if `isRequest == false`.
|
||||
*/
|
||||
std::string reason;
|
||||
|
||||
/// The HTTP headers.
|
||||
Headers headers;
|
||||
|
||||
/** Construct message headers.
|
||||
|
||||
Any provided arguments are forwarded to the
|
||||
constructor of the headers member.
|
||||
*/
|
||||
template<class... Args>
|
||||
message_headers(Args&&... args);
|
||||
};
|
||||
|
||||
#else
|
||||
template<bool isRequest, class Headers>
|
||||
using message_headers =
|
||||
typename std::conditional<isRequest,
|
||||
request_headers<Headers>,
|
||||
response_headers<Headers>>::type;
|
||||
|
||||
#endif
|
||||
|
||||
/** A complete HTTP message.
|
||||
/** 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,
|
||||
@ -260,93 +211,35 @@ using message_headers =
|
||||
The `Body` template argument type determines the model used
|
||||
to read or write the content body of the message.
|
||||
|
||||
@tparam isRequest `true` if this is a request.
|
||||
@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 A type meeting the requirements of Headers.
|
||||
@tparam Headers The type of container used to hold the
|
||||
field value pairs.
|
||||
*/
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
struct message :
|
||||
#if GENERATING_DOCS
|
||||
implementation_defined
|
||||
#else
|
||||
message_headers<isRequest, Headers>
|
||||
#endif
|
||||
{
|
||||
#if GENERATING_DOCS
|
||||
/// Indicates if the message is a request.
|
||||
using is_request =
|
||||
std::integral_constant<bool, isRequest>;
|
||||
|
||||
/// The type representing the headers.
|
||||
using headers_type = Headers;
|
||||
|
||||
/** The type controlling the body traits.
|
||||
|
||||
The body member will be of type `body_type::value_type`.
|
||||
*/
|
||||
using body_type = Body;
|
||||
|
||||
/** 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 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;
|
||||
|
||||
/// The HTTP headers.
|
||||
Headers headers;
|
||||
|
||||
#else
|
||||
/// The container used to hold the request or response headers
|
||||
/// The base class used to hold the request or response headers
|
||||
using base_type = message_headers<isRequest, Headers>;
|
||||
|
||||
/** The type controlling the body traits.
|
||||
/** The type providing the body traits.
|
||||
|
||||
The body member will be of type `body_type::value_type`.
|
||||
The `body` member will be of type `body_type::value_type`.
|
||||
*/
|
||||
using body_type = Body;
|
||||
|
||||
#endif
|
||||
|
||||
/// A container representing the body.
|
||||
/// A value representing the body.
|
||||
typename Body::value_type body;
|
||||
|
||||
/// Default constructor
|
||||
message() = default;
|
||||
|
||||
/** Construct a message from headers.
|
||||
/** Construct a message from message headers.
|
||||
|
||||
Additional arguments, if any, are forwarded to
|
||||
the constructor of the body member.
|
||||
@ -359,7 +252,7 @@ struct message :
|
||||
{
|
||||
}
|
||||
|
||||
/** Construct a message from headers.
|
||||
/** Construct a message from message headers.
|
||||
|
||||
Additional arguments, if any, are forwarded to
|
||||
the constructor of the body member.
|
||||
@ -394,6 +287,7 @@ struct message :
|
||||
/** 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
|
||||
@ -425,6 +319,7 @@ struct message :
|
||||
/** 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<class... Un, class... Vn>
|
||||
@ -436,6 +331,20 @@ struct message :
|
||||
{
|
||||
}
|
||||
|
||||
/// 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<class... Un, size_t... IUn>
|
||||
message(std::piecewise_construct_t,
|
||||
@ -456,31 +365,52 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
/// Swap one message for another message.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if GENERATING_DOCS
|
||||
/** Swap two HTTP message headers.
|
||||
|
||||
@par Requirements
|
||||
`Headers` is @b Swappable.
|
||||
*/
|
||||
template<bool isRequest, class Headers>
|
||||
void
|
||||
swap(
|
||||
message_headers<isRequest, Headers>& m1,
|
||||
message_headers<isRequest, Headers>& m2);
|
||||
#endif
|
||||
|
||||
/** Swap two HTTP messages.
|
||||
|
||||
@par Requirements:
|
||||
`Body` and `Headers` are @b Swappable.
|
||||
*/
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
swap(
|
||||
message<isRequest, Body, Headers>& a,
|
||||
message<isRequest, Body, Headers>& b)
|
||||
{
|
||||
using std::swap;
|
||||
using base_type = typename message<
|
||||
isRequest, Body, Headers>::base_type;
|
||||
swap(static_cast<base_type&>(a),
|
||||
static_cast<base_type&>(b));
|
||||
swap(a.body, b.body);
|
||||
}
|
||||
message<isRequest, Body, Headers>& m1,
|
||||
message<isRequest, Body, Headers>& m2);
|
||||
|
||||
/// A typical HTTP request
|
||||
/// Message headers for a typical HTTP request
|
||||
using request_headers = message_headers<true,
|
||||
basic_headers<std::allocator<char>>>;
|
||||
|
||||
/// Message headers for a typical HTTP response
|
||||
using response_headers = message_headers<false,
|
||||
basic_headers<std::allocator<char>>>;
|
||||
|
||||
/// A typical HTTP request message
|
||||
template<class Body,
|
||||
class Headers = basic_headers<std::allocator<char>>>
|
||||
using request = message<true, Body, Headers>;
|
||||
|
||||
/// A typical HTTP response
|
||||
/// A typical HTTP response message
|
||||
template<class Body,
|
||||
class Headers = basic_headers<std::allocator<char>>>
|
||||
using response = message<false, Body, Headers>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Returns `true` if a HTTP/1 message indicates a keep alive.
|
||||
|
||||
Undefined behavior if version is greater than 11.
|
||||
|
@ -17,6 +17,120 @@
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** Write HTTP/1 message headers on a stream.
|
||||
|
||||
This function is used to write message headers to a stream. The
|
||||
call will block until one of the following conditions is true:
|
||||
|
||||
@li All the message headers are sent.
|
||||
|
||||
@li An error occurs.
|
||||
|
||||
This operation is implemented in terms of one or more calls
|
||||
to the stream's `write_some` function.
|
||||
|
||||
Regardless of the semantic meaning of the headers (for example,
|
||||
specifying a zero-length message body and Connection: Close),
|
||||
this function will not return `boost::asio::error::eof`.
|
||||
|
||||
@param stream The stream to which the data is to be written.
|
||||
The type must support the @b `SyncWriteStream` concept.
|
||||
|
||||
@param msg The message headers to write.
|
||||
|
||||
@throws system_error Thrown on failure.
|
||||
*/
|
||||
template<class SyncWriteStream,
|
||||
bool isRequest, class Headers>
|
||||
void
|
||||
write(SyncWriteStream& stream,
|
||||
message_headers<isRequest, Headers> const& msg);
|
||||
|
||||
/** Write HTTP/1 message headers on a stream.
|
||||
|
||||
This function is used to write message headers to a stream. The
|
||||
call will block until one of the following conditions is true:
|
||||
|
||||
@li All the message headers are sent.
|
||||
|
||||
@li An error occurs.
|
||||
|
||||
This operation is implemented in terms of one or more calls
|
||||
to the stream's `write_some` function.
|
||||
|
||||
Regardless of the semantic meaning of the headers (for example,
|
||||
specifying a zero-length message body and Connection: Close),
|
||||
this function will not return `boost::asio::error::eof`.
|
||||
|
||||
@param stream The stream to which the data is to be written.
|
||||
The type must support the @b `SyncWriteStream` concept.
|
||||
|
||||
@param msg The message headers to write.
|
||||
|
||||
@param ec Set to the error, if any occurred.
|
||||
*/
|
||||
template<class SyncWriteStream,
|
||||
bool isRequest, class Headers>
|
||||
void
|
||||
write(SyncWriteStream& stream,
|
||||
message_headers<isRequest, Headers> const& msg,
|
||||
error_code& ec);
|
||||
|
||||
/** Start an asynchronous operation to write HTTP/1 message headers to a stream.
|
||||
|
||||
This function is used to asynchronously write message headers to a stream.
|
||||
The function call always returns immediately. The asynchronous
|
||||
operation will continue until one of the following conditions is true:
|
||||
|
||||
@li The entire message headers are sent.
|
||||
|
||||
@li An error occurs.
|
||||
|
||||
This operation is implemented in terms of one or more calls to the
|
||||
stream's `async_write_some` functions, and is known as a <em>composed
|
||||
operation</em>. The program must ensure that the stream performs no
|
||||
other write operations (such as @ref async_write, the stream's
|
||||
`async_write_some` function, or any other composed operations that
|
||||
perform writes) until this operation completes.
|
||||
|
||||
Regardless of the semantic meaning of the headers (for example,
|
||||
specifying a zero-length message body and Connection: Close),
|
||||
the handler will not be called with `boost::asio::error::eof`.
|
||||
|
||||
@param stream The stream to which the data is to be written.
|
||||
The type must support the @b `AsyncWriteStream` concept.
|
||||
|
||||
@param msg The message headers to send.
|
||||
|
||||
@param handler The handler to be called when the request completes.
|
||||
Copies will be made of the handler as required. The equivalent
|
||||
function signature of the handler must be:
|
||||
@code void handler(
|
||||
error_code const& error // result of operation
|
||||
); @endcode
|
||||
Regardless of whether the asynchronous operation completes
|
||||
immediately or not, the handler will not be invoked from within
|
||||
this function. Invocation of the handler will be performed in a
|
||||
manner equivalent to using `boost::asio::io_service::post`.
|
||||
|
||||
@note The message object must remain valid at least until the
|
||||
completion handler is called, no copies are made.
|
||||
*/
|
||||
template<class AsyncWriteStream,
|
||||
bool isRequest, class Headers,
|
||||
class WriteHandler>
|
||||
#if GENERATING_DOCS
|
||||
void_or_deduced
|
||||
#else
|
||||
typename async_completion<
|
||||
WriteHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_write(AsyncWriteStream& stream,
|
||||
message_headers<isRequest, Headers> const& msg,
|
||||
WriteHandler&& handler);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Write a HTTP/1 message on a stream.
|
||||
|
||||
This function is used to write a message to a stream. The call
|
||||
@ -135,7 +249,24 @@ async_write(AsyncWriteStream& stream,
|
||||
message<isRequest, Body, Headers> const& msg,
|
||||
WriteHandler&& handler);
|
||||
|
||||
/** Serialize a HTTP/1 message to an ostream.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Serialize HTTP/1 message headers to a `std::ostream`.
|
||||
|
||||
The function converts the message headers to its HTTP/1
|
||||
serialized representation and stores the result in the output
|
||||
stream.
|
||||
|
||||
@param os The output stream to write to.
|
||||
|
||||
@param msg The message headers to write.
|
||||
*/
|
||||
template<bool isRequest, class Headers>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os,
|
||||
message_headers<isRequest, Headers> const& msg);
|
||||
|
||||
/** Serialize a HTTP/1 message to a `std::ostream`.
|
||||
|
||||
The function converts the message to its HTTP/1 serialized
|
||||
representation and stores the result in the output stream.
|
||||
@ -143,7 +274,7 @@ async_write(AsyncWriteStream& stream,
|
||||
The implementation will automatically perform chunk encoding if
|
||||
the contents of the message indicate that chunk encoding is required.
|
||||
|
||||
@param os The ostream to write to.
|
||||
@param os The output stream to write to.
|
||||
|
||||
@param msg The message to write.
|
||||
*/
|
||||
|
@ -168,13 +168,13 @@ public:
|
||||
void testHeaders()
|
||||
{
|
||||
{
|
||||
using req_type = request_headers<headers>;
|
||||
using req_type = request_headers;
|
||||
static_assert(std::is_copy_constructible<req_type>::value, "");
|
||||
static_assert(std::is_move_constructible<req_type>::value, "");
|
||||
static_assert(std::is_copy_assignable<req_type>::value, "");
|
||||
static_assert(std::is_move_assignable<req_type>::value, "");
|
||||
|
||||
using res_type = response_headers<headers>;
|
||||
using res_type = response_headers;
|
||||
static_assert(std::is_copy_constructible<res_type>::value, "");
|
||||
static_assert(std::is_move_constructible<res_type>::value, "");
|
||||
static_assert(std::is_copy_assignable<res_type>::value, "");
|
||||
@ -183,7 +183,7 @@ public:
|
||||
|
||||
{
|
||||
MoveHeaders h;
|
||||
request_headers<MoveHeaders> r{std::move(h)};
|
||||
message_headers<true, MoveHeaders> r{std::move(h)};
|
||||
BEAST_EXPECT(h.moved_from);
|
||||
BEAST_EXPECT(r.headers.moved_to);
|
||||
request<string_body, MoveHeaders> m{std::move(r)};
|
||||
|
@ -818,7 +818,8 @@ private:
|
||||
{
|
||||
return on_request(method, url,
|
||||
major, minor, keep_alive, upgrade,
|
||||
typename message_type::is_request{});
|
||||
std::integral_constant<
|
||||
bool, message_type::is_request>{});
|
||||
}
|
||||
|
||||
bool
|
||||
@ -847,7 +848,7 @@ private:
|
||||
{
|
||||
return on_response(
|
||||
status, reason, major, minor, keep_alive, upgrade,
|
||||
std::integral_constant<bool, ! message_type::is_request::value>{});
|
||||
std::integral_constant<bool, ! message_type::is_request>{});
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
streambuf rb;
|
||||
headers_parser_v1<true, headers> p0;
|
||||
parse(ss, rb, p0);
|
||||
request_headers<headers> const& reqh = p0.get();
|
||||
request_headers const& reqh = p0.get();
|
||||
BEAST_EXPECT(reqh.method == "GET");
|
||||
BEAST_EXPECT(reqh.url == "/");
|
||||
BEAST_EXPECT(reqh.version == 11);
|
||||
|
Reference in New Issue
Block a user