mirror of
https://github.com/boostorg/beast.git
synced 2025-08-03 14:54:32 +02:00
parser requires basic_fields (API Change):
* `parser` is now templated on Allocator * `parser` only produces messages using `basic_fields<Allocator>` as the Fields type. * message-oriented read and async_read only work on messages using basic_fields as the Fields type. Actions Required: * Callers using `parser` with Fields types other than basic_fields will need to create their own subclass of basic_parser to work with their custom fields type.
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -8,6 +8,16 @@ Version 62:
|
|||||||
* Clear the error faster
|
* Clear the error faster
|
||||||
* Avoid explicit operator bool for error
|
* Avoid explicit operator bool for error
|
||||||
|
|
||||||
|
API Changes:
|
||||||
|
|
||||||
|
* parser requires basic_fields
|
||||||
|
|
||||||
|
Actions Required:
|
||||||
|
|
||||||
|
* Callers using `parser` with Fields types other than basic_fields
|
||||||
|
will need to create their own subclass of basic_parser to work
|
||||||
|
with their custom fields type.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Version 61:
|
Version 61:
|
||||||
|
@@ -464,7 +464,6 @@ do_head_request(
|
|||||||
*/
|
*/
|
||||||
template<
|
template<
|
||||||
bool isRequest,
|
bool isRequest,
|
||||||
class Fields = fields,
|
|
||||||
class SyncWriteStream,
|
class SyncWriteStream,
|
||||||
class SyncReadStream,
|
class SyncReadStream,
|
||||||
class DynamicBuffer,
|
class DynamicBuffer,
|
||||||
@@ -487,10 +486,10 @@ relay(
|
|||||||
char buf[2048];
|
char buf[2048];
|
||||||
|
|
||||||
// Create a parser with a buffer body to read from the input.
|
// Create a parser with a buffer body to read from the input.
|
||||||
parser<isRequest, buffer_body, Fields> p;
|
parser<isRequest, buffer_body> p;
|
||||||
|
|
||||||
// Create a serializer from the message contained in the parser.
|
// Create a serializer from the message contained in the parser.
|
||||||
serializer<isRequest, buffer_body, Fields> sr{p.get()};
|
serializer<isRequest, buffer_body, fields> sr{p.get()};
|
||||||
|
|
||||||
// Read just the header from the input
|
// Read just the header from the input
|
||||||
read_header(input, buffer, p, ec);
|
read_header(input, buffer, p, ec);
|
||||||
@@ -684,13 +683,12 @@ write_ostream(
|
|||||||
template<
|
template<
|
||||||
class Allocator,
|
class Allocator,
|
||||||
bool isRequest,
|
bool isRequest,
|
||||||
class Body,
|
class Body>
|
||||||
class Fields>
|
|
||||||
void
|
void
|
||||||
read_istream(
|
read_istream(
|
||||||
std::istream& is,
|
std::istream& is,
|
||||||
basic_flat_buffer<Allocator>& buffer,
|
basic_flat_buffer<Allocator>& buffer,
|
||||||
message<isRequest, Body, Fields>& msg,
|
message<isRequest, Body, fields>& msg,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
// Create the message parser
|
// Create the message parser
|
||||||
@@ -700,7 +698,7 @@ read_istream(
|
|||||||
// a move construction in case the caller has constructed
|
// a move construction in case the caller has constructed
|
||||||
// their message in a non-default way.
|
// their message in a non-default way.
|
||||||
//
|
//
|
||||||
parser<isRequest, Body, Fields> p{std::move(msg)};
|
parser<isRequest, Body> p{std::move(msg)};
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@@ -14,19 +14,19 @@
|
|||||||
namespace beast {
|
namespace beast {
|
||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
template<bool isRequest, class Body, class Fields>
|
template<bool isRequest, class Body, class Allocator>
|
||||||
template<class Arg1, class... ArgN, class>
|
template<class Arg1, class... ArgN, class>
|
||||||
parser<isRequest, Body, Fields>::
|
parser<isRequest, Body, Allocator>::
|
||||||
parser(Arg1&& arg1, ArgN&&... argn)
|
parser(Arg1&& arg1, ArgN&&... argn)
|
||||||
: m_(std::forward<Arg1>(arg1),
|
: m_(std::forward<Arg1>(arg1),
|
||||||
std::forward<ArgN>(argn)...)
|
std::forward<ArgN>(argn)...)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool isRequest, class Body, class Fields>
|
template<bool isRequest, class Body, class Allocator>
|
||||||
template<class OtherBody, class... Args, class>
|
template<class OtherBody, class... Args, class>
|
||||||
parser<isRequest, Body, Fields>::
|
parser<isRequest, Body, Allocator>::
|
||||||
parser(parser<isRequest, OtherBody, Fields>&& p,
|
parser(parser<isRequest, OtherBody, Allocator>&& p,
|
||||||
Args&&... args)
|
Args&&... args)
|
||||||
: base_type(std::move(p))
|
: base_type(std::move(p))
|
||||||
, m_(p.release(), std::forward<Args>(args)...)
|
, m_(p.release(), std::forward<Args>(args)...)
|
||||||
|
@@ -300,15 +300,15 @@ upcall:
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class Stream, class DynamicBuffer,
|
template<class Stream, class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Fields,
|
bool isRequest, class Body, class Allocator,
|
||||||
class Handler>
|
class Handler>
|
||||||
class read_msg_op
|
class read_msg_op
|
||||||
{
|
{
|
||||||
using parser_type =
|
using parser_type =
|
||||||
parser<isRequest, Body, Fields>;
|
parser<isRequest, Body, Allocator>;
|
||||||
|
|
||||||
using message_type =
|
using message_type =
|
||||||
message<isRequest, Body, Fields>;
|
typename parser_type::value_type;
|
||||||
|
|
||||||
struct data
|
struct data
|
||||||
{
|
{
|
||||||
@@ -383,11 +383,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<class Stream, class DynamicBuffer,
|
template<class Stream, class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Fields,
|
bool isRequest, class Body, class Allocator,
|
||||||
class Handler>
|
class Handler>
|
||||||
void
|
void
|
||||||
read_msg_op<Stream, DynamicBuffer,
|
read_msg_op<Stream, DynamicBuffer,
|
||||||
isRequest, Body, Fields, Handler>::
|
isRequest, Body, Allocator, Handler>::
|
||||||
operator()(error_code ec)
|
operator()(error_code ec)
|
||||||
{
|
{
|
||||||
auto& d = *d_;
|
auto& d = *d_;
|
||||||
@@ -693,12 +693,12 @@ async_read(
|
|||||||
template<
|
template<
|
||||||
class SyncReadStream,
|
class SyncReadStream,
|
||||||
class DynamicBuffer,
|
class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Fields>
|
bool isRequest, class Body, class Allocator>
|
||||||
void
|
void
|
||||||
read(
|
read(
|
||||||
SyncReadStream& stream,
|
SyncReadStream& stream,
|
||||||
DynamicBuffer& buffer,
|
DynamicBuffer& buffer,
|
||||||
message<isRequest, Body, Fields>& msg)
|
message<isRequest, Body, basic_fields<Allocator>>& msg)
|
||||||
{
|
{
|
||||||
static_assert(is_sync_read_stream<SyncReadStream>::value,
|
static_assert(is_sync_read_stream<SyncReadStream>::value,
|
||||||
"SyncReadStream requirements not met");
|
"SyncReadStream requirements not met");
|
||||||
@@ -717,12 +717,12 @@ read(
|
|||||||
template<
|
template<
|
||||||
class SyncReadStream,
|
class SyncReadStream,
|
||||||
class DynamicBuffer,
|
class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Fields>
|
bool isRequest, class Body, class Allocator>
|
||||||
void
|
void
|
||||||
read(
|
read(
|
||||||
SyncReadStream& stream,
|
SyncReadStream& stream,
|
||||||
DynamicBuffer& buffer,
|
DynamicBuffer& buffer,
|
||||||
message<isRequest, Body, Fields>& msg,
|
message<isRequest, Body, basic_fields<Allocator>>& msg,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
static_assert(is_sync_read_stream<SyncReadStream>::value,
|
static_assert(is_sync_read_stream<SyncReadStream>::value,
|
||||||
@@ -733,7 +733,7 @@ read(
|
|||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_writer<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyWriter requirements not met");
|
"BodyWriter requirements not met");
|
||||||
parser<isRequest, Body, Fields> p{std::move(msg)};
|
parser<isRequest, Body, Allocator> p{std::move(msg)};
|
||||||
p.eager(true);
|
p.eager(true);
|
||||||
read(stream, buffer, p.base(), ec);
|
read(stream, buffer, p.base(), ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
@@ -744,13 +744,13 @@ read(
|
|||||||
template<
|
template<
|
||||||
class AsyncReadStream,
|
class AsyncReadStream,
|
||||||
class DynamicBuffer,
|
class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Fields,
|
bool isRequest, class Body, class Allocator,
|
||||||
class ReadHandler>
|
class ReadHandler>
|
||||||
async_return_type<ReadHandler, void(error_code)>
|
async_return_type<ReadHandler, void(error_code)>
|
||||||
async_read(
|
async_read(
|
||||||
AsyncReadStream& stream,
|
AsyncReadStream& stream,
|
||||||
DynamicBuffer& buffer,
|
DynamicBuffer& buffer,
|
||||||
message<isRequest, Body, Fields>& msg,
|
message<isRequest, Body, basic_fields<Allocator>>& msg,
|
||||||
ReadHandler&& handler)
|
ReadHandler&& handler)
|
||||||
{
|
{
|
||||||
static_assert(is_async_read_stream<AsyncReadStream>::value,
|
static_assert(is_async_read_stream<AsyncReadStream>::value,
|
||||||
@@ -764,7 +764,7 @@ async_read(
|
|||||||
async_completion<ReadHandler,
|
async_completion<ReadHandler,
|
||||||
void(error_code)> init{handler};
|
void(error_code)> init{handler};
|
||||||
detail::read_msg_op<AsyncReadStream, DynamicBuffer,
|
detail::read_msg_op<AsyncReadStream, DynamicBuffer,
|
||||||
isRequest, Body, Fields, handler_type<
|
isRequest, Body, Allocator, handler_type<
|
||||||
ReadHandler, void(error_code)>>{
|
ReadHandler, void(error_code)>>{
|
||||||
init.completion_handler, stream, buffer, msg}(
|
init.completion_handler, stream, buffer, msg}(
|
||||||
error_code{});
|
error_code{});
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include <beast/http/type_traits.hpp>
|
#include <beast/http/type_traits.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -23,24 +24,27 @@ namespace http {
|
|||||||
/** An HTTP/1 parser for producing a message.
|
/** An HTTP/1 parser for producing a message.
|
||||||
|
|
||||||
This class uses the basic HTTP/1 wire format parser to convert
|
This class uses the basic HTTP/1 wire format parser to convert
|
||||||
a series of octets into a @ref message.
|
a series of octets into a @ref message using the @ref basic_fields
|
||||||
|
container to represent the fields.
|
||||||
|
|
||||||
@tparam isRequest Indicates whether a request or response
|
@tparam isRequest Indicates whether a request or response
|
||||||
will be parsed.
|
will be parsed.
|
||||||
|
|
||||||
@tparam Body The type used to represent the body.
|
@tparam Body The type used to represent the body. This must
|
||||||
|
meet the requirements of @b Body.
|
||||||
|
|
||||||
@tparam Fields The type of container used to represent the fields.
|
@tparam Allocator The type of allocator used with the
|
||||||
|
@ref basic_fields container.
|
||||||
|
|
||||||
@note A new instance of the parser is required for each message.
|
@note A new instance of the parser is required for each message.
|
||||||
*/
|
*/
|
||||||
template<
|
template<
|
||||||
bool isRequest,
|
bool isRequest,
|
||||||
class Body,
|
class Body,
|
||||||
class Fields = fields>
|
class Allocator = std::allocator<char>>
|
||||||
class parser
|
class parser
|
||||||
: public basic_parser<isRequest,
|
: public basic_parser<isRequest,
|
||||||
parser<isRequest, Body, Fields>>
|
parser<isRequest, Body, Allocator>>
|
||||||
{
|
{
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
@@ -52,14 +56,15 @@ class parser
|
|||||||
friend class parser;
|
friend class parser;
|
||||||
|
|
||||||
using base_type = basic_parser<isRequest,
|
using base_type = basic_parser<isRequest,
|
||||||
parser<isRequest, Body, Fields>>;
|
parser<isRequest, Body, Allocator>>;
|
||||||
|
|
||||||
message<isRequest, Body, Fields> m_;
|
message<isRequest, Body, basic_fields<Allocator>> m_;
|
||||||
boost::optional<typename Body::writer> wr_;
|
boost::optional<typename Body::writer> wr_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// The type of message returned by the parser
|
/// The type of message returned by the parser
|
||||||
using value_type = message<isRequest, Body, Fields>;
|
using value_type =
|
||||||
|
message<isRequest, Body, basic_fields<Allocator>>;
|
||||||
|
|
||||||
/// Constructor (default)
|
/// Constructor (default)
|
||||||
parser() = default;
|
parser() = default;
|
||||||
@@ -126,6 +131,9 @@ public:
|
|||||||
|
|
||||||
@throws std::invalid_argument Thrown when the constructed-from
|
@throws std::invalid_argument Thrown when the constructed-from
|
||||||
parser has already initialized a body writer.
|
parser has already initialized a body writer.
|
||||||
|
|
||||||
|
@note This function participates in overload resolution only
|
||||||
|
if the other parser uses a different body type.
|
||||||
*/
|
*/
|
||||||
#if BEAST_DOXYGEN
|
#if BEAST_DOXYGEN
|
||||||
template<class OtherBody, class... Args>
|
template<class OtherBody, class... Args>
|
||||||
@@ -135,13 +143,13 @@ public:
|
|||||||
! std::is_same<Body, OtherBody>::value>::type>
|
! std::is_same<Body, OtherBody>::value>::type>
|
||||||
#endif
|
#endif
|
||||||
explicit
|
explicit
|
||||||
parser(parser<isRequest, OtherBody, Fields>&& parser,
|
parser(parser<isRequest, OtherBody,
|
||||||
Args&&... args);
|
Allocator>&& parser, Args&&... args);
|
||||||
|
|
||||||
/** Returns the parsed message.
|
/** Returns the parsed message.
|
||||||
|
|
||||||
Depending on the progress of the parser, portions
|
Depending on the parser's progress,
|
||||||
of this object may be incomplete.
|
parts of this object may be incomplete.
|
||||||
*/
|
*/
|
||||||
value_type const&
|
value_type const&
|
||||||
get() const
|
get() const
|
||||||
@@ -151,8 +159,8 @@ public:
|
|||||||
|
|
||||||
/** Returns the parsed message.
|
/** Returns the parsed message.
|
||||||
|
|
||||||
Depending on the progress of the parser, portions
|
Depending on the parser's progress,
|
||||||
of this object may be incomplete.
|
parts of this object may be incomplete.
|
||||||
*/
|
*/
|
||||||
value_type&
|
value_type&
|
||||||
get()
|
get()
|
||||||
@@ -163,8 +171,8 @@ public:
|
|||||||
/** Returns ownership of the parsed message.
|
/** Returns ownership of the parsed message.
|
||||||
|
|
||||||
Ownership is transferred to the caller.
|
Ownership is transferred to the caller.
|
||||||
Depending on the progress of the parser, portions
|
Depending on the parser's progress,
|
||||||
of this object may be incomplete.
|
parts of this object may be incomplete.
|
||||||
|
|
||||||
@par Requires
|
@par Requires
|
||||||
|
|
||||||
@@ -253,12 +261,12 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// An HTTP/1 parser for producing a request message.
|
/// An HTTP/1 parser for producing a request message.
|
||||||
template<class Body, class Fields = fields>
|
template<class Body, class Allocator = std::allocator<char>>
|
||||||
using request_parser = parser<true, Body, Fields>;
|
using request_parser = parser<true, Body, Allocator>;
|
||||||
|
|
||||||
/// An HTTP/1 parser for producing a response message.
|
/// An HTTP/1 parser for producing a response message.
|
||||||
template<class Body, class Fields = fields>
|
template<class Body, class Allocator = std::allocator<char>>
|
||||||
using response_parser = parser<false, Body, Fields>;
|
using response_parser = parser<false, Body, Allocator>;
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
} // beast
|
} // beast
|
||||||
|
@@ -614,12 +614,12 @@ async_read(
|
|||||||
template<
|
template<
|
||||||
class SyncReadStream,
|
class SyncReadStream,
|
||||||
class DynamicBuffer,
|
class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Fields>
|
bool isRequest, class Body, class Allocator>
|
||||||
void
|
void
|
||||||
read(
|
read(
|
||||||
SyncReadStream& stream,
|
SyncReadStream& stream,
|
||||||
DynamicBuffer& buffer,
|
DynamicBuffer& buffer,
|
||||||
message<isRequest, Body, Fields>& msg);
|
message<isRequest, Body, basic_fields<Allocator>>& msg);
|
||||||
|
|
||||||
/** Read a complete message from a stream.
|
/** Read a complete message from a stream.
|
||||||
|
|
||||||
@@ -666,12 +666,12 @@ read(
|
|||||||
template<
|
template<
|
||||||
class SyncReadStream,
|
class SyncReadStream,
|
||||||
class DynamicBuffer,
|
class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Fields>
|
bool isRequest, class Body, class Allocator>
|
||||||
void
|
void
|
||||||
read(
|
read(
|
||||||
SyncReadStream& stream,
|
SyncReadStream& stream,
|
||||||
DynamicBuffer& buffer,
|
DynamicBuffer& buffer,
|
||||||
message<isRequest, Body, Fields>& msg,
|
message<isRequest, Body, basic_fields<Allocator>>& msg,
|
||||||
error_code& ec);
|
error_code& ec);
|
||||||
|
|
||||||
/** Read a complete message from a stream asynchronously.
|
/** Read a complete message from a stream asynchronously.
|
||||||
@@ -735,7 +735,7 @@ read(
|
|||||||
template<
|
template<
|
||||||
class AsyncReadStream,
|
class AsyncReadStream,
|
||||||
class DynamicBuffer,
|
class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Fields,
|
bool isRequest, class Body, class Allocator,
|
||||||
class ReadHandler>
|
class ReadHandler>
|
||||||
#if BEAST_DOXYGEN
|
#if BEAST_DOXYGEN
|
||||||
void_or_deduced
|
void_or_deduced
|
||||||
@@ -746,7 +746,7 @@ async_return_type<
|
|||||||
async_read(
|
async_read(
|
||||||
AsyncReadStream& stream,
|
AsyncReadStream& stream,
|
||||||
DynamicBuffer& buffer,
|
DynamicBuffer& buffer,
|
||||||
message<isRequest, Body, Fields>& msg,
|
message<isRequest, Body, basic_fields<Allocator>>& msg,
|
||||||
ReadHandler&& handler);
|
ReadHandler&& handler);
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
|
@@ -32,7 +32,7 @@ class parser_test
|
|||||||
public:
|
public:
|
||||||
template<bool isRequest>
|
template<bool isRequest>
|
||||||
using parser_type =
|
using parser_type =
|
||||||
parser<isRequest, string_body, fields>;
|
parser<isRequest, string_body>;
|
||||||
|
|
||||||
static
|
static
|
||||||
boost::asio::const_buffers_1
|
boost::asio::const_buffers_1
|
||||||
|
Reference in New Issue
Block a user