mirror of
https://github.com/boostorg/beast.git
synced 2025-08-05 07:44:35 +02:00
BodyReader and BodyWriter names are swapped (API Change):
Body::reader and Body::writer meanings are reversed, for consistency with the names of the stream operations: * Body::reader is used for read, read_some, async_read, async_read_some * Body::writer is used for write, write_some, async_write, async_write_some Actions Required: * Swap the reader and writer names for user defined Body types * Swap use of is_body_reader and is_body_writer
This commit is contained in:
@@ -8,10 +8,13 @@ Version 132:
|
|||||||
API Changes:
|
API Changes:
|
||||||
|
|
||||||
* Fields::writer replaces Fields::reader
|
* Fields::writer replaces Fields::reader
|
||||||
|
* BodyReader and BodyWriter names are swapped
|
||||||
|
|
||||||
Actions Required:
|
Actions Required:
|
||||||
|
|
||||||
* Rename reader to writer for user defined Fields
|
* Rename reader to writer for user defined Fields
|
||||||
|
* Swap the reader and writer names for user defined Body types
|
||||||
|
* Swap use of is_body_reader and is_body_writer
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -17,10 +17,10 @@ shows the customization points available to user-defined body types:
|
|||||||
/// Defines a Body type
|
/// Defines a Body type
|
||||||
struct body
|
struct body
|
||||||
{
|
{
|
||||||
/// This determines the type of the `message::body` member
|
/// This determines the return type of the `message::body` member function
|
||||||
using value_type = ...;
|
using value_type = ...;
|
||||||
|
|
||||||
/// An optional function, returns the body's payload size
|
/// An optional function, returns the body's payload size (which may be zero)
|
||||||
static
|
static
|
||||||
std::uint64_t
|
std::uint64_t
|
||||||
size(value_type const& v);
|
size(value_type const& v);
|
||||||
@@ -48,17 +48,17 @@ The meaning of the nested types is as follows
|
|||||||
[`reader`]
|
[`reader`]
|
||||||
[
|
[
|
||||||
An optional nested type meeting the requirements of __BodyReader__,
|
An optional nested type meeting the requirements of __BodyReader__,
|
||||||
which provides the algorithm for converting the body representation
|
which provides the algorithm for storing a forward range of buffer
|
||||||
to a forward range of buffer sequences.
|
sequences in the body representation.
|
||||||
If present this body type may be used with a __serializer__.
|
If present, this body type may be used with a __parser__.
|
||||||
]
|
]
|
||||||
][
|
][
|
||||||
[`writer`]
|
[`writer`]
|
||||||
[
|
[
|
||||||
An optional nested type meeting the requirements of __BodyWriter__,
|
An optional nested type meeting the requirements of __BodyWriter__,
|
||||||
which provides the algorithm for storing a forward range of buffer
|
which provides the algorithm for converting the body representation
|
||||||
sequences in the body representation.
|
to a forward range of buffer sequences.
|
||||||
If present, this body type may be used with a __parser__.
|
If present this body type may be used with a __serializer__.
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@@ -67,7 +67,7 @@ The meaning of the nested types is as follows
|
|||||||
|
|
||||||
The `value_type` nested type allows the body to define the declaration of
|
The `value_type` nested type allows the body to define the declaration of
|
||||||
the body type as it appears in the message. This can be any type. For
|
the body type as it appears in the message. This can be any type. For
|
||||||
example, a body's value type may specify `std::vector<char>` or even
|
example, a body's value type may specify `std::vector<char>` or
|
||||||
`std::list<std::string>`. A custom body may even set the value type to
|
`std::list<std::string>`. A custom body may even set the value type to
|
||||||
something that is not a container for body octets, such as a
|
something that is not a container for body octets, such as a
|
||||||
[@boost:/libs/filesystem/doc/reference.html#class-path `boost::filesystem::path`].
|
[@boost:/libs/filesystem/doc/reference.html#class-path `boost::filesystem::path`].
|
||||||
@@ -82,20 +82,14 @@ struct Body
|
|||||||
{
|
{
|
||||||
using value_type = boost::property_tree::ptree;
|
using value_type = boost::property_tree::ptree;
|
||||||
|
|
||||||
class reader;
|
class reader
|
||||||
|
|
||||||
class writer;
|
class writer;
|
||||||
|
|
||||||
// Optional member
|
|
||||||
static
|
|
||||||
std::uint64_t
|
|
||||||
size(value_type const&);
|
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
As long as a suitable reader or writer is available to provide the
|
As long as a suitable reader or writer is available to provide the
|
||||||
algorithm for transferring buffers in and out of the value type,
|
algorithm for transferring buffers in and out of the value type,
|
||||||
those bodies may be serialized or parsed.
|
those bodies may be parsed or serialized.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -105,7 +99,9 @@ Use of the flexible __Body__ concept customization point enables authors to
|
|||||||
preserve the self-contained nature of the __message__ object while allowing
|
preserve the self-contained nature of the __message__ object while allowing
|
||||||
domain specific behaviors. Common operations for HTTP servers include sending
|
domain specific behaviors. Common operations for HTTP servers include sending
|
||||||
responses which deliver file contents, and allowing for file uploads. In this
|
responses which deliver file contents, and allowing for file uploads. In this
|
||||||
example we build the `basic_file_body` type which supports both reading and
|
example we build the
|
||||||
|
[link beast.ref.boost__beast__http__basic_file_body `basic_file_body`]
|
||||||
|
type which supports both reading and
|
||||||
writing to a file on the file system. The interface is a class templated
|
writing to a file on the file system. The interface is a class templated
|
||||||
on the type of file used to access the file system, which must meet the
|
on the type of file used to access the file system, which must meet the
|
||||||
requirements of __File__.
|
requirements of __File__.
|
||||||
@@ -124,7 +120,7 @@ file is removed from the file system in between calls.
|
|||||||
|
|
||||||
[example_http_file_body_2]
|
[example_http_file_body_2]
|
||||||
|
|
||||||
Our implementation of __BodyReader__ will contain a small buffer
|
Our implementation of __BodyWriter__ will contain a small buffer
|
||||||
from which the file contents are read. The buffer is provided to
|
from which the file contents are read. The buffer is provided to
|
||||||
the implementation on each call until everything has been read in.
|
the implementation on each call until everything has been read in.
|
||||||
|
|
||||||
@@ -135,13 +131,13 @@ And here are the definitions for the functions we have declared:
|
|||||||
[example_http_file_body_4]
|
[example_http_file_body_4]
|
||||||
|
|
||||||
Files can be read now, and the next step is to allow writing to files
|
Files can be read now, and the next step is to allow writing to files
|
||||||
by implementing the __BodyWriter__. The style is similar to the reader,
|
by implementing the __BodyReader__. The style is similar to the writer,
|
||||||
except that buffers are incoming instead of outgoing. Here's the
|
except that buffers are incoming instead of outgoing. Here's the
|
||||||
declaration:
|
declaration:
|
||||||
|
|
||||||
[example_http_file_body_5]
|
[example_http_file_body_5]
|
||||||
|
|
||||||
Finally, here is the implementation of the writer member functions:
|
Finally, here is the implementation of the reader member functions:
|
||||||
|
|
||||||
[example_http_file_body_6]
|
[example_http_file_body_6]
|
||||||
|
|
||||||
|
@@ -33,26 +33,25 @@ In this table:
|
|||||||
[`B::value_type`]
|
[`B::value_type`]
|
||||||
[]
|
[]
|
||||||
[
|
[
|
||||||
The type of the `message::body` member.
|
The return type of the `message::body` member function.
|
||||||
If this is not movable or not copyable, the containing message
|
If this is not movable or not copyable, the containing message
|
||||||
will be not movable or not copyable.
|
will be not movable or not copyable.
|
||||||
]
|
]
|
||||||
][
|
|
||||||
[`B::writer`]
|
|
||||||
[]
|
|
||||||
[
|
|
||||||
If present, indicates that the body can hold a message body
|
|
||||||
parsing result. The type must meet the requirements of
|
|
||||||
__BodyWriter__. The implementation constructs an object of
|
|
||||||
this type to obtain buffers into which parsed body octets
|
|
||||||
are placed.
|
|
||||||
]
|
|
||||||
][
|
][
|
||||||
[`B::reader`]
|
[`B::reader`]
|
||||||
[]
|
[]
|
||||||
[
|
[
|
||||||
If present, indicates that the body is serializable. The type
|
If present, indicates that the body can be parsed. The type
|
||||||
must meet the requirements of __BodyReader__. The implementation
|
must meet the requirements of __BodyReader__. The implementation
|
||||||
|
constructs an object of this type to obtain buffers into which
|
||||||
|
parsed body octets are placed.
|
||||||
|
]
|
||||||
|
][
|
||||||
|
[`B::writer`]
|
||||||
|
[]
|
||||||
|
[
|
||||||
|
If present, indicates that the body is serializable. The type
|
||||||
|
must meet the requirements of __BodyWriter__. The implementation
|
||||||
constructs an object of this type to obtain buffers representing
|
constructs an object of this type to obtain buffers representing
|
||||||
the message body for serialization.
|
the message body for serialization.
|
||||||
]
|
]
|
||||||
@@ -67,7 +66,8 @@ In this table:
|
|||||||
[
|
[
|
||||||
This static member function is optional. It returns the payload
|
This static member function is optional. It returns the payload
|
||||||
size of `body` in bytes not including any chunked transfer encoding.
|
size of `body` in bytes not including any chunked transfer encoding.
|
||||||
The function shall not exit via an exception.
|
The return value may be zero, to indicate that the message is known
|
||||||
|
to have no payload. The function shall not exit via an exception.
|
||||||
|
|
||||||
When this function is present:
|
When this function is present:
|
||||||
|
|
||||||
|
@@ -9,20 +9,18 @@
|
|||||||
|
|
||||||
[section:BodyReader BodyReader]
|
[section:BodyReader BodyReader]
|
||||||
|
|
||||||
A [*BodyReader] provides an
|
A [*BodyReader] provides an online algorithm to transfer a series of zero
|
||||||
[@https://en.wikipedia.org/wiki/Online_algorithm online algorithm]
|
or more buffers containing parsed body octets into a message container. The
|
||||||
to obtain a sequence of zero
|
__parser__ creates an instance of this type when needed, and calls into
|
||||||
or more buffers from a body during serialization. The implementation creates
|
it zero or more times to transfer buffers. The interface of [*BodyReader]
|
||||||
an instance of this type when needed, and calls into it one or more times to
|
is intended to allow the conversion of buffers into these scenarios for
|
||||||
retrieve buffers holding body octets. The interface of [*BodyReader] is
|
representation:
|
||||||
intended to obtain buffers for these scenarios:
|
|
||||||
|
|
||||||
* A body that does not entirely fit in memory.
|
* Storing a body in a dynamic buffer
|
||||||
* A body produced incrementally from coroutine output.
|
* Storing a body in a user defined container with a custom allocator
|
||||||
* A body represented by zero or more buffers already in memory.
|
* Transformation of incoming body data before storage, for example
|
||||||
* A body whose size is not known ahead of time.
|
to compress it first.
|
||||||
* Body data generated dynamically from other threads.
|
* Saving body data to a file
|
||||||
* Body data computed algorithmically.
|
|
||||||
|
|
||||||
[heading Associated Types]
|
[heading Associated Types]
|
||||||
|
|
||||||
@@ -37,68 +35,71 @@ In this table:
|
|||||||
* `B` denotes a __Body__ where
|
* `B` denotes a __Body__ where
|
||||||
`std::is_same<R, B::reader>::value == true`.
|
`std::is_same<R, B::reader>::value == true`.
|
||||||
* `a` denotes a value of type `R`.
|
* `a` denotes a value of type `R`.
|
||||||
* `m` denotes a possibly const value of type `message&` where
|
* `b` is an object whose type meets the requirements of __ConstBufferSequence__
|
||||||
`std::is_same<decltype(m.body), Body::value_type>:value == true`.
|
* `m` denotes a value of type `message&` where
|
||||||
|
`std::is_same<decltype(m.body), Body::value_type>::value == true`.
|
||||||
|
* `n` is a value of type `boost::optional<std::uint64_t>`.
|
||||||
* `ec` is a value of type [link beast.ref.boost__beast__error_code `error_code&`].
|
* `ec` is a value of type [link beast.ref.boost__beast__error_code `error_code&`].
|
||||||
* `R<T>` is the type `boost::optional<std::pair<T, bool>>`.
|
|
||||||
|
|
||||||
[table Valid expressions
|
[table Valid expressions
|
||||||
[[Expression] [Type] [Semantics, Pre/Post-conditions]]
|
[[Expression] [Type] [Semantics, Pre/Post-conditions]]
|
||||||
[
|
[
|
||||||
[`R::const_buffers_type`]
|
|
||||||
[]
|
|
||||||
[
|
|
||||||
A type which meets the requirements of __ConstBufferSequence__.
|
|
||||||
This is the type of buffer returned by `R::get`.
|
|
||||||
]
|
|
||||||
][
|
|
||||||
[`R(m);`]
|
[`R(m);`]
|
||||||
[]
|
[]
|
||||||
[
|
[
|
||||||
Constructible from `m`. The lifetime of `m` is guaranteed
|
Constructible from `m`. The lifetime of `m` is guaranteed to
|
||||||
to end no earlier than after the `R` is destroyed.
|
end no earlier than after the `R` is destroyed. The constructor
|
||||||
The reader shall not access the contents of `m` before the
|
will be called after a complete header is stored in `m`, and
|
||||||
first call to `init`, permitting lazy construction of the
|
before parsing body octets for messages indicating that a body
|
||||||
|
is present The reader shall not access the contents of `m` before
|
||||||
|
the first call to `init`, permitting lazy construction of the
|
||||||
message.
|
message.
|
||||||
|
|
||||||
The constructor may optionally require that `m` is const, which
|
The function will ensure that `!ec` is `true` if there was
|
||||||
has these consequences:
|
no error or set to the appropriate error code if there was one.
|
||||||
|
|
||||||
* If `R` requires that `m` is a const reference, then serializers
|
|
||||||
constructed for messages with this body type will also require a
|
|
||||||
const reference to a message, otherwise:
|
|
||||||
|
|
||||||
* If `R` requires that `m` is a non-const reference, then serializers
|
|
||||||
constructed for messages with this body type will aso require
|
|
||||||
a non-const reference to a message.
|
|
||||||
]
|
]
|
||||||
][
|
][
|
||||||
[`a.init(ec)`]
|
[`a.init(n, ec)`]
|
||||||
[]
|
[]
|
||||||
[
|
[
|
||||||
Called once to fully initialize the object before any calls to
|
Called once to fully initialize the object before any calls to
|
||||||
`get`. The message body becomes valid before entering this function,
|
`put`. The message body is valid before entering this function,
|
||||||
and remains valid until the reader is destroyed.
|
and remains valid until the reader is destroyed.
|
||||||
|
The value of `n` will be set to the content length of the
|
||||||
|
body if known, otherwise `n` will be equal to `boost::none`.
|
||||||
|
Implementations of [*BodyReader] may use this information to
|
||||||
|
optimize allocation.
|
||||||
|
|
||||||
The function will ensure that `!ec` is `true` if there was
|
The function will ensure that `!ec` is `true` if there was
|
||||||
no error or set to the appropriate error code if there was one.
|
no error or set to the appropriate error code if there was one.
|
||||||
]
|
]
|
||||||
][
|
][
|
||||||
[`a.get(ec)`]
|
[`a.put(b,ec)`]
|
||||||
[`R<R::const_buffers_type>`]
|
[`std::size_t`]
|
||||||
[
|
[
|
||||||
Called one or more times after `init` succeeds. This function
|
This function is called to append some or all of the buffers
|
||||||
returns `boost::none` if all buffers representing the body have
|
specified by `b` into the body representation. The number of
|
||||||
been returned in previous calls or if it sets `ec` to indicate an
|
bytes inserted from `b` is returned. If the number of bytes
|
||||||
error. Otherwise, if there are buffers remaining the function
|
inserted is less than the total input, the remainder of the
|
||||||
should return a pair with the first element containing a non-zero
|
input will be presented in the next call to `put`.
|
||||||
length buffer sequence representing the next set of octets in
|
|
||||||
the body, while the second element is a `bool` meaning `true`
|
|
||||||
if there may be additional buffers returned on a subsequent call,
|
|
||||||
or `false` if the buffer returned on this call is the last
|
|
||||||
buffer representing the body.
|
|
||||||
The function will ensure that `!ec` is `true` if there was
|
The function will ensure that `!ec` is `true` if there was
|
||||||
no error or set to the appropriate error code if there was one.
|
no error or set to the appropriate error code if there was one.
|
||||||
]
|
]
|
||||||
|
][
|
||||||
|
[`a.finish(ec)`]
|
||||||
|
[]
|
||||||
|
[
|
||||||
|
This function is called when no more body octets are remaining.
|
||||||
|
The function will ensure that `!ec` is `true` if there was
|
||||||
|
no error or set to the appropriate error code if there was one.
|
||||||
|
]
|
||||||
|
][
|
||||||
|
[`is_body_reader<B>`]
|
||||||
|
[`std::true_type`]
|
||||||
|
[
|
||||||
|
An alias for `std::true_type` for `B`, otherwise an alias
|
||||||
|
for `std::false_type`.
|
||||||
|
]
|
||||||
]]
|
]]
|
||||||
|
|
||||||
[heading Exemplar]
|
[heading Exemplar]
|
||||||
|
@@ -9,18 +9,20 @@
|
|||||||
|
|
||||||
[section:BodyWriter BodyWriter]
|
[section:BodyWriter BodyWriter]
|
||||||
|
|
||||||
A [*BodyWriter] provides an online algorithm to transfer a series of zero
|
A [*BodyWriter] provides an
|
||||||
or more buffers containing parsed body octets into a message container. The
|
[@https://en.wikipedia.org/wiki/Online_algorithm online algorithm]
|
||||||
__parser__ creates an instance of this type when needed, and calls into
|
to obtain a sequence of zero
|
||||||
it zero or more times to transfer buffers. The interface of [*BodyWriter]
|
or more buffers from a body during serialization. The implementation creates
|
||||||
is intended to allow the conversion of buffers into these scenarios for
|
an instance of this type when needed, and calls into it one or more times to
|
||||||
representation:
|
retrieve buffers holding body octets. The interface of [*BodyWriter] is
|
||||||
|
intended to obtain buffers for these scenarios:
|
||||||
|
|
||||||
* Storing a body in a dynamic buffer
|
* A body that does not entirely fit in memory.
|
||||||
* Storing a body in a user defined container with a custom allocator
|
* A body produced incrementally from coroutine output.
|
||||||
* Transformation of incoming body data before storage, for example
|
* A body represented by zero or more buffers already in memory.
|
||||||
to compress it first.
|
* A body whose size is not known ahead of time.
|
||||||
* Saving body data to a file
|
* Body data generated dynamically from other threads.
|
||||||
|
* Body data computed algorithmically.
|
||||||
|
|
||||||
[heading Associated Types]
|
[heading Associated Types]
|
||||||
|
|
||||||
@@ -35,71 +37,68 @@ In this table:
|
|||||||
* `B` denotes a __Body__ where
|
* `B` denotes a __Body__ where
|
||||||
`std::is_same<W, B::writer>::value == true`.
|
`std::is_same<W, B::writer>::value == true`.
|
||||||
* `a` denotes a value of type `W`.
|
* `a` denotes a value of type `W`.
|
||||||
* `b` is an object whose type meets the requirements of __ConstBufferSequence__
|
* `m` denotes a possibly const value of type `message&` where
|
||||||
* `m` denotes a value of type `message&` where
|
`std::is_same<decltype(m.body), Body::value_type>:value == true`.
|
||||||
`std::is_same<decltype(m.body), Body::value_type>::value == true`.
|
|
||||||
* `n` is a value of type `boost::optional<std::uint64_t>`.
|
|
||||||
* `ec` is a value of type [link beast.ref.boost__beast__error_code `error_code&`].
|
* `ec` is a value of type [link beast.ref.boost__beast__error_code `error_code&`].
|
||||||
|
* `W<T>` is the type `boost::optional<std::pair<T, bool>>`.
|
||||||
|
|
||||||
[table Valid expressions
|
[table Valid expressions
|
||||||
[[Expression] [Type] [Semantics, Pre/Post-conditions]]
|
[[Expression] [Type] [Semantics, Pre/Post-conditions]]
|
||||||
[
|
[
|
||||||
|
[`W::const_buffers_type`]
|
||||||
|
[]
|
||||||
|
[
|
||||||
|
A type which meets the requirements of __ConstBufferSequence__.
|
||||||
|
This is the type of buffer returned by `W::get`.
|
||||||
|
]
|
||||||
|
][
|
||||||
[`W(m);`]
|
[`W(m);`]
|
||||||
[]
|
[]
|
||||||
[
|
[
|
||||||
Constructible from `m`. The lifetime of `m` is guaranteed to
|
Constructible from `m`. The lifetime of `m` is guaranteed
|
||||||
end no earlier than after the `W` is destroyed. The constructor
|
to end no earlier than after the `W` is destroyed.
|
||||||
will be called after a complete header is stored in `m`, and
|
The writer shall not access the contents of `m` before the
|
||||||
before parsing body octets for messages indicating that a body
|
first call to `init`, permitting lazy construction of the
|
||||||
is present The writer shall not access the contents of `m` before
|
|
||||||
the first call to `init`, permitting lazy construction of the
|
|
||||||
message.
|
message.
|
||||||
|
|
||||||
The function will ensure that `!ec` is `true` if there was
|
The constructor may optionally require that `m` is const, which
|
||||||
no error or set to the appropriate error code if there was one.
|
has these consequences:
|
||||||
|
|
||||||
|
* If `W` requires that `m` is a const reference, then serializers
|
||||||
|
constructed for messages with this body type will also require a
|
||||||
|
const reference to a message, otherwise:
|
||||||
|
|
||||||
|
* If `W` requires that `m` is a non-const reference, then serializers
|
||||||
|
constructed for messages with this body type will aso require
|
||||||
|
a non-const reference to a message.
|
||||||
]
|
]
|
||||||
][
|
][
|
||||||
[`a.init(n, ec)`]
|
[`a.init(ec)`]
|
||||||
[]
|
[]
|
||||||
[
|
[
|
||||||
Called once to fully initialize the object before any calls to
|
Called once to fully initialize the object before any calls to
|
||||||
`put`. The message body is valid before entering this function,
|
`get`. The message body becomes valid before entering this function,
|
||||||
and remains valid until the writer is destroyed.
|
and remains valid until the writer is destroyed.
|
||||||
The value of `n` will be set to the content length of the
|
|
||||||
body if known, otherwise `n` will be equal to `boost::none`.
|
|
||||||
Implementations of [*BodyWriter] may use this information to
|
|
||||||
optimize allocation.
|
|
||||||
|
|
||||||
The function will ensure that `!ec` is `true` if there was
|
The function will ensure that `!ec` is `true` if there was
|
||||||
no error or set to the appropriate error code if there was one.
|
no error or set to the appropriate error code if there was one.
|
||||||
]
|
]
|
||||||
][
|
][
|
||||||
[`a.put(b,ec)`]
|
[`a.get(ec)`]
|
||||||
[`std::size_t`]
|
[`W<W::const_buffers_type>`]
|
||||||
[
|
[
|
||||||
This function is called to append some or all of the buffers
|
Called one or more times after `init` succeeds. This function
|
||||||
specified by `b` into the body representation. The number of
|
returns `boost::none` if all buffers representing the body have
|
||||||
bytes inserted from `b` is returned. If the number of bytes
|
been returned in previous calls or if it sets `ec` to indicate an
|
||||||
inserted is less than the total input, the remainder of the
|
error. Otherwise, if there are buffers remaining the function
|
||||||
input will be presented in the next call to `put`.
|
should return a pair with the first element containing a non-zero
|
||||||
|
length buffer sequence representing the next set of octets in
|
||||||
|
the body, while the second element is a `bool` meaning `true`
|
||||||
|
if there may be additional buffers returned on a subsequent call,
|
||||||
|
or `false` if the buffer returned on this call is the last
|
||||||
|
buffer representing the body.
|
||||||
The function will ensure that `!ec` is `true` if there was
|
The function will ensure that `!ec` is `true` if there was
|
||||||
no error or set to the appropriate error code if there was one.
|
no error or set to the appropriate error code if there was one.
|
||||||
]
|
]
|
||||||
][
|
|
||||||
[`a.finish(ec)`]
|
|
||||||
[]
|
|
||||||
[
|
|
||||||
This function is called when no more body octets are remaining.
|
|
||||||
The function will ensure that `!ec` is `true` if there was
|
|
||||||
no error or set to the appropriate error code if there was one.
|
|
||||||
]
|
|
||||||
][
|
|
||||||
[`is_body_writer<B>`]
|
|
||||||
[`std::true_type`]
|
|
||||||
[
|
|
||||||
An alias for `std::true_type` for `B`, otherwise an alias
|
|
||||||
for `std::false_type`.
|
|
||||||
]
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
[heading Exemplar]
|
[heading Exemplar]
|
||||||
|
@@ -111,8 +111,8 @@
|
|||||||
<bridgehead renderas="sect3">Type Traits</bridgehead>
|
<bridgehead renderas="sect3">Type Traits</bridgehead>
|
||||||
<simplelist type="vert" columns="1">
|
<simplelist type="vert" columns="1">
|
||||||
<member><link linkend="beast.ref.boost__beast__http__is_body">is_body</link></member>
|
<member><link linkend="beast.ref.boost__beast__http__is_body">is_body</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__http__is_body_writer">is_body_writer</link></member>
|
|
||||||
<member><link linkend="beast.ref.boost__beast__http__is_body_reader">is_body_reader</link></member>
|
<member><link linkend="beast.ref.boost__beast__http__is_body_reader">is_body_reader</link></member>
|
||||||
|
<member><link linkend="beast.ref.boost__beast__http__is_body_writer">is_body_writer</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__http__is_fields">is_fields</link></member>
|
<member><link linkend="beast.ref.boost__beast__http__is_fields">is_fields</link></member>
|
||||||
</simplelist>
|
</simplelist>
|
||||||
<bridgehead renderas="sect3">Concepts</bridgehead>
|
<bridgehead renderas="sect3">Concepts</bridgehead>
|
||||||
|
@@ -56,7 +56,7 @@ struct basic_dynamic_body
|
|||||||
return v.size();
|
return v.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The algorithm for serializing the body
|
/** The algorithm for parsing the body
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
Meets the requirements of @b BodyReader.
|
||||||
*/
|
*/
|
||||||
@@ -64,51 +64,13 @@ struct basic_dynamic_body
|
|||||||
using reader = implementation_defined;
|
using reader = implementation_defined;
|
||||||
#else
|
#else
|
||||||
class reader
|
class reader
|
||||||
{
|
|
||||||
DynamicBuffer const& body_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using const_buffers_type =
|
|
||||||
typename DynamicBuffer::const_buffers_type;
|
|
||||||
|
|
||||||
template<bool isRequest, class Fields>
|
|
||||||
explicit
|
|
||||||
reader(message<isRequest,
|
|
||||||
basic_dynamic_body, Fields> const& m)
|
|
||||||
: body_(m.body())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
init(error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<std::pair<const_buffers_type, bool>>
|
|
||||||
get(error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
return {{body_.data(), false}};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** The algorithm for parsing the body
|
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
|
||||||
*/
|
|
||||||
#if BOOST_BEAST_DOXYGEN
|
|
||||||
using writer = implementation_defined;
|
|
||||||
#else
|
|
||||||
class writer
|
|
||||||
{
|
{
|
||||||
value_type& body_;
|
value_type& body_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
explicit
|
explicit
|
||||||
writer(message<isRequest,
|
reader(message<isRequest,
|
||||||
basic_dynamic_body, Fields>& msg)
|
basic_dynamic_body, Fields>& msg)
|
||||||
: body_(msg.body())
|
: body_(msg.body())
|
||||||
{
|
{
|
||||||
@@ -160,6 +122,44 @@ struct basic_dynamic_body
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** The algorithm for serializing the body
|
||||||
|
|
||||||
|
Meets the requirements of @b BodyWriter.
|
||||||
|
*/
|
||||||
|
#if BOOST_BEAST_DOXYGEN
|
||||||
|
using writer = implementation_defined;
|
||||||
|
#else
|
||||||
|
class writer
|
||||||
|
{
|
||||||
|
DynamicBuffer const& body_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using const_buffers_type =
|
||||||
|
typename DynamicBuffer::const_buffers_type;
|
||||||
|
|
||||||
|
template<bool isRequest, class Fields>
|
||||||
|
explicit
|
||||||
|
writer(message<isRequest,
|
||||||
|
basic_dynamic_body, Fields> const& m)
|
||||||
|
: body_(m.body())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init(error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<std::pair<const_buffers_type, bool>>
|
||||||
|
get(error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
return {{body_.data(), false}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
|
@@ -51,10 +51,10 @@ struct basic_file_body
|
|||||||
/// The type of File this body uses
|
/// The type of File this body uses
|
||||||
using file_type = File;
|
using file_type = File;
|
||||||
|
|
||||||
// Algorithm for retrieving buffers when serializing.
|
// Algorithm for storing buffers when parsing.
|
||||||
class reader;
|
class reader;
|
||||||
|
|
||||||
// Algorithm for storing buffers when parsing.
|
// Algorithm for retrieving buffers when serializing.
|
||||||
class writer;
|
class writer;
|
||||||
|
|
||||||
// The type of the @ref message::body member.
|
// The type of the @ref message::body member.
|
||||||
@@ -225,7 +225,7 @@ size(value_type const& body)
|
|||||||
to extract the buffers representing the body.
|
to extract the buffers representing the body.
|
||||||
*/
|
*/
|
||||||
template<class File>
|
template<class File>
|
||||||
class basic_file_body<File>::reader
|
class basic_file_body<File>::writer
|
||||||
{
|
{
|
||||||
value_type& body_; // The body we are reading from
|
value_type& body_; // The body we are reading from
|
||||||
std::uint64_t remain_; // The number of unread bytes
|
std::uint64_t remain_; // The number of unread bytes
|
||||||
@@ -239,8 +239,8 @@ public:
|
|||||||
|
|
||||||
// Constructor.
|
// Constructor.
|
||||||
//
|
//
|
||||||
// `m` holds the message we are sending, which will
|
// `m` holds the message we are serializing, which will
|
||||||
// always have the `file_body` as the body type.
|
// always have the `basic_file_body` as the body type.
|
||||||
//
|
//
|
||||||
// Note that the message is passed by non-const reference.
|
// Note that the message is passed by non-const reference.
|
||||||
// This is intentional, because reading from the file
|
// This is intentional, because reading from the file
|
||||||
@@ -248,7 +248,7 @@ public:
|
|||||||
// operation logically not-const (although it is bitwise
|
// operation logically not-const (although it is bitwise
|
||||||
// const).
|
// const).
|
||||||
//
|
//
|
||||||
// The BodyReader concept allows the reader to choose
|
// The BodyWriter concept allows the writer to choose
|
||||||
// whether to take the message by const reference or
|
// whether to take the message by const reference or
|
||||||
// non-const reference. Depending on the choice, a
|
// non-const reference. Depending on the choice, a
|
||||||
// serializer constructed using that body type will
|
// serializer constructed using that body type will
|
||||||
@@ -262,13 +262,13 @@ public:
|
|||||||
// a time.
|
// a time.
|
||||||
//
|
//
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
reader(message<
|
writer(message<
|
||||||
isRequest, basic_file_body, Fields>& m);
|
isRequest, basic_file_body, Fields>& m);
|
||||||
|
|
||||||
// Initializer
|
// Initializer
|
||||||
//
|
//
|
||||||
// This is called before the body is serialized and
|
// This is called before the body is serialized and
|
||||||
// gives the reader a chance to do something that might
|
// gives the writer a chance to do something that might
|
||||||
// need to return an error code.
|
// need to return an error code.
|
||||||
//
|
//
|
||||||
void
|
void
|
||||||
@@ -295,8 +295,8 @@ public:
|
|||||||
template<class File>
|
template<class File>
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
basic_file_body<File>::
|
basic_file_body<File>::
|
||||||
reader::
|
writer::
|
||||||
reader(message<isRequest, basic_file_body, Fields>& m)
|
writer(message<isRequest, basic_file_body, Fields>& m)
|
||||||
: body_(m.body())
|
: body_(m.body())
|
||||||
{
|
{
|
||||||
// The file must already be open
|
// The file must already be open
|
||||||
@@ -310,7 +310,7 @@ reader(message<isRequest, basic_file_body, Fields>& m)
|
|||||||
template<class File>
|
template<class File>
|
||||||
void
|
void
|
||||||
basic_file_body<File>::
|
basic_file_body<File>::
|
||||||
reader::
|
writer::
|
||||||
init(error_code& ec)
|
init(error_code& ec)
|
||||||
{
|
{
|
||||||
// The error_code specification requires that we
|
// The error_code specification requires that we
|
||||||
@@ -329,7 +329,7 @@ init(error_code& ec)
|
|||||||
template<class File>
|
template<class File>
|
||||||
auto
|
auto
|
||||||
basic_file_body<File>::
|
basic_file_body<File>::
|
||||||
reader::
|
writer::
|
||||||
get(error_code& ec) ->
|
get(error_code& ec) ->
|
||||||
boost::optional<std::pair<const_buffers_type, bool>>
|
boost::optional<std::pair<const_buffers_type, bool>>
|
||||||
{
|
{
|
||||||
@@ -389,7 +389,7 @@ get(error_code& ec) ->
|
|||||||
to store incoming buffers representing the body.
|
to store incoming buffers representing the body.
|
||||||
*/
|
*/
|
||||||
template<class File>
|
template<class File>
|
||||||
class basic_file_body<File>::writer
|
class basic_file_body<File>::reader
|
||||||
{
|
{
|
||||||
value_type& body_; // The body we are writing to
|
value_type& body_; // The body we are writing to
|
||||||
|
|
||||||
@@ -399,17 +399,17 @@ public:
|
|||||||
// This is called after the header is parsed and
|
// This is called after the header is parsed and
|
||||||
// indicates that a non-zero sized body may be present.
|
// indicates that a non-zero sized body may be present.
|
||||||
// `m` holds the message we are receiving, which will
|
// `m` holds the message we are receiving, which will
|
||||||
// always have the `file_body` as the body type.
|
// always have the `basic_file_body` as the body type.
|
||||||
//
|
//
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
explicit
|
explicit
|
||||||
writer(
|
reader(
|
||||||
message<isRequest, basic_file_body, Fields>& m);
|
message<isRequest, basic_file_body, Fields>& m);
|
||||||
|
|
||||||
// Initializer
|
// Initializer
|
||||||
//
|
//
|
||||||
// This is called before the body is parsed and
|
// This is called before the body is parsed and
|
||||||
// gives the writer a chance to do something that might
|
// gives the reader a chance to do something that might
|
||||||
// need to return an error code. It informs us of
|
// need to return an error code. It informs us of
|
||||||
// the payload size (`content_length`) which we can
|
// the payload size (`content_length`) which we can
|
||||||
// optionally use for optimization.
|
// optionally use for optimization.
|
||||||
@@ -440,14 +440,14 @@ public:
|
|||||||
|
|
||||||
//[example_http_file_body_6
|
//[example_http_file_body_6
|
||||||
|
|
||||||
// We don't do much in the writer constructor since the
|
// We don't do much in the reader constructor since the
|
||||||
// file is already open.
|
// file is already open.
|
||||||
//
|
//
|
||||||
template<class File>
|
template<class File>
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
basic_file_body<File>::
|
basic_file_body<File>::
|
||||||
writer::
|
reader::
|
||||||
writer(message<isRequest, basic_file_body, Fields>& m)
|
reader(message<isRequest, basic_file_body, Fields>& m)
|
||||||
: body_(m.body())
|
: body_(m.body())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -455,7 +455,7 @@ writer(message<isRequest, basic_file_body, Fields>& m)
|
|||||||
template<class File>
|
template<class File>
|
||||||
void
|
void
|
||||||
basic_file_body<File>::
|
basic_file_body<File>::
|
||||||
writer::
|
reader::
|
||||||
init(
|
init(
|
||||||
boost::optional<std::uint64_t> const& content_length,
|
boost::optional<std::uint64_t> const& content_length,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
@@ -482,7 +482,7 @@ template<class File>
|
|||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
std::size_t
|
std::size_t
|
||||||
basic_file_body<File>::
|
basic_file_body<File>::
|
||||||
writer::
|
reader::
|
||||||
put(ConstBufferSequence const& buffers, error_code& ec)
|
put(ConstBufferSequence const& buffers, error_code& ec)
|
||||||
{
|
{
|
||||||
// This function must return the total number of
|
// This function must return the total number of
|
||||||
@@ -513,7 +513,7 @@ put(ConstBufferSequence const& buffers, error_code& ec)
|
|||||||
template<class File>
|
template<class File>
|
||||||
void
|
void
|
||||||
basic_file_body<File>::
|
basic_file_body<File>::
|
||||||
writer::
|
reader::
|
||||||
finish(error_code& ec)
|
finish(error_code& ec)
|
||||||
{
|
{
|
||||||
// This has to be cleared before returning, to
|
// This has to be cleared before returning, to
|
||||||
|
@@ -91,7 +91,7 @@ struct buffer_body
|
|||||||
bool more = true;
|
bool more = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The algorithm for serializing the body
|
/** The algorithm for parsing the body
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
Meets the requirements of @b BodyReader.
|
||||||
*/
|
*/
|
||||||
@@ -99,6 +99,64 @@ struct buffer_body
|
|||||||
using reader = implementation_defined;
|
using reader = implementation_defined;
|
||||||
#else
|
#else
|
||||||
class reader
|
class reader
|
||||||
|
{
|
||||||
|
value_type& body_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<bool isRequest, class Fields>
|
||||||
|
explicit
|
||||||
|
reader(message<isRequest, buffer_body, Fields>& m)
|
||||||
|
: body_(m.body())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init(boost::optional<std::uint64_t> const&, error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ConstBufferSequence>
|
||||||
|
std::size_t
|
||||||
|
put(ConstBufferSequence const& buffers,
|
||||||
|
error_code& ec)
|
||||||
|
{
|
||||||
|
using boost::asio::buffer_size;
|
||||||
|
using boost::asio::buffer_copy;
|
||||||
|
if(! body_.data)
|
||||||
|
{
|
||||||
|
ec = error::need_buffer;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto const bytes_transferred =
|
||||||
|
buffer_copy(boost::asio::buffer(
|
||||||
|
body_.data, body_.size), buffers);
|
||||||
|
body_.data = reinterpret_cast<char*>(
|
||||||
|
body_.data) + bytes_transferred;
|
||||||
|
body_.size -= bytes_transferred;
|
||||||
|
if(bytes_transferred == buffer_size(buffers))
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
else
|
||||||
|
ec = error::need_buffer;
|
||||||
|
return bytes_transferred;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
finish(error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** The algorithm for serializing the body
|
||||||
|
|
||||||
|
Meets the requirements of @b BodyWriter.
|
||||||
|
*/
|
||||||
|
#if BOOST_BEAST_DOXYGEN
|
||||||
|
using writer = implementation_defined;
|
||||||
|
#else
|
||||||
|
class writer
|
||||||
{
|
{
|
||||||
bool toggle_ = false;
|
bool toggle_ = false;
|
||||||
value_type const& body_;
|
value_type const& body_;
|
||||||
@@ -109,7 +167,7 @@ struct buffer_body
|
|||||||
|
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
explicit
|
explicit
|
||||||
reader(message<isRequest,
|
writer(message<isRequest,
|
||||||
buffer_body, Fields> const& msg)
|
buffer_body, Fields> const& msg)
|
||||||
: body_(msg.body())
|
: body_(msg.body())
|
||||||
{
|
{
|
||||||
@@ -153,64 +211,6 @@ struct buffer_body
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** The algorithm for parsing the body
|
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
|
||||||
*/
|
|
||||||
#if BOOST_BEAST_DOXYGEN
|
|
||||||
using writer = implementation_defined;
|
|
||||||
#else
|
|
||||||
class writer
|
|
||||||
{
|
|
||||||
value_type& body_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
template<bool isRequest, class Fields>
|
|
||||||
explicit
|
|
||||||
writer(message<isRequest, buffer_body, Fields>& m)
|
|
||||||
: body_(m.body())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
init(boost::optional<std::uint64_t> const&, error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
|
||||||
std::size_t
|
|
||||||
put(ConstBufferSequence const& buffers,
|
|
||||||
error_code& ec)
|
|
||||||
{
|
|
||||||
using boost::asio::buffer_size;
|
|
||||||
using boost::asio::buffer_copy;
|
|
||||||
if(! body_.data)
|
|
||||||
{
|
|
||||||
ec = error::need_buffer;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
auto const bytes_transferred =
|
|
||||||
buffer_copy(boost::asio::buffer(
|
|
||||||
body_.data, body_.size), buffers);
|
|
||||||
body_.data = reinterpret_cast<char*>(
|
|
||||||
body_.data) + bytes_transferred;
|
|
||||||
body_.size -= bytes_transferred;
|
|
||||||
if(bytes_transferred == buffer_size(buffers))
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
else
|
|
||||||
ec = error::need_buffer;
|
|
||||||
return bytes_transferred;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
finish(error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if ! BOOST_BEAST_DOXYGEN
|
#if ! BOOST_BEAST_DOXYGEN
|
||||||
|
@@ -52,7 +52,7 @@ struct empty_body
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The algorithm for serializing the body
|
/** The algorithm for parsing the body
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
Meets the requirements of @b BodyReader.
|
||||||
*/
|
*/
|
||||||
@@ -61,43 +61,9 @@ struct empty_body
|
|||||||
#else
|
#else
|
||||||
struct reader
|
struct reader
|
||||||
{
|
{
|
||||||
using const_buffers_type =
|
|
||||||
boost::asio::null_buffers;
|
|
||||||
|
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
explicit
|
explicit
|
||||||
reader(message<isRequest,
|
reader(message<isRequest, empty_body, Fields>&)
|
||||||
empty_body, Fields> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
init(error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<std::pair<const_buffers_type, bool>>
|
|
||||||
get(error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
return boost::none;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** The algorithm for parsing the body
|
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
|
||||||
*/
|
|
||||||
#if BOOST_BEAST_DOXYGEN
|
|
||||||
using writer = implementation_defined;
|
|
||||||
#else
|
|
||||||
struct writer
|
|
||||||
{
|
|
||||||
template<bool isRequest, class Fields>
|
|
||||||
explicit
|
|
||||||
writer(message<isRequest, empty_body, Fields>&)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +89,40 @@ struct empty_body
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** The algorithm for serializing the body
|
||||||
|
|
||||||
|
Meets the requirements of @b BodyWriter.
|
||||||
|
*/
|
||||||
|
#if BOOST_BEAST_DOXYGEN
|
||||||
|
using writer = implementation_defined;
|
||||||
|
#else
|
||||||
|
struct writer
|
||||||
|
{
|
||||||
|
using const_buffers_type =
|
||||||
|
boost::asio::null_buffers;
|
||||||
|
|
||||||
|
template<bool isRequest, class Fields>
|
||||||
|
explicit
|
||||||
|
writer(message<isRequest,
|
||||||
|
empty_body, Fields> const&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init(error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<std::pair<const_buffers_type, bool>>
|
||||||
|
get(error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
|
@@ -42,15 +42,15 @@ struct basic_file_body<file_win32>
|
|||||||
{
|
{
|
||||||
using file_type = file_win32;
|
using file_type = file_win32;
|
||||||
|
|
||||||
class reader;
|
|
||||||
class writer;
|
class writer;
|
||||||
|
class reader;
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
class value_type
|
class value_type
|
||||||
{
|
{
|
||||||
friend class reader;
|
|
||||||
friend class writer;
|
friend class writer;
|
||||||
|
friend class reader;
|
||||||
friend struct basic_file_body<file_win32>;
|
friend struct basic_file_body<file_win32>;
|
||||||
|
|
||||||
template<class, class, bool, class>
|
template<class, class, bool, class>
|
||||||
@@ -100,7 +100,7 @@ struct basic_file_body<file_win32>
|
|||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
class reader
|
class writer
|
||||||
{
|
{
|
||||||
template<class, class, bool, class>
|
template<class, class, bool, class>
|
||||||
friend class detail::write_some_win32_op;
|
friend class detail::write_some_win32_op;
|
||||||
@@ -123,7 +123,7 @@ struct basic_file_body<file_win32>
|
|||||||
boost::asio::const_buffer;
|
boost::asio::const_buffer;
|
||||||
|
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
reader(message<isRequest,
|
writer(message<isRequest,
|
||||||
basic_file_body<file_win32>, Fields>& m)
|
basic_file_body<file_win32>, Fields>& m)
|
||||||
: body_(m.body())
|
: body_(m.body())
|
||||||
{
|
{
|
||||||
@@ -160,14 +160,14 @@ struct basic_file_body<file_win32>
|
|||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
class writer
|
class reader
|
||||||
{
|
{
|
||||||
value_type& body_;
|
value_type& body_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
explicit
|
explicit
|
||||||
writer(message<isRequest, basic_file_body, Fields>& m)
|
reader(message<isRequest, basic_file_body, Fields>& m)
|
||||||
: body_(m.body())
|
: body_(m.body())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -44,7 +44,7 @@ parser(parser<isRequest, OtherBody, Allocator>&& other,
|
|||||||
, m_(other.release(), std::forward<Args>(args)...)
|
, m_(other.release(), std::forward<Args>(args)...)
|
||||||
, wr_(m_)
|
, wr_(m_)
|
||||||
{
|
{
|
||||||
if(other.wr_inited_)
|
if(other.rd_inited_)
|
||||||
BOOST_THROW_EXCEPTION(std::invalid_argument{
|
BOOST_THROW_EXCEPTION(std::invalid_argument{
|
||||||
"moved-from parser has a body"});
|
"moved-from parser has a body"});
|
||||||
}
|
}
|
||||||
|
@@ -738,8 +738,8 @@ read(
|
|||||||
"DynamicBuffer requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_writer<Body>::value,
|
static_assert(is_body_reader<Body>::value,
|
||||||
"BodyWriter requirements not met");
|
"BodyReader requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
auto const bytes_transferred =
|
auto const bytes_transferred =
|
||||||
read(stream, buffer, msg, ec);
|
read(stream, buffer, msg, ec);
|
||||||
@@ -766,8 +766,8 @@ read(
|
|||||||
"DynamicBuffer requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_writer<Body>::value,
|
static_assert(is_body_reader<Body>::value,
|
||||||
"BodyWriter requirements not met");
|
"BodyReader requirements not met");
|
||||||
parser<isRequest, Body, Allocator> p{std::move(msg)};
|
parser<isRequest, Body, Allocator> p{std::move(msg)};
|
||||||
p.eager(true);
|
p.eager(true);
|
||||||
auto const bytes_transferred =
|
auto const bytes_transferred =
|
||||||
@@ -798,8 +798,8 @@ async_read(
|
|||||||
"DynamicBuffer requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_writer<Body>::value,
|
static_assert(is_body_reader<Body>::value,
|
||||||
"BodyWriter requirements not met");
|
"BodyReader requirements not met");
|
||||||
boost::asio::async_completion<
|
boost::asio::async_completion<
|
||||||
ReadHandler,
|
ReadHandler,
|
||||||
void(error_code, std::size_t)> init{handler};
|
void(error_code, std::size_t)> init{handler};
|
||||||
|
@@ -499,8 +499,8 @@ write_some(
|
|||||||
"SyncWriteStream requirements not met");
|
"SyncWriteStream requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
auto const bytes_transferred =
|
auto const bytes_transferred =
|
||||||
write_some(stream, sr, ec);
|
write_some(stream, sr, ec);
|
||||||
@@ -522,8 +522,8 @@ write_some(
|
|||||||
"SyncWriteStream requirements not met");
|
"SyncWriteStream requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
return detail::write_some(stream, sr, ec);
|
return detail::write_some(stream, sr, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,8 +543,8 @@ async_write_some(
|
|||||||
"AsyncWriteStream requirements not met");
|
"AsyncWriteStream requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
return detail::async_write_some(stream, sr,
|
return detail::async_write_some(stream, sr,
|
||||||
std::forward<WriteHandler>(handler));
|
std::forward<WriteHandler>(handler));
|
||||||
}
|
}
|
||||||
@@ -562,8 +562,8 @@ write_header(SyncWriteStream& stream,
|
|||||||
"SyncWriteStream requirements not met");
|
"SyncWriteStream requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
auto const bytes_transferred =
|
auto const bytes_transferred =
|
||||||
write_header(stream, sr, ec);
|
write_header(stream, sr, ec);
|
||||||
@@ -585,8 +585,8 @@ write_header(
|
|||||||
"SyncWriteStream requirements not met");
|
"SyncWriteStream requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
sr.split(true);
|
sr.split(true);
|
||||||
std::size_t bytes_transferred = 0;
|
std::size_t bytes_transferred = 0;
|
||||||
if(! sr.is_header_done())
|
if(! sr.is_header_done())
|
||||||
@@ -626,8 +626,8 @@ async_write_header(
|
|||||||
"AsyncWriteStream requirements not met");
|
"AsyncWriteStream requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
sr.split(true);
|
sr.split(true);
|
||||||
boost::asio::async_completion<
|
boost::asio::async_completion<
|
||||||
WriteHandler,
|
WriteHandler,
|
||||||
@@ -703,8 +703,8 @@ async_write(
|
|||||||
"AsyncWriteStream requirements not met");
|
"AsyncWriteStream requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
sr.split(false);
|
sr.split(false);
|
||||||
boost::asio::async_completion<
|
boost::asio::async_completion<
|
||||||
WriteHandler,
|
WriteHandler,
|
||||||
@@ -733,8 +733,8 @@ write(
|
|||||||
"SyncWriteStream requirements not met");
|
"SyncWriteStream requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
auto const bytes_transferred =
|
auto const bytes_transferred =
|
||||||
write(stream, msg, ec);
|
write(stream, msg, ec);
|
||||||
@@ -756,8 +756,8 @@ write(
|
|||||||
"SyncWriteStream requirements not met");
|
"SyncWriteStream requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
serializer<isRequest, Body, Fields> sr{msg};
|
serializer<isRequest, Body, Fields> sr{msg};
|
||||||
return write(stream, sr, ec);
|
return write(stream, sr, ec);
|
||||||
}
|
}
|
||||||
@@ -778,8 +778,8 @@ async_write(
|
|||||||
"AsyncWriteStream requirements not met");
|
"AsyncWriteStream requirements not met");
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
boost::asio::async_completion<
|
boost::asio::async_completion<
|
||||||
WriteHandler,
|
WriteHandler,
|
||||||
void(error_code, std::size_t)> init{handler};
|
void(error_code, std::size_t)> init{handler};
|
||||||
@@ -860,8 +860,8 @@ operator<<(std::ostream& os,
|
|||||||
{
|
{
|
||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
serializer<isRequest, Body, Fields> sr{msg};
|
serializer<isRequest, Body, Fields> sr{msg};
|
||||||
error_code ec;
|
error_code ec;
|
||||||
detail::write_ostream_lambda<decltype(sr)> f{os, sr};
|
detail::write_ostream_lambda<decltype(sr)> f{os, sr};
|
||||||
|
@@ -53,8 +53,8 @@ class parser
|
|||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
|
|
||||||
static_assert(is_body_writer<Body>::value,
|
static_assert(is_body_reader<Body>::value,
|
||||||
"BodyWriter requirements not met");
|
"BodyReader requirements not met");
|
||||||
|
|
||||||
template<bool, class, class>
|
template<bool, class, class>
|
||||||
friend class parser;
|
friend class parser;
|
||||||
@@ -63,8 +63,8 @@ class parser
|
|||||||
parser<isRequest, Body, Allocator>>;
|
parser<isRequest, Body, Allocator>>;
|
||||||
|
|
||||||
message<isRequest, Body, basic_fields<Allocator>> m_;
|
message<isRequest, Body, basic_fields<Allocator>> m_;
|
||||||
typename Body::writer wr_;
|
typename Body::reader wr_;
|
||||||
bool wr_inited_ = false;
|
bool rd_inited_ = false;
|
||||||
|
|
||||||
std::function<void(
|
std::function<void(
|
||||||
std::uint64_t,
|
std::uint64_t,
|
||||||
@@ -127,7 +127,7 @@ public:
|
|||||||
This constructs a new parser by move constructing the
|
This constructs a new parser by move constructing the
|
||||||
header from another parser with a different body type. The
|
header from another parser with a different body type. The
|
||||||
constructed-from parser must not have any parsed body octets or
|
constructed-from parser must not have any parsed body octets or
|
||||||
initialized @b BodyWriter, otherwise an exception is generated.
|
initialized @b BodyReader, otherwise an exception is generated.
|
||||||
|
|
||||||
@par Example
|
@par Example
|
||||||
@code
|
@code
|
||||||
@@ -148,7 +148,7 @@ public:
|
|||||||
constructor.
|
constructor.
|
||||||
|
|
||||||
@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 reader.
|
||||||
|
|
||||||
@note This function participates in overload resolution only
|
@note This function participates in overload resolution only
|
||||||
if the other parser uses a different body type.
|
if the other parser uses a different body type.
|
||||||
@@ -247,7 +247,7 @@ public:
|
|||||||
BOOST_STATIC_ASSERT(! std::is_const<Callback>::value);
|
BOOST_STATIC_ASSERT(! std::is_const<Callback>::value);
|
||||||
|
|
||||||
// Can't set the callback after receiving any chunk data!
|
// Can't set the callback after receiving any chunk data!
|
||||||
BOOST_ASSERT(! wr_inited_);
|
BOOST_ASSERT(! rd_inited_);
|
||||||
|
|
||||||
cb_h_ = std::ref(cb);
|
cb_h_ = std::ref(cb);
|
||||||
}
|
}
|
||||||
@@ -295,7 +295,7 @@ public:
|
|||||||
BOOST_STATIC_ASSERT(! std::is_const<Callback>::value);
|
BOOST_STATIC_ASSERT(! std::is_const<Callback>::value);
|
||||||
|
|
||||||
// Can't set the callback after receiving any chunk data!
|
// Can't set the callback after receiving any chunk data!
|
||||||
BOOST_ASSERT(! wr_inited_);
|
BOOST_ASSERT(! rd_inited_);
|
||||||
|
|
||||||
cb_b_ = std::ref(cb);
|
cb_b_ = std::ref(cb);
|
||||||
}
|
}
|
||||||
@@ -377,7 +377,7 @@ private:
|
|||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
wr_.init(content_length, ec);
|
wr_.init(content_length, ec);
|
||||||
wr_inited_ = true;
|
rd_inited_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
std::size_t
|
||||||
|
@@ -60,22 +60,22 @@ public:
|
|||||||
static_assert(is_body<Body>::value,
|
static_assert(is_body<Body>::value,
|
||||||
"Body requirements not met");
|
"Body requirements not met");
|
||||||
|
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
|
|
||||||
/** The type of message this serializer uses
|
/** The type of message this serializer uses
|
||||||
|
|
||||||
This may be const or non-const depending on the
|
This may be const or non-const depending on the
|
||||||
implementation of the corresponding @b BodyReader.
|
implementation of the corresponding @b BodyWriter.
|
||||||
*/
|
*/
|
||||||
#if BOOST_BEAST_DOXYGEN
|
#if BOOST_BEAST_DOXYGEN
|
||||||
using value_type = implementation_defined;
|
using value_type = implementation_defined;
|
||||||
#else
|
#else
|
||||||
using value_type =
|
using value_type =
|
||||||
typename std::conditional<
|
typename std::conditional<
|
||||||
std::is_constructible<typename Body::reader,
|
std::is_constructible<typename Body::writer,
|
||||||
message<isRequest, Body, Fields>&>::value &&
|
message<isRequest, Body, Fields>&>::value &&
|
||||||
! std::is_constructible<typename Body::reader,
|
! std::is_constructible<typename Body::writer,
|
||||||
message<isRequest, Body, Fields> const&>::value,
|
message<isRequest, Body, Fields> const&>::value,
|
||||||
message<isRequest, Body, Fields>,
|
message<isRequest, Body, Fields>,
|
||||||
message<isRequest, Body, Fields> const>::type;
|
message<isRequest, Body, Fields> const>::type;
|
||||||
@@ -111,7 +111,7 @@ private:
|
|||||||
void
|
void
|
||||||
do_visit(error_code& ec, Visit& visit);
|
do_visit(error_code& ec, Visit& visit);
|
||||||
|
|
||||||
using reader = typename Body::reader;
|
using writer = typename Body::writer;
|
||||||
|
|
||||||
using cb1_t = buffers_suffix<typename
|
using cb1_t = buffers_suffix<typename
|
||||||
Fields::writer::const_buffers_type>; // header
|
Fields::writer::const_buffers_type>; // header
|
||||||
@@ -119,11 +119,11 @@ private:
|
|||||||
|
|
||||||
using cb2_t = buffers_suffix<buffers_cat_view<
|
using cb2_t = buffers_suffix<buffers_cat_view<
|
||||||
typename Fields::writer::const_buffers_type,// header
|
typename Fields::writer::const_buffers_type,// header
|
||||||
typename reader::const_buffers_type>>; // body
|
typename writer::const_buffers_type>>; // body
|
||||||
using pcb2_t = buffers_prefix_view<cb2_t const&>;
|
using pcb2_t = buffers_prefix_view<cb2_t const&>;
|
||||||
|
|
||||||
using cb3_t = buffers_suffix<
|
using cb3_t = buffers_suffix<
|
||||||
typename reader::const_buffers_type>; // body
|
typename writer::const_buffers_type>; // body
|
||||||
using pcb3_t = buffers_prefix_view<cb3_t const&>;
|
using pcb3_t = buffers_prefix_view<cb3_t const&>;
|
||||||
|
|
||||||
using cb4_t = buffers_suffix<buffers_cat_view<
|
using cb4_t = buffers_suffix<buffers_cat_view<
|
||||||
@@ -131,7 +131,7 @@ private:
|
|||||||
detail::chunk_size, // chunk-size
|
detail::chunk_size, // chunk-size
|
||||||
boost::asio::const_buffer, // chunk-ext
|
boost::asio::const_buffer, // chunk-ext
|
||||||
chunk_crlf, // crlf
|
chunk_crlf, // crlf
|
||||||
typename reader::const_buffers_type, // body
|
typename writer::const_buffers_type, // body
|
||||||
chunk_crlf>>; // crlf
|
chunk_crlf>>; // crlf
|
||||||
using pcb4_t = buffers_prefix_view<cb4_t const&>;
|
using pcb4_t = buffers_prefix_view<cb4_t const&>;
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ private:
|
|||||||
detail::chunk_size, // chunk-header
|
detail::chunk_size, // chunk-header
|
||||||
boost::asio::const_buffer, // chunk-ext
|
boost::asio::const_buffer, // chunk-ext
|
||||||
chunk_crlf, // crlf
|
chunk_crlf, // crlf
|
||||||
typename reader::const_buffers_type, // body
|
typename writer::const_buffers_type, // body
|
||||||
chunk_crlf>>; // crlf
|
chunk_crlf>>; // crlf
|
||||||
using pcb5_t = buffers_prefix_view<cb5_t const&>;
|
using pcb5_t = buffers_prefix_view<cb5_t const&>;
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ private:
|
|||||||
detail::chunk_size, // chunk-header
|
detail::chunk_size, // chunk-header
|
||||||
boost::asio::const_buffer, // chunk-size
|
boost::asio::const_buffer, // chunk-size
|
||||||
chunk_crlf, // crlf
|
chunk_crlf, // crlf
|
||||||
typename reader::const_buffers_type, // body
|
typename writer::const_buffers_type, // body
|
||||||
chunk_crlf, // crlf
|
chunk_crlf, // crlf
|
||||||
boost::asio::const_buffer, // chunk-final
|
boost::asio::const_buffer, // chunk-final
|
||||||
boost::asio::const_buffer, // trailers
|
boost::asio::const_buffer, // trailers
|
||||||
@@ -159,7 +159,7 @@ private:
|
|||||||
detail::chunk_size, // chunk-size
|
detail::chunk_size, // chunk-size
|
||||||
boost::asio::const_buffer, // chunk-ext
|
boost::asio::const_buffer, // chunk-ext
|
||||||
chunk_crlf, // crlf
|
chunk_crlf, // crlf
|
||||||
typename reader::const_buffers_type, // body
|
typename writer::const_buffers_type, // body
|
||||||
chunk_crlf, // crlf
|
chunk_crlf, // crlf
|
||||||
boost::asio::const_buffer, // chunk-final
|
boost::asio::const_buffer, // chunk-final
|
||||||
boost::asio::const_buffer, // trailers
|
boost::asio::const_buffer, // trailers
|
||||||
@@ -173,7 +173,7 @@ private:
|
|||||||
using pcb8_t = buffers_prefix_view<cb8_t const&>;
|
using pcb8_t = buffers_prefix_view<cb8_t const&>;
|
||||||
|
|
||||||
value_type& m_;
|
value_type& m_;
|
||||||
reader rd_;
|
writer rd_;
|
||||||
boost::optional<typename Fields::writer> frd_;
|
boost::optional<typename Fields::writer> frd_;
|
||||||
beast::detail::variant<
|
beast::detail::variant<
|
||||||
cb1_t, cb2_t, cb3_t, cb4_t,
|
cb1_t, cb2_t, cb3_t, cb4_t,
|
||||||
@@ -210,7 +210,7 @@ public:
|
|||||||
the type of Body used, this may or may not be a `const` reference.
|
the type of Body used, this may or may not be a `const` reference.
|
||||||
|
|
||||||
@note This function participates in overload resolution only if
|
@note This function participates in overload resolution only if
|
||||||
Body::reader is constructible from a `const` message reference.
|
Body::writer is constructible from a `const` message reference.
|
||||||
*/
|
*/
|
||||||
explicit
|
explicit
|
||||||
serializer(value_type& msg);
|
serializer(value_type& msg);
|
||||||
@@ -336,17 +336,17 @@ public:
|
|||||||
void
|
void
|
||||||
consume(std::size_t n);
|
consume(std::size_t n);
|
||||||
|
|
||||||
/** Provides low-level access to the associated @b BodyReader
|
/** Provides low-level access to the associated @b BodyWriter
|
||||||
|
|
||||||
This function provides access to the instance of the reader
|
This function provides access to the instance of the writer
|
||||||
associated with the body and created by the serializer
|
associated with the body and created by the serializer
|
||||||
upon construction. The behavior of accessing this object
|
upon construction. The behavior of accessing this object
|
||||||
is defined by the specification of the particular reader
|
is defined by the specification of the particular writer
|
||||||
and its associated body.
|
and its associated body.
|
||||||
|
|
||||||
@return A reference to the reader.
|
@return A reference to the writer.
|
||||||
*/
|
*/
|
||||||
reader&
|
writer&
|
||||||
reader_impl()
|
reader_impl()
|
||||||
{
|
{
|
||||||
return rd_;
|
return rd_;
|
||||||
|
@@ -59,7 +59,7 @@ public:
|
|||||||
return body.size();
|
return body.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The algorithm for serializing the body
|
/** The algorithm for parsing the body
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
Meets the requirements of @b BodyReader.
|
||||||
*/
|
*/
|
||||||
@@ -67,55 +67,13 @@ public:
|
|||||||
using reader = implementation_defined;
|
using reader = implementation_defined;
|
||||||
#else
|
#else
|
||||||
class reader
|
class reader
|
||||||
{
|
|
||||||
value_type const& body_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using const_buffers_type =
|
|
||||||
boost::asio::const_buffer;
|
|
||||||
|
|
||||||
template<bool isRequest, class Fields>
|
|
||||||
explicit
|
|
||||||
reader(message<isRequest,
|
|
||||||
span_body, Fields> const& msg)
|
|
||||||
: body_(msg.body())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
init(error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<std::pair<const_buffers_type, bool>>
|
|
||||||
get(error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
return {{
|
|
||||||
{ body_.data(),
|
|
||||||
body_.size() * sizeof(typename
|
|
||||||
value_type::value_type)},
|
|
||||||
false}};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** The algorithm for parsing the body
|
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
|
||||||
*/
|
|
||||||
#if BOOST_BEAST_DOXYGEN
|
|
||||||
using writer = implementation_defined;
|
|
||||||
#else
|
|
||||||
class writer
|
|
||||||
{
|
{
|
||||||
value_type& body_;
|
value_type& body_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
explicit
|
explicit
|
||||||
writer(message<isRequest,
|
reader(message<isRequest,
|
||||||
span_body, Fields>& m)
|
span_body, Fields>& m)
|
||||||
: body_(m.body())
|
: body_(m.body())
|
||||||
{
|
{
|
||||||
@@ -162,6 +120,48 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** The algorithm for serializing the body
|
||||||
|
|
||||||
|
Meets the requirements of @b BodyWriter.
|
||||||
|
*/
|
||||||
|
#if BOOST_BEAST_DOXYGEN
|
||||||
|
using writer = implementation_defined;
|
||||||
|
#else
|
||||||
|
class writer
|
||||||
|
{
|
||||||
|
value_type const& body_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using const_buffers_type =
|
||||||
|
boost::asio::const_buffer;
|
||||||
|
|
||||||
|
template<bool isRequest, class Fields>
|
||||||
|
explicit
|
||||||
|
writer(message<isRequest,
|
||||||
|
span_body, Fields> const& msg)
|
||||||
|
: body_(msg.body())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init(error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<std::pair<const_buffers_type, bool>>
|
||||||
|
get(error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
return {{
|
||||||
|
{ body_.data(),
|
||||||
|
body_.size() * sizeof(typename
|
||||||
|
value_type::value_type)},
|
||||||
|
false}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
|
@@ -67,7 +67,7 @@ public:
|
|||||||
return body.size();
|
return body.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The algorithm for serializing the body
|
/** The algorithm for parsing the body
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
Meets the requirements of @b BodyReader.
|
||||||
*/
|
*/
|
||||||
@@ -75,52 +75,13 @@ public:
|
|||||||
using reader = implementation_defined;
|
using reader = implementation_defined;
|
||||||
#else
|
#else
|
||||||
class reader
|
class reader
|
||||||
{
|
|
||||||
value_type const& body_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using const_buffers_type =
|
|
||||||
boost::asio::const_buffer;
|
|
||||||
|
|
||||||
template<bool isRequest, class Fields>
|
|
||||||
explicit
|
|
||||||
reader(message<isRequest,
|
|
||||||
basic_string_body, Fields> const& msg)
|
|
||||||
: body_(msg.body())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
init(error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<std::pair<const_buffers_type, bool>>
|
|
||||||
get(error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
return {{const_buffers_type{
|
|
||||||
body_.data(), body_.size()}, false}};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** The algorithm for parsing the body
|
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
|
||||||
*/
|
|
||||||
#if BOOST_BEAST_DOXYGEN
|
|
||||||
using writer = implementation_defined;
|
|
||||||
#else
|
|
||||||
class writer
|
|
||||||
{
|
{
|
||||||
value_type& body_;
|
value_type& body_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
explicit
|
explicit
|
||||||
writer(message<isRequest,
|
reader(message<isRequest,
|
||||||
basic_string_body, Fields>& m)
|
basic_string_body, Fields>& m)
|
||||||
: body_(m.body())
|
: body_(m.body())
|
||||||
{
|
{
|
||||||
@@ -188,6 +149,45 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** The algorithm for serializing the body
|
||||||
|
|
||||||
|
Meets the requirements of @b BodyWriter.
|
||||||
|
*/
|
||||||
|
#if BOOST_BEAST_DOXYGEN
|
||||||
|
using writer = implementation_defined;
|
||||||
|
#else
|
||||||
|
class writer
|
||||||
|
{
|
||||||
|
value_type const& body_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using const_buffers_type =
|
||||||
|
boost::asio::const_buffer;
|
||||||
|
|
||||||
|
template<bool isRequest, class Fields>
|
||||||
|
explicit
|
||||||
|
writer(message<isRequest,
|
||||||
|
basic_string_body, Fields> const& msg)
|
||||||
|
: body_(msg.body())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init(error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<std::pair<const_buffers_type, bool>>
|
||||||
|
get(error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
return {{const_buffers_type{
|
||||||
|
body_.data(), body_.size()}, false}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A @b Body using `std::string`
|
/// A @b Body using `std::string`
|
||||||
|
@@ -57,7 +57,7 @@ using is_body = detail::has_value_type<T>;
|
|||||||
|
|
||||||
@li `T` has a nested type named `reader`
|
@li `T` has a nested type named `reader`
|
||||||
|
|
||||||
@li The nested type meets the requirements of @b BodyReader.
|
@li The nested type meets the requirements of @b BodyWriter.
|
||||||
|
|
||||||
@tparam T The body type to test.
|
@tparam T The body type to test.
|
||||||
|
|
||||||
@@ -65,55 +65,9 @@ using is_body = detail::has_value_type<T>;
|
|||||||
@code
|
@code
|
||||||
template<bool isRequest, class Body, class Fields>
|
template<bool isRequest, class Body, class Fields>
|
||||||
void check_can_serialize(message<isRequest, Body, Fields> const&)
|
void check_can_serialize(message<isRequest, Body, Fields> const&)
|
||||||
{
|
|
||||||
static_assert(is_body_reader<Body>::value,
|
|
||||||
"Cannot serialize Body, no reader");
|
|
||||||
}
|
|
||||||
@endcode
|
|
||||||
*/
|
|
||||||
#if BOOST_BEAST_DOXYGEN
|
|
||||||
template<class T>
|
|
||||||
struct is_body_reader : std::integral_constant<bool, ...> {};
|
|
||||||
#else
|
|
||||||
template<class T, class = void>
|
|
||||||
struct is_body_reader : std::false_type {};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct is_body_reader<T, beast::detail::void_t<
|
|
||||||
typename T::reader,
|
|
||||||
typename T::reader::const_buffers_type,
|
|
||||||
decltype(
|
|
||||||
std::declval<typename T::reader&>().init(std::declval<error_code&>()),
|
|
||||||
std::declval<boost::optional<std::pair<
|
|
||||||
typename T::reader::const_buffers_type, bool>>&>() =
|
|
||||||
std::declval<typename T::reader>().get(std::declval<error_code&>()),
|
|
||||||
(void)0)>> : std::integral_constant<bool,
|
|
||||||
boost::asio::is_const_buffer_sequence<
|
|
||||||
typename T::reader::const_buffers_type>::value &&
|
|
||||||
std::is_constructible<typename T::reader,
|
|
||||||
message<true, T, detail::fields_model>&>::value &&
|
|
||||||
std::is_constructible<typename T::reader,
|
|
||||||
message<false, T, detail::fields_model>&>::value
|
|
||||||
> {};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Determine if a @b Body type has a writer.
|
|
||||||
|
|
||||||
This metafunction is equivalent to `std::true_type` if:
|
|
||||||
|
|
||||||
@li `T` has a nested type named `writer`
|
|
||||||
|
|
||||||
@li The nested type meets the requirements of @b BodyWriter.
|
|
||||||
|
|
||||||
@tparam T The body type to test.
|
|
||||||
|
|
||||||
@par Example
|
|
||||||
@code
|
|
||||||
template<bool isRequest, class Body, class Fields>
|
|
||||||
void check_can_parse(message<isRequest, Body, Fields>&)
|
|
||||||
{
|
{
|
||||||
static_assert(is_body_writer<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"Cannot parse Body, no writer");
|
"Cannot serialize Body, no reader");
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
*/
|
*/
|
||||||
@@ -125,20 +79,66 @@ template<class T, class = void>
|
|||||||
struct is_body_writer : std::false_type {};
|
struct is_body_writer : std::false_type {};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_body_writer<T, beast::detail::void_t<decltype(
|
struct is_body_writer<T, beast::detail::void_t<
|
||||||
std::declval<typename T::writer&>().init(
|
typename T::writer,
|
||||||
|
typename T::writer::const_buffers_type,
|
||||||
|
decltype(
|
||||||
|
std::declval<typename T::writer&>().init(std::declval<error_code&>()),
|
||||||
|
std::declval<boost::optional<std::pair<
|
||||||
|
typename T::writer::const_buffers_type, bool>>&>() =
|
||||||
|
std::declval<typename T::writer>().get(std::declval<error_code&>()),
|
||||||
|
(void)0)>> : std::integral_constant<bool,
|
||||||
|
boost::asio::is_const_buffer_sequence<
|
||||||
|
typename T::writer::const_buffers_type>::value &&
|
||||||
|
std::is_constructible<typename T::writer,
|
||||||
|
message<true, T, detail::fields_model>&>::value &&
|
||||||
|
std::is_constructible<typename T::writer,
|
||||||
|
message<false, T, detail::fields_model>&>::value
|
||||||
|
> {};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Determine if a @b Body type has a reader.
|
||||||
|
|
||||||
|
This metafunction is equivalent to `std::true_type` if:
|
||||||
|
|
||||||
|
@li `T` has a nested type named `reader`
|
||||||
|
|
||||||
|
@li The nested type meets the requirements of @b BodyReader.
|
||||||
|
|
||||||
|
@tparam T The body type to test.
|
||||||
|
|
||||||
|
@par Example
|
||||||
|
@code
|
||||||
|
template<bool isRequest, class Body, class Fields>
|
||||||
|
void check_can_parse(message<isRequest, Body, Fields>&)
|
||||||
|
{
|
||||||
|
static_assert(is_body_reader<Body>::value,
|
||||||
|
"Cannot parse Body, no reader");
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
*/
|
||||||
|
#if BOOST_BEAST_DOXYGEN
|
||||||
|
template<class T>
|
||||||
|
struct is_body_reader : std::integral_constant<bool, ...> {};
|
||||||
|
#else
|
||||||
|
template<class T, class = void>
|
||||||
|
struct is_body_reader : std::false_type {};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct is_body_reader<T, beast::detail::void_t<decltype(
|
||||||
|
std::declval<typename T::reader&>().init(
|
||||||
boost::optional<std::uint64_t>(),
|
boost::optional<std::uint64_t>(),
|
||||||
std::declval<error_code&>()),
|
std::declval<error_code&>()),
|
||||||
std::declval<std::size_t&>() =
|
std::declval<std::size_t&>() =
|
||||||
std::declval<typename T::writer&>().put(
|
std::declval<typename T::reader&>().put(
|
||||||
std::declval<boost::asio::const_buffer>(),
|
std::declval<boost::asio::const_buffer>(),
|
||||||
std::declval<error_code&>()),
|
std::declval<error_code&>()),
|
||||||
std::declval<typename T::writer&>().finish(
|
std::declval<typename T::reader&>().finish(
|
||||||
std::declval<error_code&>()),
|
std::declval<error_code&>()),
|
||||||
(void)0)>> : std::integral_constant<bool,
|
(void)0)>> : std::integral_constant<bool,
|
||||||
std::is_constructible<typename T::writer,
|
std::is_constructible<typename T::reader,
|
||||||
message<true, T, detail::fields_model>&>::value &&
|
message<true, T, detail::fields_model>&>::value &&
|
||||||
std::is_constructible<typename T::writer,
|
std::is_constructible<typename T::reader,
|
||||||
message<false, T, detail::fields_model>&>::value
|
message<false, T, detail::fields_model>&>::value
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
|
@@ -62,7 +62,7 @@ public:
|
|||||||
return body.size();
|
return body.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The algorithm for serializing the body
|
/** The algorithm for parsing the body
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
Meets the requirements of @b BodyReader.
|
||||||
*/
|
*/
|
||||||
@@ -70,52 +70,13 @@ public:
|
|||||||
using reader = implementation_defined;
|
using reader = implementation_defined;
|
||||||
#else
|
#else
|
||||||
class reader
|
class reader
|
||||||
{
|
|
||||||
value_type const& body_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using const_buffers_type =
|
|
||||||
boost::asio::const_buffer;
|
|
||||||
|
|
||||||
template<bool isRequest, class Fields>
|
|
||||||
explicit
|
|
||||||
reader(message<isRequest,
|
|
||||||
vector_body, Fields> const& msg)
|
|
||||||
: body_(msg.body())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
init(error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<std::pair<const_buffers_type, bool>>
|
|
||||||
get(error_code& ec)
|
|
||||||
{
|
|
||||||
ec.assign(0, ec.category());
|
|
||||||
return {{const_buffers_type{
|
|
||||||
body_.data(), body_.size()}, false}};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** The algorithm for parsing the body
|
|
||||||
|
|
||||||
Meets the requirements of @b BodyReader.
|
|
||||||
*/
|
|
||||||
#if BOOST_BEAST_DOXYGEN
|
|
||||||
using writer = implementation_defined;
|
|
||||||
#else
|
|
||||||
class writer
|
|
||||||
{
|
{
|
||||||
value_type& body_;
|
value_type& body_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
explicit
|
explicit
|
||||||
writer(message<isRequest,
|
reader(message<isRequest,
|
||||||
vector_body, Fields>& m)
|
vector_body, Fields>& m)
|
||||||
: body_(m.body())
|
: body_(m.body())
|
||||||
{
|
{
|
||||||
@@ -177,6 +138,45 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** The algorithm for serializing the body
|
||||||
|
|
||||||
|
Meets the requirements of @b BodyWriter.
|
||||||
|
*/
|
||||||
|
#if BOOST_BEAST_DOXYGEN
|
||||||
|
using writer = implementation_defined;
|
||||||
|
#else
|
||||||
|
class writer
|
||||||
|
{
|
||||||
|
value_type const& body_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using const_buffers_type =
|
||||||
|
boost::asio::const_buffer;
|
||||||
|
|
||||||
|
template<bool isRequest, class Fields>
|
||||||
|
explicit
|
||||||
|
writer(message<isRequest,
|
||||||
|
vector_body, Fields> const& msg)
|
||||||
|
: body_(msg.body())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init(error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<std::pair<const_buffers_type, bool>>
|
||||||
|
get(error_code& ec)
|
||||||
|
{
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
return {{const_buffers_type{
|
||||||
|
body_.data(), body_.size()}, false}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
|
@@ -15,8 +15,8 @@ namespace beast {
|
|||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(is_body<empty_body>::value);
|
BOOST_STATIC_ASSERT(is_body<empty_body>::value);
|
||||||
BOOST_STATIC_ASSERT(is_body_reader<empty_body>::value);
|
|
||||||
BOOST_STATIC_ASSERT(is_body_writer<empty_body>::value);
|
BOOST_STATIC_ASSERT(is_body_writer<empty_body>::value);
|
||||||
|
BOOST_STATIC_ASSERT(is_body_reader<empty_body>::value);
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
} // beast
|
} // beast
|
||||||
|
@@ -24,13 +24,13 @@ public:
|
|||||||
{
|
{
|
||||||
struct value_type{};
|
struct value_type{};
|
||||||
|
|
||||||
struct reader
|
struct writer
|
||||||
{
|
{
|
||||||
using const_buffers_type =
|
using const_buffers_type =
|
||||||
boost::asio::const_buffer;
|
boost::asio::const_buffer;
|
||||||
|
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
reader(message<isRequest, const_body, Fields> const&);
|
writer(message<isRequest, const_body, Fields> const&);
|
||||||
|
|
||||||
void
|
void
|
||||||
init(error_code& ec);
|
init(error_code& ec);
|
||||||
@@ -44,13 +44,13 @@ public:
|
|||||||
{
|
{
|
||||||
struct value_type{};
|
struct value_type{};
|
||||||
|
|
||||||
struct reader
|
struct writer
|
||||||
{
|
{
|
||||||
using const_buffers_type =
|
using const_buffers_type =
|
||||||
boost::asio::const_buffer;
|
boost::asio::const_buffer;
|
||||||
|
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
reader(message<isRequest, mutable_body, Fields>&);
|
writer(message<isRequest, mutable_body, Fields>&);
|
||||||
|
|
||||||
void
|
void
|
||||||
init(error_code& ec);
|
init(error_code& ec);
|
||||||
|
@@ -34,7 +34,7 @@ struct span_body_test
|
|||||||
BEAST_EXPECT(req.body().size() == 3);
|
BEAST_EXPECT(req.body().size() == 3);
|
||||||
BEAST_EXPECT(B::size(req.body()) == 3);
|
BEAST_EXPECT(B::size(req.body()) == 3);
|
||||||
|
|
||||||
B::reader r{req};
|
B::writer r{req};
|
||||||
error_code ec;
|
error_code ec;
|
||||||
r.init(ec);
|
r.init(ec);
|
||||||
BEAST_EXPECTS(! ec, ec.message());
|
BEAST_EXPECTS(! ec, ec.message());
|
||||||
@@ -50,7 +50,7 @@ struct span_body_test
|
|||||||
using B = span_body<char>;
|
using B = span_body<char>;
|
||||||
request<B> req;
|
request<B> req;
|
||||||
req.body() = span<char>{buf, sizeof(buf)};
|
req.body() = span<char>{buf, sizeof(buf)};
|
||||||
B::writer w{req};
|
B::reader w{req};
|
||||||
error_code ec;
|
error_code ec;
|
||||||
w.init(boost::none, ec);
|
w.init(boost::none, ec);
|
||||||
BEAST_EXPECTS(! ec, ec.message());
|
BEAST_EXPECTS(! ec, ec.message());
|
||||||
|
@@ -15,8 +15,8 @@ namespace beast {
|
|||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(is_body<string_body>::value);
|
BOOST_STATIC_ASSERT(is_body<string_body>::value);
|
||||||
BOOST_STATIC_ASSERT(is_body_reader<string_body>::value);
|
|
||||||
BOOST_STATIC_ASSERT(is_body_writer<string_body>::value);
|
BOOST_STATIC_ASSERT(is_body_writer<string_body>::value);
|
||||||
|
BOOST_STATIC_ASSERT(is_body_reader<string_body>::value);
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
} // beast
|
} // beast
|
||||||
|
@@ -17,11 +17,11 @@ namespace boost {
|
|||||||
namespace beast {
|
namespace beast {
|
||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(! is_body_reader<int>::value);
|
BOOST_STATIC_ASSERT(! is_body_writer<int>::value);
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(is_body_reader<empty_body>::value);
|
BOOST_STATIC_ASSERT(is_body_writer<empty_body>::value);
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(! is_body_writer<std::string>::value);
|
BOOST_STATIC_ASSERT(! is_body_reader<std::string>::value);
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@@ -15,8 +15,8 @@ namespace beast {
|
|||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(is_body<vector_body<char>>::value);
|
BOOST_STATIC_ASSERT(is_body<vector_body<char>>::value);
|
||||||
BOOST_STATIC_ASSERT(is_body_reader<vector_body<char>>::value);
|
|
||||||
BOOST_STATIC_ASSERT(is_body_writer<vector_body<char>>::value);
|
BOOST_STATIC_ASSERT(is_body_writer<vector_body<char>>::value);
|
||||||
|
BOOST_STATIC_ASSERT(is_body_reader<vector_body<char>>::value);
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
} // beast
|
} // beast
|
||||||
|
@@ -38,7 +38,7 @@ public:
|
|||||||
{
|
{
|
||||||
using value_type = std::string;
|
using value_type = std::string;
|
||||||
|
|
||||||
class reader
|
class writer
|
||||||
{
|
{
|
||||||
value_type const& body_;
|
value_type const& body_;
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ public:
|
|||||||
|
|
||||||
template<bool isRequest, class Allocator>
|
template<bool isRequest, class Allocator>
|
||||||
explicit
|
explicit
|
||||||
reader(message<isRequest,
|
writer(message<isRequest,
|
||||||
unsized_body, Allocator> const& msg)
|
unsized_body, Allocator> const& msg)
|
||||||
: body_(msg.body())
|
: body_(msg.body())
|
||||||
{
|
{
|
||||||
@@ -82,7 +82,7 @@ public:
|
|||||||
bool mutable read = false;
|
bool mutable read = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class reader
|
class writer
|
||||||
{
|
{
|
||||||
int step_ = 0;
|
int step_ = 0;
|
||||||
value_type const& body_;
|
value_type const& body_;
|
||||||
@@ -93,7 +93,7 @@ public:
|
|||||||
|
|
||||||
template<bool isRequest, class Fields>
|
template<bool isRequest, class Fields>
|
||||||
explicit
|
explicit
|
||||||
reader(message<isRequest,
|
writer(message<isRequest,
|
||||||
test_body, Fields> const& msg)
|
test_body, Fields> const& msg)
|
||||||
: body_(msg.body())
|
: body_(msg.body())
|
||||||
{
|
{
|
||||||
@@ -195,11 +195,11 @@ public:
|
|||||||
|
|
||||||
struct fail_body
|
struct fail_body
|
||||||
{
|
{
|
||||||
class reader;
|
class writer;
|
||||||
|
|
||||||
class value_type
|
class value_type
|
||||||
{
|
{
|
||||||
friend class reader;
|
friend class writer;
|
||||||
|
|
||||||
std::string s_;
|
std::string s_;
|
||||||
test::fail_counter& fc_;
|
test::fail_counter& fc_;
|
||||||
@@ -219,7 +219,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class reader
|
class writer
|
||||||
{
|
{
|
||||||
std::size_t n_ = 0;
|
std::size_t n_ = 0;
|
||||||
value_type const& body_;
|
value_type const& body_;
|
||||||
@@ -230,7 +230,7 @@ public:
|
|||||||
|
|
||||||
template<bool isRequest, class Allocator>
|
template<bool isRequest, class Allocator>
|
||||||
explicit
|
explicit
|
||||||
reader(message<isRequest,
|
writer(message<isRequest,
|
||||||
fail_body, Allocator> const& msg)
|
fail_body, Allocator> const& msg)
|
||||||
: body_(msg.body())
|
: body_(msg.body())
|
||||||
{
|
{
|
||||||
|
@@ -19,8 +19,8 @@ namespace boost {
|
|||||||
namespace beast {
|
namespace beast {
|
||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
class BodyReader;
|
|
||||||
class BodyWriter;
|
class BodyWriter;
|
||||||
|
class BodyReader;
|
||||||
|
|
||||||
//[concept_Body
|
//[concept_Body
|
||||||
|
|
||||||
@@ -29,10 +29,10 @@ struct Body
|
|||||||
// The type of message::body when used
|
// The type of message::body when used
|
||||||
struct value_type;
|
struct value_type;
|
||||||
|
|
||||||
/// The algorithm used for extracting buffers
|
/// The algorithm used during parsing
|
||||||
class reader;
|
class reader;
|
||||||
|
|
||||||
/// The algorithm used for inserting buffers
|
/// The algorithm used during serialization
|
||||||
class writer;
|
class writer;
|
||||||
|
|
||||||
/// Returns the body's payload size
|
/// Returns the body's payload size
|
||||||
@@ -45,27 +45,27 @@ static_assert(is_body<Body>::value, "");
|
|||||||
|
|
||||||
//]
|
//]
|
||||||
|
|
||||||
struct Body_BodyReader {
|
struct Body_BodyWriter {
|
||||||
struct value_type{};
|
struct value_type{};
|
||||||
//[concept_BodyReader
|
//[concept_BodyWriter
|
||||||
|
|
||||||
struct BodyReader
|
struct BodyWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// The type of buffer returned by `get`.
|
/// The type of buffer returned by `get`.
|
||||||
using const_buffers_type = boost::asio::const_buffer;
|
using const_buffers_type = boost::asio::const_buffer;
|
||||||
|
|
||||||
/** Construct the reader.
|
/** Construct the writer.
|
||||||
|
|
||||||
@param msg The message whose body is to be retrieved.
|
@param msg The message whose body is to be serialized.
|
||||||
|
|
||||||
@param ec Set to the error, if any occurred.
|
@param ec Set to the error, if any occurred.
|
||||||
*/
|
*/
|
||||||
template<bool isRequest, class Body, class Fields>
|
template<bool isRequest, class Body, class Fields>
|
||||||
explicit
|
explicit
|
||||||
BodyReader(message<isRequest, Body, Fields> const& msg);
|
BodyWriter(message<isRequest, Body, Fields> const& msg);
|
||||||
|
|
||||||
/** Initialize the reader
|
/** Initialize the writer.
|
||||||
|
|
||||||
This is called after construction and before the first
|
This is called after construction and before the first
|
||||||
call to `get`. The message is valid and complete upon
|
call to `get`. The message is valid and complete upon
|
||||||
@@ -109,26 +109,26 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//]
|
//]
|
||||||
using reader = BodyReader;
|
using writer = BodyWriter;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(is_body_reader<Body_BodyReader>::value, "");
|
static_assert(is_body_writer<Body_BodyWriter>::value, "");
|
||||||
|
|
||||||
struct Body_BodyWriter {
|
struct Body_BodyReader {
|
||||||
struct value_type{};
|
struct value_type{};
|
||||||
//[concept_BodyWriter
|
//[concept_BodyReader
|
||||||
|
|
||||||
struct BodyWriter
|
struct BodyReader
|
||||||
{
|
{
|
||||||
/** Construct the writer.
|
/** Construct the reader.
|
||||||
|
|
||||||
@param msg The message whose body is to be stored.
|
@param msg The message whose body is to be parsed.
|
||||||
*/
|
*/
|
||||||
template<bool isRequest, class Body, class Fields>
|
template<bool isRequest, class Body, class Fields>
|
||||||
explicit
|
explicit
|
||||||
BodyWriter(message<isRequest, Body, Fields>& msg);
|
BodyReader(message<isRequest, Body, Fields>& msg);
|
||||||
|
|
||||||
/** Initialize the writer
|
/** Initialize the reader.
|
||||||
|
|
||||||
This is called after construction and before the first
|
This is called after construction and before the first
|
||||||
call to `put`. The message is valid and complete upon
|
call to `put`. The message is valid and complete upon
|
||||||
@@ -180,10 +180,10 @@ struct BodyWriter
|
|||||||
};
|
};
|
||||||
|
|
||||||
//]
|
//]
|
||||||
using writer = BodyWriter;
|
using reader = BodyReader;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(is_body_writer<Body_BodyWriter>::value, "");
|
static_assert(is_body_reader<Body_BodyReader>::value, "");
|
||||||
|
|
||||||
//[concept_Fields
|
//[concept_Fields
|
||||||
|
|
||||||
|
@@ -299,7 +299,7 @@ void fxx() {
|
|||||||
the @b SyncWriteStream concept.
|
the @b SyncWriteStream concept.
|
||||||
|
|
||||||
@param m The message to send. The Body type must support
|
@param m The message to send. The Body type must support
|
||||||
the @b BodyReader concept.
|
the @b BodyWriter concept.
|
||||||
*/
|
*/
|
||||||
template<
|
template<
|
||||||
class SyncWriteStream,
|
class SyncWriteStream,
|
||||||
@@ -312,8 +312,8 @@ send(
|
|||||||
// Check the template types
|
// Check the template types
|
||||||
static_assert(is_sync_write_stream<SyncWriteStream>::value,
|
static_assert(is_sync_write_stream<SyncWriteStream>::value,
|
||||||
"SyncWriteStream requirements not met");
|
"SyncWriteStream requirements not met");
|
||||||
static_assert(is_body_reader<Body>::value,
|
static_assert(is_body_writer<Body>::value,
|
||||||
"BodyReader requirements not met");
|
"BodyWriter requirements not met");
|
||||||
|
|
||||||
// Create the instance of serializer for the message
|
// Create the instance of serializer for the message
|
||||||
serializer<isRequest, Body, Fields> sr{m};
|
serializer<isRequest, Body, Fields> sr{m};
|
||||||
|
Reference in New Issue
Block a user