Files
boost_beast/doc/concept/BodyReader.qbk
T
2017-07-20 08:12:17 -07:00

195 lines
6.4 KiB
Plaintext

[/
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]
[section:BodyReader BodyReader requirements]
A [*BodyReader] provides an online algorithm to obtain a sequence of zero
or more buffers from a body during serialization. The implementation creates
an instance of this type when needed, and calls into it one or more times to
retrieve buffers holding body octets. The interface of [*BodyReader] is
intended to obtain buffers for these scenarios:
* A body that does not entirely fit in memory.
* A body produced incrementally from coroutine output.
* A body represented by zero or more buffers already in memory.
* A body whose size is not known ahead of time.
* Body data generated dynamically from other threads.
* Body data computed algorithmically.
In this table:
* `X` denotes a type meeting the requirements of [*BodyReader].
* `B` denotes a __Body__ where
`std::is_same<X, B::reader>::value == true`.
* `a` denotes a value of type `X`.
* `m` denotes a value of type `message const&` where
`std::is_same<decltype(m.body), Body::value_type>:value == true`.
* `ec` is a value of type [link beast.ref.error_code `error_code&`].
* `R<T>` is the type `boost::optional<std::pair<T, bool>>`.
[table BodyReader requirements
[[expression] [type] [semantics, pre/post-conditions]]
[
[`X::const_buffers_type`]
[]
[
A type which meets the requirements of __ConstBufferSequence__.
This is the type of buffer returned by `X::get`.
]
]
[
[`X::is_deferred`]
[]
[
The type `std::true_type` if the serialization implementation
should only attempt to retrieve buffers from the reader after
the header has been serialized. Otherwise, if this type is
`std::false_type` the implementation will activate an
optimization: the first buffer produced during serialization
will contain both the header and some or all of this body.
Implementations of [*BodyReader] for which initialization is
expensive, should use `std::false_type` here, to reduce the
latency experienced by the remote host when expecting to read
the HTTP header.
]
]
[
[`X(m);`]
[]
[
Constructible from `m`. The lifetime of `m` is guaranteed
to end no earlier than after the `X` is destroyed.
]
]
[
[`a.init(ec)`]
[]
[
Called immediately after construction. If the function sets an
error code in `ec`, the serialization is aborted and the error
is propagated to the caller.
]
]
[
[`a.content_length()`]
[`std::uint64_t`]
[
If this member is present, it is called after initialization
and before calls to provide buffers. The serialized message will
have the Content-Length field set to the value returned from
this function. If this member is absent, the serialized message
body will be chunk-encoded for HTTP versions 1.1 and later, else
the serialized message body will be sent unmodified, with the
error `boost::asio::error::eof` returned to the caller, to notify
they should close the connection to indicate the end of the message.
This function must be `noexcept`.
]
]
[
[`a.get(ec)`]
[`R<X::const_buffers_type>`]
[
Called repeatedly after `init` succeeds. This function returns
`boost::none` if all buffers representing the body have been
returned in previous calls or if it sets `ec` to indicate an
error. Otherwise, if there are buffers remaining the function
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.
]
]
[
[`is_body_reader<B>`]
[`std::true_type`]
[
An alias for `std::true_type` for `B`, otherwise an alias
for `std::false_type`.
]
]
]
[note
Definitions for required [*BodyReader] member functions should
be declared inline so the generated code can become part of the
implementation.
]
Exemplar:
```
struct reader
{
public:
/** Controls when the implementation requests buffers.
If false, the implementation will request the first buffer
immediately and try to serialize both the header and some
or all of the body in a single buffer.
*/
using is_deferred = std::false_type;
/// The type of buffer returned by `get`.
using const_buffers_type = boost::asio::const_buffers_1;
/** Construct the reader.
@param msg The message whose body is to be retrieved.
*/
template<bool isRequest, class Body, class Headers>
explicit
reader(message<isRequest, Body, Headers> const& msg);
/** Initialization.
Called once immediately after construction.
@param ec Set to the error, if any occurred.
*/
void
init(error_code& ec);
/** Returns the content length.
If this member is present, the implementation will set the
Content-Length field accordingly. If absent, the implementation
will use chunk-encoding or terminate the connection to indicate
the end of the message.
*/
std::uint64_t
content_length();
/** Returns the next buffer in the body.
@li If the return value is `boost::none` (unseated optional) and
`ec` does not contain an error, this indicates the end of the
body, no more buffers are present.
@li If the optional contains a value, the first element of the
pair represents a @b ConstBufferSequence containing one or
more octets of the body data. The second element indicates
whether or not there are additional octets of body data.
A value of `true` means there is more data, and that the
implementation will perform a subsequent call to `get`.
A value of `false` means there is no more body data.
@li If `ec` contains an error code, the return value is ignored.
*/
boost::optional<std::pair<const_buffers_type, bool>>
get(error_code& ec);
};
```
[endsect]