Files
boost_beast/doc/concept/Reader.qbk
T
Vinnie Falco 3664329ea7 Refactor HTTP serialization (API Change):
A new class `serializer` is introduced to permit incremental
serialization of HTTP messages. Existing free functions are
re-implemented in terms of this new class.

* The BodyReader concept is refined to support a greater variety
of strategies for providing buffers representing the body to
the serialization algorithms.

* Added buffer_body, a new model of Body which allows the caller
to provide a series of owned buffers using their own serialization
loop.

* Added empty_body, a model of Body which is for serialization only,
to represent HTTP messages with no content body.

* Removed overloads of write and async_write which send only
the HTTP header.

* Removed public interfaces for performing low-level chunk encoding.
2017-07-20 08:12:17 -07:00

211 lines
6.6 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:Reader Reader requirements]
Parsers provided by the implementation will construct the corresponding
`reader` object during parsing. This customization point allows the
Body to determine the strategy for storing incoming message body data.
Readers come in two flavors, direct and indirect:
Direct readers provide a buffer to callers, in which body data is placed.
This type of reader is used when the bytes corresponding to the body data
are stored without transformation. The parse algorithm performs stream or
socket reads directly into the reader-provided buffer, hence the name
"direct." This model avoids an unnecessary buffer copy. An example of
a [*Body] type with a direct reader is
[link beast.ref.http__string_body `string_body`].
Indirect readers are passed body data in a buffer managed by the parser
algorithm. This reader is appropriate when the body data is transformed
or not otherwised stored verbatim. Some examples of when an indirect
reader is appropriate:
* When bytes corresponding to the body are written to a file
as they are parsed.
* The content of the message is JSON, which is parsed as it is
being read in, and stored in a structured, hierarchical format.
In the tables below:
* `X` denotes a type meeting the requirements of [*`Reader`].
* `a` denotes a value of type `X`.
* `n` is a value convertible to `std::size_t` without loss of precision.
* `v` is a value convertible to `std::uint64_t` without loss of precision.
* `s` is a value of type `boost::string_ref`.
* `ec` is a value of type [link beast.ref.error_code `error_code&`].
* `m` denotes a value of type `message&` where
`std::is_same<decltype(m.body), Body::value_type>::value == true`.
[table Direct Reader requirements
[[operation] [type] [semantics, pre/post-conditions]]
[
[`X::is_direct`]
[`bool`]
[
This static constant must be set to `true` to indicate that
the reader is a direct reader.
]
]
[
[`X::mutable_buffers_type`]
[]
[
This member type must be present, and meet the requirements
of [*MutableBufferSequence]. It represents the type of
the writable buffers returned by the reader, in which
bytes representing the body are stored by the implementation.
]
]
[
[`X a{m};`]
[]
[
`a` is constructible from `m`. The lifetime of `m` is guaranteed
to end no earlier than after `a` is destroyed. The constructor
will be called after all headers have been stored in `m`, and
just before parsing bytes corresponding to the body for messages
whose semantics indicate that a body is present with non-zero
length.
]
]
[
[`a.init()`]
[]
[
This function is called once before any bytes corresponding
to the body are presented to the reader, for messages whose
body is determined by the end-of-file marker on a stream,
or for messages where the chunked Transfer-Encoding is
specified.
]
]
[
[`a.init(v)`]
[]
[
This function is called once before any bytes corresponding
to the body are presented to the reader, for messages where
the Content-Length is specified. The value of `v` will be
set to the number of bytes indicated by the content length.
]
]
[
[`a.prepare(n)`]
[`mutable_buffers_type`]
[
The implementation calls this function to obtain a mutable
buffer sequence of up to `n` bytes in size in which to place
data corresponding to the body. The buffer returned must
be at least one byte in size, and may be smaller than `n`.
]
]
[
[`a.commit(n)`]
[]
[
The implementation calls this function to indicate to the
reader that `n` bytes of data have been successfully placed
into the buffer obtained through a prior call to `prepare`.
The value of `n` will be less than or equal to the size of
the buffer returned in the previous call to `prepare`.
]
]
[
[`a.finish()`]
[]
[
This function is called after all the bytes corresponding
to the body have been written to the buffers and committed.
]
]
]
[table Indirect Reader requirements
[[operation] [type] [semantics, pre/post-conditions]]
[
[`X::is_direct`]
[`bool`]
[
This static constant must be set to `false` to indicate that
the reader is an indirect reader.
]
]
[
[`X a{m};`]
[]
[
`a` is constructible from `m`. The lifetime of `m` is guaranteed
to end no earlier than after `a` is destroyed. The constructor
will be called after all headers have been stored in `m`, and
just before parsing bytes corresponding to the body for messages
whose semantics indicate that a body is present with non-zero
length.
]
]
[
[`a.init(ec)`]
[]
[
This function is called once before any bytes corresponding
to the body are presented to the reader, for messages whose
body is determined by the end-of-file market on a stream,
or for messages where the chunked Transfer-Encoding is
specified.
If `ec` is set before returning, parsing will stop
and the error will be returned to the caller.
]
]
[
[`a.init(v,ec)`]
[]
[
This function is called once before any bytes corresponding
to the body are presented to the reader, for messages where
the Content-Length is specified. The value of `v` will be
set to the number of bytes indicated by the content length.
If `ec` is set before returning, parsing will stop
and the error will be returned to the caller.
]
]
[
[`a.write(s,ec)`]
[]
[
The implementation calls this function with `s` containing
bytes corresponding to the body, after removing any present
chunked encoding transformation.
If `ec` is set before returning, parsing will stop
and the error will be returned to the caller.
]
]
[
[`a.finish(ec)`]
[]
[
This function is called after all the bytes corresponding
to the body have been written to the buffers and committed.
If `ec` is set before returning, parsing will stop
and the error will be returned to the caller.
]
]
]
[note
Definitions for required `Reader` member functions should be declared
inline so the generated code can become part of the implementation.
]
[endsect]