forked from boostorg/beast
151 lines
5.0 KiB
Plaintext
151 lines
5.0 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 Serializer Stream Operations]
|
|
|
|
Non-trivial algorithms need to do more than send entire messages
|
|
at once, such as:
|
|
|
|
* Send the header first, and the body later.
|
|
|
|
* Set chunk extensions or trailers using a chunk decorator.
|
|
|
|
* Send a message incrementally: bounded work in each I/O cycle.
|
|
|
|
* Use a series of caller-provided buffers to represent the body.
|
|
|
|
These tasks may be performed by using the serializer stream interfaces.
|
|
To use these interfaces, first construct a suitable object with
|
|
the message to be sent:
|
|
|
|
[table Serializer
|
|
[[Name][Description]]
|
|
[[
|
|
__serializer__
|
|
][
|
|
```
|
|
/// Provides buffer oriented HTTP message serialization functionality.
|
|
template<
|
|
bool isRequest,
|
|
class Body,
|
|
class Fields = fields,
|
|
class ChunkDecorator = no_chunk_decorator
|
|
>
|
|
class serializer;
|
|
```
|
|
]]
|
|
[[
|
|
[link beast.ref.beast__http__request_serializer `request_serializer`]
|
|
][
|
|
```
|
|
/// A serializer for HTTP/1 requests
|
|
template<
|
|
class Body,
|
|
class Fields = fields,
|
|
class ChunkDecorator = no_chunk_decorator>
|
|
using request_serializer = serializer<true, Body, Fields, ChunkDecorator>;
|
|
```
|
|
]]
|
|
[[
|
|
[link beast.ref.beast__http__response_serializer `response_serializer`]
|
|
][
|
|
```
|
|
/// A serializer for HTTP/1 responses
|
|
template<
|
|
class Body,
|
|
class Fields = fields,
|
|
class ChunkDecorator = no_chunk_decorator>
|
|
using response_serializer = serializer<false, Body, Fields, ChunkDecorator>;
|
|
```
|
|
]]
|
|
]
|
|
|
|
The choices for template types must match the message passed on construction.
|
|
This code creates an HTTP response and the corresponding serializer:
|
|
|
|
[http_snippet_10]
|
|
|
|
The stream operations which work on serializers are:
|
|
|
|
[table Serializer Stream Operations
|
|
[[Name][Description]]
|
|
[[
|
|
[link beast.ref.beast__http__write.overload1 [*write]]
|
|
][
|
|
Send everything in a __serializer__ to a __SyncWriteStream__.
|
|
]]
|
|
[[
|
|
[link beast.ref.beast__http__async_write.overload1 [*async_write]]
|
|
][
|
|
Send everything in a __serializer__ asynchronously to an __AsyncWriteStream__.
|
|
]]
|
|
[[
|
|
[link beast.ref.beast__http__write_header.overload1 [*write_header]]
|
|
][
|
|
Send only the header from a __serializer__ to a __SyncWriteStream__.
|
|
]]
|
|
[[
|
|
[link beast.ref.beast__http__async_write_header [*async_write_header]]
|
|
][
|
|
Send only the header from a __serializer__ asynchronously to an __AsyncWriteStream__.
|
|
]]
|
|
[[
|
|
[link beast.ref.beast__http__write_some.overload1 [*write_some]]
|
|
][
|
|
Send part of a __serializer__ to a __SyncWriteStream__.
|
|
]]
|
|
[[
|
|
[link beast.ref.beast__http__async_write_some [*async_write_some]]
|
|
][
|
|
Send part of a __serializer__ asynchronously to an __AsyncWriteStream__.
|
|
]]
|
|
]
|
|
|
|
Here is an example of using a serializer to send a message on a stream
|
|
synchronously. This performs the same operation as calling `write(stream, m)`:
|
|
|
|
[http_snippet_12]
|
|
|
|
[heading Chunk Decorators]
|
|
|
|
When the message used to construct the serializer indicates the chunked
|
|
transfer encoding, the serializer will automatically generate the proper
|
|
encoding in the output buffers. __rfc7230__ defines additional fields
|
|
called the
|
|
[@https://tools.ietf.org/html/rfc7230#section-4.1.1 chunk extensions]
|
|
in chunks with body octets, and the
|
|
[@https://tools.ietf.org/html/rfc7230#section-4.1.2 chunked trailer part]
|
|
for the final chunk. Applications that wish to emit chunk extensions
|
|
and trailers may instantiate the serializer with a "chunk decorator" type,
|
|
and pass an instance of the type upon construction. This decorator is
|
|
a function object which, when invoked with a __ConstBufferSequence__,
|
|
returns a
|
|
[link beast.ref.beast__string_view `string_view`] containing either the extensions
|
|
or the trailer. For chunks containing body data, the passed buffer will
|
|
contain one or more corresponding body octets. The decorator may use this
|
|
information as needed. For example, to compute a digest on the data and
|
|
store it as a chunk extension. For the trailers, the serializer will
|
|
invoke the decorator with a buffer sequence of size zero. Or more
|
|
specifically, with an object of type
|
|
[@http://www.boost.org/doc/html/boost_asio/reference/null_buffers.html `boost::asio::null_buffers`].
|
|
|
|
For body chunks the string returned by the decorator must follow the
|
|
[@https://tools.ietf.org/html/rfc7230#section-4.1.1 correct syntax]
|
|
for the entire chunk extension. For the trailer, the returned string
|
|
should consist of zero or more lines ending in a CRLF and containing
|
|
a field name/value pair in the format prescribed by __rfc7230__. It
|
|
is the responsibility of the decorator to manage returned string buffers.
|
|
The implementation guarantees it will not reference previous strings
|
|
after subsequent calls.
|
|
|
|
This defines a decorator which sets an extension variable `x` equal
|
|
to the size of the chunk in bytes, and returns a single trailer field:
|
|
|
|
[http_snippet_17]
|
|
|
|
[endsect]
|