Files
boost_beast/doc/qbk/04_http/08_chunked_encoding.qbk

148 lines
5.3 KiB
Plaintext
Raw Normal View History

Refactor chunked-encoding serialization: New buffer sequence classes are provided to allow full control over the serialization of chunk-encoded message payloads: * chunk_header A ConstBufferSequence representing the chunk header. It includes a hexadecimal-encoded size, an optional set of chunk extensions, and the trailing CRLF required to denote the end of the chunk header. This allows the caller to manually serialize the chunk body in one or more calls to a stream output function. The caller must also output an object of type `chunk_crlf` to the stream to indicate the end of the chunk body. * chunk_crlf A small ConstBufferSequence that simply represents the two character sequence "\r\n" (CRLF). This is needed for the case where the caller wants to output a chunk body as a series of buffers (i.e. "chunking a chunk"). * chunk_body A ConstBufferSequence representing a complete chunk. This includes the size, an optional set of chunk extensions, a caller provided buffer containing the body, and the required CRLF that follows. * chunk_final A ConstBufferSequence representing a final chunk. It includes an optional set of caller-provided field trailers * chunk_extensions A container for building a set of chunk extensions to use during serialization. The use of the container is optional, callers may provide their own buffer containing a correctly formatted set of chunk extensions, or they may use their own convenience container which meets the requirements. The basic_fields container is modified to allow construction outside the context of a message. The container can be used to provide trailers to `chunk_final`. Actions Required: * Remove references to ChunkDecorators. Use the new chunk-encoding buffer sequences to manually produce a chunked payload body in the case where control over the chunk-extensions and/or trailers is required.
2017-07-09 20:09:30 -07:00
[/
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 Chunked Encoding]
For message payloads whose size is not known ahead of time, HTTP
version 1.1 defines the
[@https://tools.ietf.org/html/rfc7230#section-4.1 ['chunked]]
transfer coding. This coding consists of zero or more
[@https://tools.ietf.org/html/rfc7230#section-4.1 ['chunked bodies]],
followed by a
[@https://tools.ietf.org/html/rfc7230#section-4.1 ['last chunk]].
Each chunked body may contain optional application-defined, connection-specific
[@https://tools.ietf.org/html/rfc7230#section-4.1.1 ['chunk-extensions]].
The last chunk may contain additional HTTP field values in a section
of the last chunk called a
[@https://tools.ietf.org/html/rfc7230#section-4.1.2 ['chunk-trailer]].
The field values are "promised" in the header as a comma delimited list
of field names in the
[@https://tools.ietf.org/html/rfc7230#section-4.4 [*Trailer]]
field value. Clients indicate their willingness to accept trailers
by including the "trailers" token in the
[@https://tools.ietf.org/html/rfc7230#section-4.3 [*TE]]
field value.
[heading Serializing Chunks]
The __serializer__ automatically applies the chunked tranfer encoding
when a message returns `true` from
[link beast.ref.beast__http__message.chunked.overload1 `message::chunked`].
The boundaries between chunks emitted by the serializer are implementation
defined. Chunk extensions and trailers are omitted. Applications which
need precise control over the chunk boundaries, extensions, and trailers
may use a set of helper classes which enable manual emission of message
payloads using chunk encoding.
To use these helper classes, first serialize the header portion of the
message using the standard interface. Then prepare the buffers, chunk
extensions, and desired trailers, and use them with these helpers:
[table Chunking Helpers
[[Name][Description]]
[
[[link beast.ref.beast__http__chunk_body `chunk_body`]]
[
A buffer sequence representing a complete chunk body.
]
][
[[link beast.ref.beast__http__chunk_crlf `chunk_crlf`]]
[
A buffer sequence representing the CRLF (`"\r\n"`) delimiter.
This class is used when the caller desires to emit the
chunk body in two or more individual stream operations.
]
][
[
[link beast.ref.beast__http__chunk_extensions `chunk_extensions`]
[link beast.ref.beast__http__basic_chunk_extensions `basic_chunk_extensions`]
]
[
This is a simple, allocating container which lets callers
easily build up a set of chunk extensions.
]
][
[[link beast.ref.beast__http__chunk_header `chunk_header`]]
[
A buffer sequence representing a hex-encoded chunk size,
followed by an optional set of chunk extensions, including
the terminating CRLF (`"\r\n"`) delimiter which precedes
the chunk body. This class is used when the caller desires
to emit the chunk body in two or more individual stream
operations.
]
][
[[link beast.ref.beast__http__chunk_last `chunk_last`]]
[
A buffer sequence representing a last chunk. The last chunk
indicates the end of the chunked message payload, and may
contain optional trailer fields.
]
][
[
[link beast.ref.beast__http__make_chunk `make_chunk`]
[link beast.ref.beast__http__make_chunk_last `make_chunk_last`]
]
[
These helper functions are used to construct a chunk
or last chunk directly at call sites.
]
]]
We demonstrate the use of these objects first by declaring a function
which returns the next buffer sequence to use as a chunk body:
[http_snippet_17]
This example demonstrates sending a complete chunked message payload
manually. No chunk extensions or trailers are emitted:
[http_snippet_18]
The following code sends additional chunks, and sets chunk extensions
using the helper container. The container automatically quotes values
in the serialized output when necessary:
[http_snippet_19]
Callers can take over the generation and management of the extensions
buffer by passing a non-owning string. Note that this requires the
string contents to adhere to the correct syntax for chunk extensions,
including the needed double quotes for values which contain spaces:
[http_snippet_20]
The next code sample emits a chunked response which promises two
trailer fields and delivers them in the last chunk. The implementation
allocates memory using the default or a passed-in allocator to hold
the state information required to serialize the trailer:
[http_snippet_21]
Using a custom allocator to serialize the last chunk:
[http_snippet_22]
Alternatively, callers can take over the generation and lifetime
management of the serialized trailer fields by passing in a non-owning
string:
[http_snippet_23]
For the ultimate level of control, a caller can manually compose the
chunk itself by first emitting a header with the correct chunk body
size, and then by emitting the chunk body in multiple calls to the
stream write function. In this case the caller is responsible for
also emitting the terminating CRLF (`"\r\n"`):
[http_snippet_24]
[endsect]