2017-05-28 17:04:39 -07:00
|
|
|
//
|
|
|
|
// Copyright (c) 2013-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)
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef BEAST_HTTP_SERIALIZER_HPP
|
|
|
|
#define BEAST_HTTP_SERIALIZER_HPP
|
|
|
|
|
|
|
|
#include <beast/config.hpp>
|
|
|
|
#include <beast/core/buffer_cat.hpp>
|
2017-07-06 20:58:07 -07:00
|
|
|
#include <beast/core/buffer_prefix.hpp>
|
2017-05-28 17:04:39 -07:00
|
|
|
#include <beast/core/consuming_buffers.hpp>
|
2017-06-16 09:38:53 -07:00
|
|
|
#include <beast/core/string.hpp>
|
2017-05-28 17:04:39 -07:00
|
|
|
#include <beast/core/type_traits.hpp>
|
|
|
|
#include <beast/http/message.hpp>
|
|
|
|
#include <beast/http/detail/chunk_encode.hpp>
|
|
|
|
#include <boost/asio/buffer.hpp>
|
|
|
|
#include <boost/optional.hpp>
|
|
|
|
#include <boost/variant.hpp>
|
|
|
|
|
2017-06-26 18:26:35 -07:00
|
|
|
#ifndef BEAST_NO_BIG_VARIANTS
|
|
|
|
# if defined(BOOST_GCC) && BOOST_GCC < 50000 && BOOST_VERSION < 106400
|
2017-07-06 20:44:57 -07:00
|
|
|
# define BEAST_NO_BIG_VARIANTS
|
2017-06-26 18:26:35 -07:00
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2017-05-28 17:04:39 -07:00
|
|
|
namespace beast {
|
|
|
|
namespace http {
|
|
|
|
|
|
|
|
/** A chunk decorator which does nothing.
|
|
|
|
|
|
|
|
When selected as a chunk decorator, objects of this type
|
|
|
|
affect the output of messages specifying chunked
|
|
|
|
transfer encodings as follows:
|
|
|
|
|
|
|
|
@li chunk headers will have empty chunk extensions, and
|
|
|
|
|
|
|
|
@li final chunks will have an empty set of trailers.
|
|
|
|
|
|
|
|
@see @ref serializer
|
|
|
|
*/
|
2017-06-03 06:49:11 -07:00
|
|
|
struct no_chunk_decorator
|
2017-05-28 17:04:39 -07:00
|
|
|
{
|
|
|
|
template<class ConstBufferSequence>
|
|
|
|
string_view
|
|
|
|
operator()(ConstBufferSequence const&) const
|
|
|
|
{
|
2017-06-03 06:49:11 -07:00
|
|
|
return {};
|
2017-05-28 17:04:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
string_view
|
|
|
|
operator()(boost::asio::null_buffers) const
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Provides buffer oriented HTTP message serialization functionality.
|
|
|
|
|
|
|
|
An object of this type is used to serialize a complete
|
2017-06-22 07:48:05 -07:00
|
|
|
HTTP message into a sequence of octets. To use this class,
|
2017-05-28 17:04:39 -07:00
|
|
|
construct an instance with the message to be serialized.
|
|
|
|
|
|
|
|
The implementation will automatically perform chunk encoding
|
|
|
|
if the contents of the message indicate that chunk encoding
|
|
|
|
is required. If the semantics of the message indicate that
|
|
|
|
the connection should be closed after the message is sent, the
|
2017-07-07 23:05:11 -07:00
|
|
|
function @ref keep_alive will return `true`.
|
2017-05-28 17:04:39 -07:00
|
|
|
|
|
|
|
Upon construction, an optional chunk decorator may be
|
|
|
|
specified. This decorator is a function object called with
|
|
|
|
each buffer sequence of the body when the chunked transfer
|
|
|
|
encoding is indicate in the message header. The decorator
|
|
|
|
will be called with an empty buffer sequence (actually
|
|
|
|
the type `boost::asio::null_buffers`) to indicate the
|
|
|
|
final chunk. The decorator may return a string which forms
|
|
|
|
the chunk extension for chunks, and the field trailers
|
|
|
|
for the final chunk.
|
|
|
|
|
|
|
|
In C++11 the decorator must be declared as a class or
|
|
|
|
struct with a templated operator() thusly:
|
|
|
|
|
|
|
|
@code
|
2017-06-03 18:40:28 -07:00
|
|
|
// The implementation guarantees that operator()
|
|
|
|
// will be called only after the view returned by
|
|
|
|
// any previous calls to operator() are no longer
|
|
|
|
// needed. The decorator instance is intended to
|
|
|
|
// manage the lifetime of the storage for all returned
|
|
|
|
// views.
|
|
|
|
//
|
|
|
|
struct decorator
|
|
|
|
{
|
|
|
|
// Returns the chunk-extension for each chunk,
|
|
|
|
// or an empty string for no chunk extension. The
|
|
|
|
// buffer must include the leading semicolon (";")
|
|
|
|
// and follow the format for chunk extensions defined
|
|
|
|
// in rfc7230.
|
|
|
|
//
|
|
|
|
template<class ConstBufferSequence>
|
|
|
|
string_view
|
|
|
|
operator()(ConstBufferSequence const&) const;
|
|
|
|
|
|
|
|
// Returns a set of field trailers for the final chunk.
|
|
|
|
// Each field should be formatted according to rfc7230
|
|
|
|
// including the trailing "\r\n" for each field. If
|
|
|
|
// no trailers are indicated, an empty string is returned.
|
2017-05-28 17:04:39 -07:00
|
|
|
//
|
2017-06-03 18:40:28 -07:00
|
|
|
string_view
|
|
|
|
operator()(boost::asio::null_buffers) const;
|
|
|
|
};
|
2017-05-28 17:04:39 -07:00
|
|
|
@endcode
|
|
|
|
|
|
|
|
@tparam isRequest `true` if the message is a request.
|
|
|
|
|
|
|
|
@tparam Body The body type of the message.
|
|
|
|
|
|
|
|
@tparam Fields The type of fields in the message.
|
|
|
|
|
2017-06-03 06:49:11 -07:00
|
|
|
@tparam ChunkDecorator The type of chunk decorator to use.
|
2017-05-28 17:04:39 -07:00
|
|
|
*/
|
|
|
|
template<
|
2017-06-22 07:48:05 -07:00
|
|
|
bool isRequest,
|
|
|
|
class Body,
|
|
|
|
class Fields = fields,
|
2017-06-07 05:10:58 -07:00
|
|
|
class ChunkDecorator = no_chunk_decorator>
|
2017-05-28 17:04:39 -07:00
|
|
|
class serializer
|
|
|
|
{
|
2017-07-07 14:32:51 -07:00
|
|
|
public:
|
2017-05-28 17:04:39 -07:00
|
|
|
static_assert(is_body<Body>::value,
|
|
|
|
"Body requirements not met");
|
2017-07-07 14:32:51 -07:00
|
|
|
|
2017-05-28 17:04:39 -07:00
|
|
|
static_assert(is_body_reader<Body>::value,
|
|
|
|
"BodyReader requirements not met");
|
|
|
|
|
2017-07-07 20:08:52 -07:00
|
|
|
/** The type of message this serializer uses
|
2017-07-07 14:32:51 -07:00
|
|
|
|
|
|
|
This may be const or non-const depending on the
|
|
|
|
implementation of the corresponding @b BodyReader.
|
|
|
|
*/
|
|
|
|
#if BEAST_DOXYGEN
|
|
|
|
using value_type = implementation_defined;
|
|
|
|
#else
|
|
|
|
using value_type =
|
|
|
|
typename std::conditional<
|
|
|
|
std::is_constructible<typename Body::reader,
|
2017-07-07 20:08:52 -07:00
|
|
|
message<isRequest, Body, Fields>&>::value &&
|
2017-07-07 14:32:51 -07:00
|
|
|
! std::is_constructible<typename Body::reader,
|
2017-07-07 20:08:52 -07:00
|
|
|
message<isRequest, Body, Fields> const&>::value,
|
2017-07-07 14:32:51 -07:00
|
|
|
message<isRequest, Body, Fields>,
|
|
|
|
message<isRequest, Body, Fields> const>::type;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
private:
|
2017-05-28 17:04:39 -07:00
|
|
|
enum
|
|
|
|
{
|
2017-05-31 08:01:55 -07:00
|
|
|
do_construct = 0,
|
|
|
|
|
|
|
|
do_init = 10,
|
|
|
|
do_header_only = 20,
|
|
|
|
do_header = 30,
|
2017-05-28 17:04:39 -07:00
|
|
|
do_body = 40,
|
|
|
|
|
|
|
|
do_init_c = 50,
|
|
|
|
do_header_only_c = 60,
|
|
|
|
do_header_c = 70,
|
2017-06-26 18:26:35 -07:00
|
|
|
do_body_c = 80,
|
|
|
|
do_final_c = 90,
|
2017-07-06 20:44:57 -07:00
|
|
|
#ifndef BEAST_NO_BIG_VARIANTS
|
2017-06-26 18:26:35 -07:00
|
|
|
do_body_final_c = 100,
|
|
|
|
do_all_c = 110,
|
|
|
|
#endif
|
|
|
|
|
|
|
|
do_complete = 120
|
2017-05-28 17:04:39 -07:00
|
|
|
};
|
|
|
|
|
2017-06-06 17:26:11 -07:00
|
|
|
void frdinit(std::true_type);
|
|
|
|
void frdinit(std::false_type);
|
2017-05-28 17:04:39 -07:00
|
|
|
|
2017-07-06 20:58:07 -07:00
|
|
|
template<class T1, class T2, class Visit>
|
|
|
|
void
|
|
|
|
do_visit(error_code& ec, Visit& visit);
|
|
|
|
|
2017-05-28 17:04:39 -07:00
|
|
|
using reader = typename Body::reader;
|
|
|
|
|
2017-07-06 20:58:07 -07:00
|
|
|
using cb1_t = consuming_buffers<typename
|
2017-06-06 17:26:11 -07:00
|
|
|
Fields::reader::const_buffers_type>; // header
|
2017-07-06 20:58:07 -07:00
|
|
|
using pcb1_t = buffer_prefix_view<cb1_t const&>;
|
2017-06-06 17:26:11 -07:00
|
|
|
|
2017-07-06 20:58:07 -07:00
|
|
|
using cb2_t = consuming_buffers<buffer_cat_view<
|
2017-06-06 17:26:11 -07:00
|
|
|
typename Fields::reader::const_buffers_type,// header
|
2017-05-28 17:04:39 -07:00
|
|
|
typename reader::const_buffers_type>>; // body
|
2017-07-06 20:58:07 -07:00
|
|
|
using pcb2_t = buffer_prefix_view<cb2_t const&>;
|
2017-05-28 17:04:39 -07:00
|
|
|
|
2017-07-06 20:58:07 -07:00
|
|
|
using cb3_t = consuming_buffers<
|
2017-05-28 17:04:39 -07:00
|
|
|
typename reader::const_buffers_type>; // body
|
2017-07-06 20:58:07 -07:00
|
|
|
using pcb3_t = buffer_prefix_view<cb3_t const&>;
|
2017-05-28 17:04:39 -07:00
|
|
|
|
2017-07-06 20:58:07 -07:00
|
|
|
using cb4_t = consuming_buffers<buffer_cat_view<
|
2017-06-06 17:26:11 -07:00
|
|
|
typename Fields::reader::const_buffers_type,// header
|
2017-05-28 17:04:39 -07:00
|
|
|
detail::chunk_header, // chunk-header
|
2017-06-03 06:49:11 -07:00
|
|
|
boost::asio::const_buffers_1, // chunk-ext
|
|
|
|
boost::asio::const_buffers_1, // crlf
|
2017-05-28 17:04:39 -07:00
|
|
|
typename reader::const_buffers_type, // body
|
|
|
|
boost::asio::const_buffers_1>>; // crlf
|
2017-07-06 20:58:07 -07:00
|
|
|
using pcb4_t = buffer_prefix_view<cb4_t const&>;
|
2017-06-26 18:26:35 -07:00
|
|
|
|
2017-07-06 20:58:07 -07:00
|
|
|
using cb5_t = consuming_buffers<buffer_cat_view<
|
2017-05-28 17:04:39 -07:00
|
|
|
detail::chunk_header, // chunk-header
|
2017-06-03 06:49:11 -07:00
|
|
|
boost::asio::const_buffers_1, // chunk-ext
|
|
|
|
boost::asio::const_buffers_1, // crlf
|
2017-05-28 17:04:39 -07:00
|
|
|
typename reader::const_buffers_type, // body
|
|
|
|
boost::asio::const_buffers_1>>; // crlf
|
2017-07-06 20:58:07 -07:00
|
|
|
using pcb5_t = buffer_prefix_view<cb5_t const&>;
|
2017-05-28 17:04:39 -07:00
|
|
|
|
2017-07-06 20:44:57 -07:00
|
|
|
#ifndef BEAST_NO_BIG_VARIANTS
|
2017-07-06 20:58:07 -07:00
|
|
|
using cb6_t = consuming_buffers<buffer_cat_view<
|
2017-06-26 18:26:35 -07:00
|
|
|
detail::chunk_header, // chunk-header
|
|
|
|
boost::asio::const_buffers_1, // chunk-ext
|
|
|
|
boost::asio::const_buffers_1, // crlf
|
|
|
|
typename reader::const_buffers_type, // body
|
|
|
|
boost::asio::const_buffers_1, // crlf
|
|
|
|
boost::asio::const_buffers_1, // chunk-final
|
|
|
|
boost::asio::const_buffers_1, // trailers
|
|
|
|
boost::asio::const_buffers_1>>; // crlf
|
2017-07-06 20:58:07 -07:00
|
|
|
using pcb6_t = buffer_prefix_view<cb6_t const&>;
|
2017-06-26 18:26:35 -07:00
|
|
|
|
2017-07-06 20:58:07 -07:00
|
|
|
using cb7_t = consuming_buffers<buffer_cat_view<
|
2017-06-26 18:26:35 -07:00
|
|
|
typename Fields::reader::const_buffers_type,// header
|
|
|
|
detail::chunk_header, // chunk-header
|
|
|
|
boost::asio::const_buffers_1, // chunk-ext
|
|
|
|
boost::asio::const_buffers_1, // crlf
|
|
|
|
typename reader::const_buffers_type, // body
|
|
|
|
boost::asio::const_buffers_1, // crlf
|
|
|
|
boost::asio::const_buffers_1, // chunk-final
|
|
|
|
boost::asio::const_buffers_1, // trailers
|
|
|
|
boost::asio::const_buffers_1>>; // crlf
|
2017-07-06 20:58:07 -07:00
|
|
|
using pcb7_t = buffer_prefix_view<cb7_t const&>;
|
2017-06-26 18:26:35 -07:00
|
|
|
#endif
|
|
|
|
|
2017-07-06 20:58:07 -07:00
|
|
|
using cb8_t = consuming_buffers<buffer_cat_view<
|
2017-05-28 17:04:39 -07:00
|
|
|
boost::asio::const_buffers_1, // chunk-final
|
|
|
|
boost::asio::const_buffers_1, // trailers
|
|
|
|
boost::asio::const_buffers_1>>; // crlf
|
2017-07-06 20:58:07 -07:00
|
|
|
using pcb8_t = buffer_prefix_view<cb8_t const&>;
|
2017-05-28 17:04:39 -07:00
|
|
|
|
2017-07-07 14:32:51 -07:00
|
|
|
value_type& m_;
|
2017-07-07 20:08:52 -07:00
|
|
|
reader rd_;
|
2017-06-06 17:26:11 -07:00
|
|
|
boost::optional<typename Fields::reader> frd_;
|
2017-05-28 17:04:39 -07:00
|
|
|
boost::variant<boost::blank,
|
2017-07-06 20:58:07 -07:00
|
|
|
cb1_t, cb2_t, cb3_t, cb4_t, cb5_t
|
|
|
|
#ifndef BEAST_NO_BIG_VARIANTS
|
|
|
|
,cb6_t, cb7_t
|
|
|
|
#endif
|
|
|
|
, cb8_t> v_;
|
|
|
|
boost::variant<boost::blank,
|
|
|
|
pcb1_t, pcb2_t, pcb3_t, pcb4_t, pcb5_t
|
2017-07-06 20:44:57 -07:00
|
|
|
#ifndef BEAST_NO_BIG_VARIANTS
|
2017-07-06 20:58:07 -07:00
|
|
|
,pcb6_t, pcb7_t
|
2017-06-26 18:26:35 -07:00
|
|
|
#endif
|
2017-07-06 20:58:07 -07:00
|
|
|
, pcb8_t> pv_;
|
|
|
|
std::size_t limit_ =
|
|
|
|
(std::numeric_limits<std::size_t>::max)();
|
2017-05-31 08:01:55 -07:00
|
|
|
int s_ = do_construct;
|
2017-06-25 10:14:18 -07:00
|
|
|
bool split_ = false;
|
2017-05-28 17:04:39 -07:00
|
|
|
bool header_done_ = false;
|
|
|
|
bool chunked_;
|
2017-07-07 23:05:11 -07:00
|
|
|
bool keep_alive_;
|
2017-05-28 17:04:39 -07:00
|
|
|
bool more_;
|
2017-06-07 05:10:58 -07:00
|
|
|
ChunkDecorator d_;
|
2017-05-28 17:04:39 -07:00
|
|
|
|
|
|
|
public:
|
|
|
|
/** Constructor
|
|
|
|
|
2017-05-31 08:01:55 -07:00
|
|
|
The implementation guarantees that the message passed on
|
|
|
|
construction will not be accessed until the first call to
|
2017-07-04 01:17:56 -07:00
|
|
|
@ref next. This allows the message to be lazily created.
|
2017-05-31 08:01:55 -07:00
|
|
|
For example, if the header is filled in before serialization.
|
|
|
|
|
2017-07-07 14:32:51 -07:00
|
|
|
@param msg A reference to the message to serialize, which must
|
|
|
|
remain valid for the lifetime of the serializer. Depending on
|
|
|
|
the type of Body used, this may or may not be a `const` reference.
|
|
|
|
|
|
|
|
@note This function participates in overload resolution only if
|
|
|
|
Body::reader is constructible from a `const` message reference.
|
|
|
|
*/
|
|
|
|
explicit
|
|
|
|
serializer(value_type& msg);
|
|
|
|
|
|
|
|
/** Constructor
|
|
|
|
|
|
|
|
The implementation guarantees that the message passed on
|
|
|
|
construction will not be accessed until the first call to
|
|
|
|
@ref next. This allows the message to be lazily created.
|
|
|
|
For example, if the header is filled in before serialization.
|
|
|
|
|
|
|
|
@param msg A reference to the message to serialize, which must
|
|
|
|
remain valid for the lifetime of the serializer. Depending on
|
|
|
|
the type of Body used, this may or may not be a `const` reference.
|
|
|
|
|
|
|
|
@param decorator The decorator to use.
|
2017-05-28 17:04:39 -07:00
|
|
|
|
2017-07-07 14:32:51 -07:00
|
|
|
@note This function participates in overload resolution only if
|
|
|
|
Body::reader is constructible from a `const` message reference.
|
2017-05-28 17:04:39 -07:00
|
|
|
*/
|
|
|
|
explicit
|
2017-07-07 14:32:51 -07:00
|
|
|
serializer(value_type& msg, ChunkDecorator const& decorator);
|
2017-05-28 17:04:39 -07:00
|
|
|
|
2017-07-07 09:16:51 -07:00
|
|
|
/// Returns the message being serialized
|
|
|
|
value_type&
|
|
|
|
get()
|
|
|
|
{
|
|
|
|
return m_;
|
|
|
|
}
|
|
|
|
|
2017-07-06 20:58:07 -07:00
|
|
|
/// Returns the serialized buffer size limit
|
|
|
|
std::size_t
|
2017-07-07 23:49:02 -07:00
|
|
|
limit()
|
2017-07-06 20:58:07 -07:00
|
|
|
{
|
|
|
|
return limit_;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Set the serialized buffer size limit
|
|
|
|
|
|
|
|
This function adjusts the limit on the maximum size of the
|
|
|
|
buffers passed to the visitor. The new size limit takes effect
|
|
|
|
in the following call to @ref next.
|
|
|
|
|
|
|
|
The default is no buffer size limit.
|
|
|
|
|
|
|
|
@param limit The new buffer size limit. If this number
|
|
|
|
is zero, the size limit is removed.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
limit(std::size_t limit)
|
|
|
|
{
|
|
|
|
limit_ = limit > 0 ? limit:
|
|
|
|
(std::numeric_limits<std::size_t>::max)();
|
|
|
|
}
|
|
|
|
|
2017-05-28 19:49:41 -07:00
|
|
|
/** Returns `true` if we will pause after writing the complete header.
|
2017-05-28 17:04:39 -07:00
|
|
|
*/
|
|
|
|
bool
|
2017-07-07 23:49:02 -07:00
|
|
|
split()
|
2017-05-28 17:04:39 -07:00
|
|
|
{
|
|
|
|
return split_;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Set whether the header and body are written separately.
|
|
|
|
|
|
|
|
When the split feature is enabled, the implementation will
|
|
|
|
write only the octets corresponding to the serialized header
|
|
|
|
first. If the header has already been written, this function
|
2017-06-25 10:14:18 -07:00
|
|
|
will have no effect on output.
|
2017-05-28 17:04:39 -07:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
split(bool v)
|
|
|
|
{
|
2017-06-25 10:14:18 -07:00
|
|
|
split_ = v;
|
2017-05-28 17:04:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Return `true` if serialization of the header is complete.
|
|
|
|
|
2017-05-28 19:49:41 -07:00
|
|
|
This function indicates whether or not all buffers containing
|
|
|
|
serialized header octets have been retrieved.
|
2017-05-28 17:04:39 -07:00
|
|
|
*/
|
|
|
|
bool
|
2017-07-07 23:49:02 -07:00
|
|
|
is_header_done()
|
2017-05-28 17:04:39 -07:00
|
|
|
{
|
|
|
|
return header_done_;
|
|
|
|
}
|
|
|
|
|
2017-05-28 19:49:41 -07:00
|
|
|
/** Return `true` if serialization is complete.
|
2017-05-28 17:04:39 -07:00
|
|
|
|
|
|
|
The operation is complete when all octets corresponding
|
|
|
|
to the serialized representation of the message have been
|
2017-05-28 19:49:41 -07:00
|
|
|
successfully retrieved.
|
2017-05-28 17:04:39 -07:00
|
|
|
*/
|
|
|
|
bool
|
2017-07-07 23:49:02 -07:00
|
|
|
is_done()
|
2017-05-28 17:04:39 -07:00
|
|
|
{
|
|
|
|
return s_ == do_complete;
|
|
|
|
}
|
|
|
|
|
2017-07-07 22:58:10 -07:00
|
|
|
/** Return `true` if the serializer will apply chunk-encoding.
|
|
|
|
|
|
|
|
This function may only be called if @ref is_header_done
|
|
|
|
would return `true`.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
chunked()
|
|
|
|
{
|
|
|
|
return chunked_;
|
|
|
|
}
|
|
|
|
|
2017-07-07 23:05:11 -07:00
|
|
|
/** Return `true` if Connection: keep-alive semantic is indicated.
|
2017-05-28 17:04:39 -07:00
|
|
|
|
2017-07-07 23:05:11 -07:00
|
|
|
This function returns `true` if the semantics of the
|
|
|
|
message indicate that the connection should be kept open
|
|
|
|
after the serialized message has been transmitted. The
|
|
|
|
value depends on the HTTP version of the message,
|
|
|
|
the tokens in the Connection header, and the metadata
|
|
|
|
describing the payload body.
|
|
|
|
|
|
|
|
Depending on the payload body, the end of the message may
|
|
|
|
be indicated by connection closuire. In order for the
|
|
|
|
recipient (if any) to receive a complete message, the
|
|
|
|
underlying stream or network connection must be closed
|
|
|
|
when this function returns `false`.
|
2017-07-07 22:58:10 -07:00
|
|
|
|
|
|
|
This function may only be called if @ref is_header_done
|
|
|
|
would return `true`.
|
2017-05-28 17:04:39 -07:00
|
|
|
*/
|
|
|
|
bool
|
2017-07-07 23:05:11 -07:00
|
|
|
keep_alive()
|
2017-05-28 17:04:39 -07:00
|
|
|
{
|
2017-07-07 23:05:11 -07:00
|
|
|
return keep_alive_;
|
2017-05-28 17:04:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Returns the next set of buffers in the serialization.
|
|
|
|
|
|
|
|
This function will attempt to call the `visit` function
|
|
|
|
object with a @b ConstBufferSequence of unspecified type
|
|
|
|
representing the next set of buffers in the serialization
|
|
|
|
of the message represented by this object.
|
|
|
|
|
|
|
|
If there are no more buffers in the serialization, the
|
|
|
|
visit function will not be called. In this case, no error
|
|
|
|
will be indicated, and the function @ref is_done will
|
|
|
|
return `true`.
|
|
|
|
|
|
|
|
@param ec Set to the error, if any occurred.
|
|
|
|
|
|
|
|
@param visit The function to call. The equivalent function
|
|
|
|
signature of this object must be:
|
2017-05-28 19:49:41 -07:00
|
|
|
@code
|
|
|
|
template<class ConstBufferSequence>
|
2017-05-28 17:04:39 -07:00
|
|
|
void visit(error_code&, ConstBufferSequence const&);
|
|
|
|
@endcode
|
|
|
|
The function is not copied, if no error occurs it will be
|
2017-07-04 01:17:56 -07:00
|
|
|
invoked before the call to @ref next returns.
|
2017-05-28 17:04:39 -07:00
|
|
|
|
|
|
|
*/
|
|
|
|
template<class Visit>
|
|
|
|
void
|
2017-07-04 01:17:56 -07:00
|
|
|
next(error_code& ec, Visit&& visit);
|
2017-05-28 17:04:39 -07:00
|
|
|
|
|
|
|
/** Consume buffer octets in the serialization.
|
|
|
|
|
|
|
|
This function should be called after one or more octets
|
|
|
|
contained in the buffers provided in the prior call
|
2017-07-04 01:17:56 -07:00
|
|
|
to @ref next have been used.
|
2017-05-28 17:04:39 -07:00
|
|
|
|
|
|
|
After a call to @ref consume, callers should check the
|
|
|
|
return value of @ref is_done to determine if the entire
|
|
|
|
message has been serialized.
|
|
|
|
|
|
|
|
@param n The number of octets to consume. This number must
|
|
|
|
be greater than zero and no greater than the number of
|
2017-07-04 01:17:56 -07:00
|
|
|
octets in the buffers provided in the prior call to @ref next.
|
2017-05-28 17:04:39 -07:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
consume(std::size_t n);
|
|
|
|
};
|
|
|
|
|
2017-06-22 22:17:45 -07:00
|
|
|
/// A serializer for HTTP/1 requests
|
|
|
|
template<
|
|
|
|
class Body,
|
|
|
|
class Fields = fields,
|
|
|
|
class ChunkDecorator = no_chunk_decorator>
|
|
|
|
using request_serializer = serializer<true, Body, Fields, ChunkDecorator>;
|
|
|
|
|
|
|
|
/// A serializer for HTTP/1 responses
|
|
|
|
template<
|
|
|
|
class Body,
|
|
|
|
class Fields = fields,
|
|
|
|
class ChunkDecorator = no_chunk_decorator>
|
|
|
|
using response_serializer = serializer<false, Body, Fields, ChunkDecorator>;
|
|
|
|
|
2017-05-28 17:04:39 -07:00
|
|
|
} // http
|
|
|
|
} // beast
|
|
|
|
|
|
|
|
#include <beast/http/impl/serializer.ipp>
|
|
|
|
|
|
|
|
#endif
|