Refine message class hierarchy:

Two new objects, request_headers and response_headers,
represent the portion of HTTP messages excluding the body.
This commit is contained in:
Vinnie Falco
2016-10-20 17:22:36 -04:00
parent cf43f516d2
commit ada1f60e3e
31 changed files with 569 additions and 487 deletions
-1
View File
@@ -14,7 +14,6 @@
#include <beast/http/empty_body.hpp>
#include <beast/http/headers.hpp>
#include <beast/http/message.hpp>
#include <beast/http/message_v1.hpp>
#include <beast/http/parse.hpp>
#include <beast/http/parse_error.hpp>
#include <beast/http/parser_v1.hpp>
+4 -4
View File
@@ -251,14 +251,14 @@ public:
@note Meets the requirements of @b `FieldSequence`.
*/
template<class Allocator>
class basic_headers
class basic_headers :
#if ! GENERATING_DOCS
: private beast::detail::empty_base_optimization<
private beast::detail::empty_base_optimization<
typename std::allocator_traits<Allocator>::
template rebind_alloc<
detail::basic_headers_base::element>>
, public detail::basic_headers_base
detail::basic_headers_base::element>>,
#endif
public detail::basic_headers_base
{
using alloc_type = typename
std::allocator_traits<Allocator>::
@@ -5,13 +5,14 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BEAST_HTTP_IMPL_MESSAGE_V1_IPP
#define BEAST_HTTP_IMPL_MESSAGE_V1_IPP
#ifndef BEAST_HTTP_IMPL_MESSAGE_IPP
#define BEAST_HTTP_IMPL_MESSAGE_IPP
#include <beast/core/error.hpp>
#include <beast/http/concepts.hpp>
#include <beast/http/rfc7230.hpp>
#include <beast/core/detail/ci_char_traits.hpp>
#include <boost/assert.hpp>
#include <boost/optional.hpp>
#include <stdexcept>
@@ -20,9 +21,10 @@ namespace http {
template<bool isRequest, class Body, class Headers>
bool
is_keep_alive(message_v1<isRequest, Body, Headers> const& msg)
is_keep_alive(message<isRequest, Body, Headers> const& msg)
{
if(msg.version >= 11)
BOOST_ASSERT(msg.version == 10 || msg.version == 11);
if(msg.version == 11)
{
if(token_list{msg.headers["Connection"]}.exists("close"))
return false;
@@ -35,9 +37,10 @@ is_keep_alive(message_v1<isRequest, Body, Headers> const& msg)
template<bool isRequest, class Body, class Headers>
bool
is_upgrade(message_v1<isRequest, Body, Headers> const& msg)
is_upgrade(message<isRequest, Body, Headers> const& msg)
{
if(msg.version < 11)
BOOST_ASSERT(msg.version == 10 || msg.version == 11);
if(msg.version == 10)
return false;
if(token_list{msg.headers["Connection"]}.exists("upgrade"))
return true;
@@ -56,14 +59,14 @@ template<bool isRequest, class Body, class Headers>
inline
void
prepare_options(prepare_info& pi,
message_v1<isRequest, Body, Headers>& msg)
message<isRequest, Body, Headers>& msg)
{
}
template<bool isRequest, class Body, class Headers>
void
prepare_option(prepare_info& pi,
message_v1<isRequest, Body, Headers>& msg,
message<isRequest, Body, Headers>& msg,
connection value)
{
pi.connection_value = value;
@@ -74,7 +77,7 @@ template<
class Opt, class... Opts>
void
prepare_options(prepare_info& pi,
message_v1<isRequest, Body, Headers>& msg,
message<isRequest, Body, Headers>& msg,
Opt&& opt, Opts&&... opts)
{
prepare_option(pi, msg, opt);
@@ -85,7 +88,7 @@ prepare_options(prepare_info& pi,
template<bool isRequest, class Body, class Headers>
void
prepare_content_length(prepare_info& pi,
message_v1<isRequest, Body, Headers> const& msg,
message<isRequest, Body, Headers> const& msg,
std::true_type)
{
typename Body::writer w(msg);
@@ -100,7 +103,7 @@ prepare_content_length(prepare_info& pi,
template<bool isRequest, class Body, class Headers>
void
prepare_content_length(prepare_info& pi,
message_v1<isRequest, Body, Headers> const& msg,
message<isRequest, Body, Headers> const& msg,
std::false_type)
{
pi.content_length = boost::none;
@@ -112,7 +115,7 @@ template<
bool isRequest, class Body, class Headers,
class... Options>
void
prepare(message_v1<isRequest, Body, Headers>& msg,
prepare(message<isRequest, Body, Headers>& msg,
Options&&... options)
{
// VFALCO TODO
@@ -121,7 +124,7 @@ prepare(message_v1<isRequest, Body, Headers>& msg,
static_assert(has_writer<Body>::value,
"Body has no writer");
static_assert(is_Writer<typename Body::writer,
message_v1<isRequest, Body, Headers>>::value,
message<isRequest, Body, Headers>>::value,
"Writer requirements not met");
detail::prepare_info pi;
detail::prepare_content_length(pi, msg,
@@ -148,7 +151,7 @@ prepare(message_v1<isRequest, Body, Headers>& msg,
struct set_field
{
void
operator()(message_v1<true, Body, Headers>& msg,
operator()(message<true, Body, Headers>& msg,
detail::prepare_info const& pi) const
{
using beast::detail::ci_equal;
@@ -161,7 +164,7 @@ prepare(message_v1<isRequest, Body, Headers>& msg,
}
void
operator()(message_v1<false, Body, Headers>& msg,
operator()(message<false, Body, Headers>& msg,
detail::prepare_info const& pi) const
{
if((msg.status / 100 ) != 1 &&
+7 -7
View File
@@ -33,7 +33,7 @@ class read_op
parser_v1<isRequest, Body, Headers>;
using message_type =
message_v1<isRequest, Body, Headers>;
message<isRequest, Body, Headers>;
struct data
{
@@ -144,7 +144,7 @@ template<class SyncReadStream, class DynamicBuffer,
bool isRequest, class Body, class Headers>
void
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
message_v1<isRequest, Body, Headers>& msg)
message<isRequest, Body, Headers>& msg)
{
static_assert(is_SyncReadStream<SyncReadStream>::value,
"SyncReadStream requirements not met");
@@ -155,7 +155,7 @@ read(SyncReadStream& stream, DynamicBuffer& dynabuf,
static_assert(has_reader<Body>::value,
"Body has no reader");
static_assert(is_Reader<typename Body::reader,
message_v1<isRequest, Body, Headers>>::value,
message<isRequest, Body, Headers>>::value,
"Reader requirements not met");
error_code ec;
beast::http::read(stream, dynabuf, msg, ec);
@@ -167,7 +167,7 @@ template<class SyncReadStream, class DynamicBuffer,
bool isRequest, class Body, class Headers>
void
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
message_v1<isRequest, Body, Headers>& m,
message<isRequest, Body, Headers>& m,
error_code& ec)
{
static_assert(is_SyncReadStream<SyncReadStream>::value,
@@ -179,7 +179,7 @@ read(SyncReadStream& stream, DynamicBuffer& dynabuf,
static_assert(has_reader<Body>::value,
"Body has no reader");
static_assert(is_Reader<typename Body::reader,
message_v1<isRequest, Body, Headers>>::value,
message<isRequest, Body, Headers>>::value,
"Reader requirements not met");
parser_v1<isRequest, Body, Headers> p;
beast::http::parse(stream, dynabuf, p, ec);
@@ -195,7 +195,7 @@ template<class AsyncReadStream, class DynamicBuffer,
typename async_completion<
ReadHandler, void(error_code)>::result_type
async_read(AsyncReadStream& stream, DynamicBuffer& dynabuf,
message_v1<isRequest, Body, Headers>& m,
message<isRequest, Body, Headers>& m,
ReadHandler&& handler)
{
static_assert(is_AsyncReadStream<AsyncReadStream>::value,
@@ -207,7 +207,7 @@ async_read(AsyncReadStream& stream, DynamicBuffer& dynabuf,
static_assert(has_reader<Body>::value,
"Body has no reader");
static_assert(is_Reader<typename Body::reader,
message_v1<isRequest, Body, Headers>>::value,
message<isRequest, Body, Headers>>::value,
"Reader requirements not met");
beast::async_completion<ReadHandler,
void(error_code)> completion(handler);
+13 -13
View File
@@ -34,7 +34,7 @@ namespace detail {
template<class DynamicBuffer, class Body, class Headers>
void
write_firstline(DynamicBuffer& dynabuf,
message_v1<true, Body, Headers> const& msg)
message<true, Body, Headers> const& msg)
{
write(dynabuf, msg.method);
write(dynabuf, " ");
@@ -62,7 +62,7 @@ write_firstline(DynamicBuffer& dynabuf,
template<class DynamicBuffer, class Body, class Headers>
void
write_firstline(DynamicBuffer& dynabuf,
message_v1<false, Body, Headers> const& msg)
message<false, Body, Headers> const& msg)
{
switch(msg.version)
{
@@ -108,7 +108,7 @@ write_fields(DynamicBuffer& dynabuf, FieldSequence const& fields)
template<bool isRequest, class Body, class Headers>
struct write_preparation
{
message_v1<isRequest, Body, Headers> const& msg;
message<isRequest, Body, Headers> const& msg;
typename Body::writer w;
streambuf sb;
bool chunked;
@@ -116,7 +116,7 @@ struct write_preparation
explicit
write_preparation(
message_v1<isRequest, Body, Headers> const& msg_)
message<isRequest, Body, Headers> const& msg_)
: msg(msg_)
, w(msg)
, chunked(token_list{
@@ -161,7 +161,7 @@ class write_op
template<class DeducedHandler>
data(DeducedHandler&& h_, Stream& s_,
message_v1<isRequest, Body, Headers> const& m_)
message<isRequest, Body, Headers> const& m_)
: s(s_)
, wp(m_)
, h(std::forward<DeducedHandler>(h_))
@@ -467,7 +467,7 @@ template<class SyncWriteStream,
bool isRequest, class Body, class Headers>
void
write(SyncWriteStream& stream,
message_v1<isRequest, Body, Headers> const& msg)
message<isRequest, Body, Headers> const& msg)
{
static_assert(is_SyncWriteStream<SyncWriteStream>::value,
"SyncWriteStream requirements not met");
@@ -476,7 +476,7 @@ write(SyncWriteStream& stream,
static_assert(has_writer<Body>::value,
"Body has no writer");
static_assert(is_Writer<typename Body::writer,
message_v1<isRequest, Body, Headers>>::value,
message<isRequest, Body, Headers>>::value,
"Writer requirements not met");
error_code ec;
write(stream, msg, ec);
@@ -488,7 +488,7 @@ template<class SyncWriteStream,
bool isRequest, class Body, class Headers>
void
write(SyncWriteStream& stream,
message_v1<isRequest, Body, Headers> const& msg,
message<isRequest, Body, Headers> const& msg,
error_code& ec)
{
static_assert(is_SyncWriteStream<SyncWriteStream>::value,
@@ -498,7 +498,7 @@ write(SyncWriteStream& stream,
static_assert(has_writer<Body>::value,
"Body has no writer");
static_assert(is_Writer<typename Body::writer,
message_v1<isRequest, Body, Headers>>::value,
message<isRequest, Body, Headers>>::value,
"Writer requirements not met");
detail::write_preparation<isRequest, Body, Headers> wp(msg);
wp.init(ec);
@@ -584,7 +584,7 @@ template<class AsyncWriteStream,
typename async_completion<
WriteHandler, void(error_code)>::result_type
async_write(AsyncWriteStream& stream,
message_v1<isRequest, Body, Headers> const& msg,
message<isRequest, Body, Headers> const& msg,
WriteHandler&& handler)
{
static_assert(is_AsyncWriteStream<AsyncWriteStream>::value,
@@ -594,7 +594,7 @@ async_write(AsyncWriteStream& stream,
static_assert(has_writer<Body>::value,
"Body has no writer");
static_assert(is_Writer<typename Body::writer,
message_v1<isRequest, Body, Headers>>::value,
message<isRequest, Body, Headers>>::value,
"Writer requirements not met");
beast::async_completion<WriteHandler,
void(error_code)> completion(handler);
@@ -655,14 +655,14 @@ public:
template<bool isRequest, class Body, class Headers>
std::ostream&
operator<<(std::ostream& os,
message_v1<isRequest, Body, Headers> const& msg)
message<isRequest, Body, Headers> const& msg)
{
static_assert(is_Body<Body>::value,
"Body requirements not met");
static_assert(has_writer<Body>::value,
"Body has no writer");
static_assert(is_Writer<typename Body::writer,
message_v1<isRequest, Body, Headers>>::value,
message<isRequest, Body, Headers>>::value,
"Writer requirements not met");
detail::ostream_SyncStream oss(os);
error_code ec;
+248 -57
View File
@@ -18,41 +18,174 @@
namespace beast {
namespace http {
namespace detail {
/** A container for HTTP request headers.
struct request_fields
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<class Headers>
struct request_headers
{
/// Indicates if the message is a request.
using is_request =
std::integral_constant<bool, true>;
/// 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 method.
std::string method;
/// The request URI.
std::string url;
protected:
void
swap(request_fields& other)
/// The HTTP headers.
Headers headers;
/** Construct HTTP request headers.
Arguments, if any, are forwarded to the constructor
of the headers member.
*/
/** @{ */
request_headers() = default;
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>
explicit
request_headers(Arg1&& arg1, ArgN&&... argn)
: headers(std::forward<Arg1>(arg1),
std::forward<ArgN>(argn)...)
{
using std::swap;
swap(method, other.method);
swap(url, other.url);
}
/** @} */
};
struct response_fields
/** 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.
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<class Headers>
struct response_headers
{
/// Indicates if the message is a response.
using is_request =
std::integral_constant<bool, 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 response Status-Code.
int status;
/// The HTTP Reason-Phrase (obsolete).
std::string reason;
protected:
void
swap(response_fields& other)
/// The HTTP headers.
Headers headers;
/** Construct HTTP request headers.
Arguments, if any, are forwarded to the constructor
of the headers member.
*/
/** @{ */
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>
explicit
response_headers(Arg1&& arg1, ArgN&&... argn)
: headers(std::forward<Arg1>(arg1),
std::forward<ArgN>(argn)...)
{
using std::swap;
swap(status, other.status);
swap(reason, other.reason);
}
/** @} */
};
} // detail
/** Swap two HTTP response headers.
/** A HTTP message.
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.
*/
template<bool isRequest, class Headers>
using message_headers =
typename std::conditional<isRequest,
request_headers<Headers>,
response_headers<Headers>>::type;
/** 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,
@@ -68,37 +201,56 @@ protected:
@tparam Headers A type meeting the requirements of Headers.
*/
template<bool isRequest, class Body, class Headers>
struct message
: std::conditional<isRequest,
detail::request_fields, detail::response_fields>::type
struct message : message_headers<isRequest, Headers>
{
/// The container used to hold the request or response headers
using base_type = message_headers<isRequest, Headers>;
/** The type controlling the body traits.
The body member will be of type `body_type::value_type`.
*/
using body_type = Body;
/// The type representing the headers.
using headers_type = Headers;
/// Indicates if the message is a request.
using is_request =
std::integral_constant<bool, isRequest>;
/// The container holding the headers.
headers_type headers;
/// A container representing the body.
typename Body::value_type body;
/// Default constructor
message() = default;
/** Construct a message from headers.
Additional arguments, if any, are forwarded to
the constructor of the body member.
*/
template<class... Args>
explicit
message(base_type&& base, Args&&... args)
: base_type(std::move(base))
, body(std::forward<Args>(args)...)
{
}
/** Construct a message from headers.
Additional arguments, if any, are forwarded to
the constructor of the body member.
*/
template<class... Args>
explicit
message(base_type const& base, Args&&... args)
: base_type(base)
, body(std::forward<Args>(args)...)
{
}
/** Construct a message.
@param u An argument forwarded to the body constructor.
*/
template<class U>
template<class U,
class = typename std::enable_if<! std::is_same<
typename std::decay<U>::type, base_type>::value>>
explicit
message(U&& u)
: body(std::forward<U>(u))
@@ -110,9 +262,11 @@ struct message
@param u An argument forwarded to the body constructor.
@param v An argument forwarded to the headers constructor.
*/
template<class U, class V>
template<class U, class V,
class = typename std::enable_if<! std::is_same<
typename std::decay<U>::type, base_type>::value>>
message(U&& u, V&& v)
: headers(std::forward<V>(v))
: base_type(std::forward<V>(v))
, body(std::forward<U>(u))
{
}
@@ -126,7 +280,6 @@ struct message
: message(std::piecewise_construct, un,
beast::detail::make_index_sequence<sizeof...(Un)>{})
{
}
/** Construct a message.
@@ -143,14 +296,7 @@ struct message
{
}
/// Swap this message for another message.
void
swap(message& other);
private:
using base = typename std::conditional<isRequest,
detail::request_fields, detail::response_fields>::type;
template<class... Un, size_t... IUn>
message(std::piecewise_construct_t,
std::tuple<Un...>& tu, beast::detail::index_sequence<IUn...>)
@@ -164,31 +310,25 @@ private:
std::tuple<Un...>& tu, std::tuple<Vn...>& tv,
beast::detail::index_sequence<IUn...>,
beast::detail::index_sequence<IVn...>)
: headers(std::forward<Vn>(std::get<IVn>(tv))...)
: base_type(std::forward<Vn>(std::get<IVn>(tv))...)
, body(std::forward<Un>(std::get<IUn>(tu))...)
{
}
};
template<bool isRequest, class Body, class Headers>
void
message<isRequest, Body, Headers>::
swap(message& other)
{
using std::swap;
base::swap(other);
swap(headers, other.headers);
swap(body, other.body);
}
/// Swap one message for another message.
template<bool isRequest, class Body, class Headers>
inline
void
swap(message<isRequest, Body, Headers>& lhs,
message<isRequest, Body, Headers>& rhs)
swap(
message<isRequest, Body, Headers>& a,
message<isRequest, Body, Headers>& b)
{
lhs.swap(rhs);
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);
}
/// A typical HTTP request
@@ -201,7 +341,58 @@ 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.
*/
template<bool isRequest, class Body, class Headers>
bool
is_keep_alive(message<isRequest, Body, Headers> 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 isRequest, class Body, class Headers>
bool
is_upgrade(message<isRequest, Body, Headers> 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<isRequest, Body, Headers>& msg,
Options&&... options);
} // http
} // beast
#include <beast/http/impl/message.ipp>
#endif
-139
View File
@@ -1,139 +0,0 @@
//
// 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_V1_HPP
#define BEAST_HTTP_MESSAGE_V1_HPP
#include <beast/http/message.hpp>
#include <memory>
#include <string>
#include <type_traits>
namespace beast {
namespace http {
/** A HTTP/1 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 is a request.
@tparam Body A type meeting the requirements of Body.
@tparam Headers A type meeting the requirements of Headers.
*/
template<bool isRequest, class Body, class Headers>
struct message_v1 : message<isRequest, Body, Headers>
{
/// HTTP/1 version (10 or 11)
int version;
/// Default constructor
message_v1() = default;
/// Constructor
template<class Arg1, class... Argn,
class = typename std::enable_if<
! std::is_convertible<message_v1,
typename std::decay<Arg1>::type>::value>::type>
explicit
message_v1(Arg1&& arg1, Argn&&... argn)
: message<isRequest, Body, Headers>(
std::forward<Arg1>(arg1),
std::forward<Argn>(argn)...)
{
}
/// Swap this message for another message.
void
swap(message_v1& other);
};
template<bool isRequest, class Body, class Headers>
void
message_v1<isRequest, Body, Headers>::
swap(message_v1& other)
{
using std::swap;
message<isRequest, Body, Headers>::swap(other);
swap(version, other.version);
}
/// Swap one message for another message.
template<bool isRequest, class Body, class Headers>
inline
void
swap(message_v1<isRequest, Body, Headers>& lhs,
message_v1<isRequest, Body, Headers>& rhs)
{
lhs.swap(rhs);
}
/// A typical HTTP/1 request
template<class Body,
class Headers = basic_headers<std::allocator<char>>>
using request_v1 = message_v1<true, Body, Headers>;
/// A typical HTTP/1 response
template<class Body,
class Headers = basic_headers<std::allocator<char>>>
using response_v1 = message_v1<false, Body, Headers>;
/// Returns `true` if a HTTP/1 message indicates a keep alive
template<bool isRequest, class Body, class Headers>
bool
is_keep_alive(message_v1<isRequest, Body, Headers> const& msg);
/// Returns `true` if a HTTP/1 message indicates an Upgrade request or response
template<bool isRequest, class Body, class Headers>
bool
is_upgrade(message_v1<isRequest, Body, Headers> 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/1 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_v1<isRequest, Body, Headers>& msg,
Options&&... options);
} // http
} // beast
#include <beast/http/impl/message_v1.ipp>
#endif
+3 -3
View File
@@ -10,7 +10,7 @@
#include <beast/http/basic_parser_v1.hpp>
#include <beast/http/concepts.hpp>
#include <beast/http/message_v1.hpp>
#include <beast/http/message.hpp>
#include <beast/core/error.hpp>
#include <boost/assert.hpp>
#include <boost/optional.hpp>
@@ -71,7 +71,7 @@ struct skip_body
/** A parser for producing HTTP/1 messages.
This class uses the basic HTTP/1 wire format parser to convert
a series of octets into a `message_v1`.
a series of octets into a `message`.
@note A new instance of the parser is required for each message.
*/
@@ -85,7 +85,7 @@ class parser_v1
public:
/// The type of message this parser produces.
using message_type =
message_v1<isRequest, Body, Headers>;
message<isRequest, Body, Headers>;
private:
using reader =
+4 -4
View File
@@ -10,7 +10,7 @@
#include <beast/core/async_completion.hpp>
#include <beast/core/error.hpp>
#include <beast/http/message_v1.hpp>
#include <beast/http/message.hpp>
namespace beast {
namespace http {
@@ -49,7 +49,7 @@ template<class SyncReadStream, class DynamicBuffer,
bool isRequest, class Body, class Headers>
void
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
message_v1<isRequest, Body, Headers>& msg);
message<isRequest, Body, Headers>& msg);
/** Read a HTTP/1 message from a stream.
@@ -85,7 +85,7 @@ template<class SyncReadStream, class DynamicBuffer,
bool isRequest, class Body, class Headers>
void
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
message_v1<isRequest, Body, Headers>& msg,
message<isRequest, Body, Headers>& msg,
error_code& ec);
/** Start an asynchronous operation to read a HTTP/1 message from a stream.
@@ -136,7 +136,7 @@ typename async_completion<
ReadHandler, void(error_code)>::result_type
#endif
async_read(AsyncReadStream& stream, DynamicBuffer& dynabuf,
message_v1<isRequest, Body, Headers>& msg,
message<isRequest, Body, Headers>& msg,
ReadHandler&& handler);
} // http
+5 -5
View File
@@ -8,7 +8,7 @@
#ifndef BEAST_HTTP_WRITE_HPP
#define BEAST_HTTP_WRITE_HPP
#include <beast/http/message_v1.hpp>
#include <beast/http/message.hpp>
#include <beast/core/error.hpp>
#include <beast/core/async_completion.hpp>
#include <ostream>
@@ -46,7 +46,7 @@ template<class SyncWriteStream,
bool isRequest, class Body, class Headers>
void
write(SyncWriteStream& stream,
message_v1<isRequest, Body, Headers> const& msg);
message<isRequest, Body, Headers> const& msg);
/** Write a HTTP/1 message on a stream.
@@ -77,7 +77,7 @@ template<class SyncWriteStream,
bool isRequest, class Body, class Headers>
void
write(SyncWriteStream& stream,
message_v1<isRequest, Body, Headers> const& msg,
message<isRequest, Body, Headers> const& msg,
error_code& ec);
/** Start an asynchronous operation to write a HTTP/1 message to a stream.
@@ -132,7 +132,7 @@ typename async_completion<
WriteHandler, void(error_code)>::result_type
#endif
async_write(AsyncWriteStream& stream,
message_v1<isRequest, Body, Headers> const& msg,
message<isRequest, Body, Headers> const& msg,
WriteHandler&& handler);
/** Serialize a HTTP/1 message to an ostream.
@@ -150,7 +150,7 @@ async_write(AsyncWriteStream& stream,
template<bool isRequest, class Body, class Headers>
std::ostream&
operator<<(std::ostream& os,
message_v1<isRequest, Body, Headers> const& msg);
message<isRequest, Body, Headers> const& msg);
} // http
} // beast
+2 -2
View File
@@ -9,7 +9,7 @@
#define BEAST_WEBSOCKET_IMPL_ACCEPT_OP_HPP
#include <beast/websocket/impl/response_op.ipp>
#include <beast/http/message_v1.hpp>
#include <beast/http/message.hpp>
#include <beast/http/parser_v1.hpp>
#include <beast/http/read.hpp>
#include <beast/core/handler_alloc.hpp>
@@ -33,7 +33,7 @@ class stream<NextLayer>::accept_op
struct data
{
stream<NextLayer>& ws;
http::request_v1<http::string_body> req;
http::request<http::string_body> req;
Handler h;
bool cont;
int state = 0;
@@ -9,7 +9,7 @@
#define BEAST_WEBSOCKET_IMPL_HANDSHAKE_OP_HPP
#include <beast/http/empty_body.hpp>
#include <beast/http/message_v1.hpp>
#include <beast/http/message.hpp>
#include <beast/http/read.hpp>
#include <beast/http/write.hpp>
#include <beast/core/handler_alloc.hpp>
@@ -33,8 +33,8 @@ class stream<NextLayer>::handshake_op
stream<NextLayer>& ws;
Handler h;
std::string key;
http::request_v1<http::empty_body> req;
http::response_v1<http::string_body> resp;
http::request<http::empty_body> req;
http::response<http::string_body> resp;
bool cont;
int state = 0;
+3 -3
View File
@@ -8,7 +8,7 @@
#ifndef BEAST_WEBSOCKET_IMPL_RESPONSE_OP_HPP
#define BEAST_WEBSOCKET_IMPL_RESPONSE_OP_HPP
#include <beast/http/message_v1.hpp>
#include <beast/http/message.hpp>
#include <beast/http/string_body.hpp>
#include <beast/http/write.hpp>
#include <beast/core/handler_alloc.hpp>
@@ -28,7 +28,7 @@ class stream<NextLayer>::response_op
struct data
{
stream<NextLayer>& ws;
http::response_v1<http::string_body> resp;
http::response<http::string_body> resp;
Handler h;
error_code final_ec;
bool cont;
@@ -37,7 +37,7 @@ class stream<NextLayer>::response_op
template<class DeducedHandler,
class Body, class Headers>
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
http::request_v1<Body, Headers> const& req,
http::request<Body, Headers> const& req,
bool cont_)
: ws(ws_)
, resp(ws_.build_response(req))
+13 -13
View File
@@ -116,7 +116,7 @@ accept(ConstBufferSequence const& buffers, error_code& ec)
stream_.buffer().commit(buffer_copy(
stream_.buffer().prepare(
buffer_size(buffers)), buffers));
http::request_v1<http::string_body> m;
http::request<http::string_body> m;
http::read(next_layer(), stream_.buffer(), m, ec);
if(ec)
return;
@@ -147,7 +147,7 @@ template<class NextLayer>
template<class Body, class Headers>
void
stream<NextLayer>::
accept(http::request_v1<Body, Headers> const& request)
accept(http::request<Body, Headers> const& request)
{
static_assert(is_SyncStream<next_layer_type>::value,
"SyncStream requirements not met");
@@ -161,7 +161,7 @@ template<class NextLayer>
template<class Body, class Headers>
void
stream<NextLayer>::
accept(http::request_v1<Body, Headers> const& req,
accept(http::request<Body, Headers> const& req,
error_code& ec)
{
static_assert(is_SyncStream<next_layer_type>::value,
@@ -186,7 +186,7 @@ template<class Body, class Headers, class AcceptHandler>
typename async_completion<
AcceptHandler, void(error_code)>::result_type
stream<NextLayer>::
async_accept(http::request_v1<Body, Headers> const& req,
async_accept(http::request<Body, Headers> const& req,
AcceptHandler&& handler)
{
static_assert(is_AsyncStream<next_layer_type>::value,
@@ -230,7 +230,7 @@ handshake(boost::string_ref const& host,
build_request(host, resource, key), ec);
if(ec)
return;
http::response_v1<http::string_body> res;
http::response<http::string_body> res;
http::read(next_layer(), stream_.buffer(), res, ec);
if(ec)
return;
@@ -839,12 +839,12 @@ reset()
}
template<class NextLayer>
http::request_v1<http::empty_body>
http::request<http::empty_body>
stream<NextLayer>::
build_request(boost::string_ref const& host,
boost::string_ref const& resource, std::string& key)
{
http::request_v1<http::empty_body> req;
http::request<http::empty_body> req;
req.url = { resource.data(), resource.size() };
req.version = 11;
req.method = "GET";
@@ -860,14 +860,14 @@ build_request(boost::string_ref const& host,
template<class NextLayer>
template<class Body, class Headers>
http::response_v1<http::string_body>
http::response<http::string_body>
stream<NextLayer>::
build_response(http::request_v1<Body, Headers> const& req)
build_response(http::request<Body, Headers> const& req)
{
auto err =
[&](std::string const& text)
{
http::response_v1<http::string_body> res;
http::response<http::string_body> res;
res.status = 400;
res.reason = http::reason_string(res.status);
res.version = req.version;
@@ -898,7 +898,7 @@ build_response(http::request_v1<Body, Headers> const& req)
return err("Missing Sec-WebSocket-Version");
if(version != "13")
{
http::response_v1<http::string_body> res;
http::response<http::string_body> res;
res.status = 426;
res.reason = http::reason_string(res.status);
res.version = req.version;
@@ -910,7 +910,7 @@ build_response(http::request_v1<Body, Headers> const& req)
return res;
}
}
http::response_v1<http::string_body> res;
http::response<http::string_body> res;
res.status = 101;
res.reason = http::reason_string(res.status);
res.version = req.version;
@@ -931,7 +931,7 @@ template<class NextLayer>
template<class Body, class Headers>
void
stream<NextLayer>::
do_response(http::response_v1<Body, Headers> const& res,
do_response(http::response<Body, Headers> const& res,
boost::string_ref const& key, error_code& ec)
{
// VFALCO Review these error codes
+8 -8
View File
@@ -10,7 +10,7 @@
#include <beast/websocket/option.hpp>
#include <beast/websocket/detail/stream_base.hpp>
#include <beast/http/message_v1.hpp>
#include <beast/http/message.hpp>
#include <beast/http/string_body.hpp>
#include <beast/core/dynabuf_readstream.hpp>
#include <beast/core/async_completion.hpp>
@@ -586,7 +586,7 @@ public:
// VFALCO TODO This should also take a DynamicBuffer with any leftover bytes.
template<class Body, class Headers>
void
accept(http::request_v1<Body, Headers> const& request);
accept(http::request<Body, Headers> const& request);
/** Respond to a WebSocket HTTP Upgrade request
@@ -618,7 +618,7 @@ public:
*/
template<class Body, class Headers>
void
accept(http::request_v1<Body, Headers> const& request,
accept(http::request<Body, Headers> const& request,
error_code& ec);
/** Start responding to a WebSocket HTTP Upgrade request.
@@ -669,7 +669,7 @@ public:
typename async_completion<
AcceptHandler, void(error_code)>::result_type
#endif
async_accept(http::request_v1<Body, Headers> const& request,
async_accept(http::request<Body, Headers> const& request,
AcceptHandler&& handler);
/** Send a HTTP WebSocket Upgrade request and receive the response.
@@ -1530,18 +1530,18 @@ private:
void
reset();
http::request_v1<http::empty_body>
http::request<http::empty_body>
build_request(boost::string_ref const& host,
boost::string_ref const& resource,
std::string& key);
template<class Body, class Headers>
http::response_v1<http::string_body>
build_response(http::request_v1<Body, Headers> const& req);
http::response<http::string_body>
build_response(http::request<Body, Headers> const& req);
template<class Body, class Headers>
void
do_response(http::response_v1<Body, Headers> const& resp,
do_response(http::response<Body, Headers> const& resp,
boost::string_ref const& key, error_code& ec);
void