forked from boostorg/beast
108 lines
3.8 KiB
Plaintext
108 lines
3.8 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:streams Message Stream Operations]
|
|
|
|
Beast provides synchronous and asynchronous algorithms to serialize and
|
|
parse HTTP/1 wire format messages on streams. These functions form a
|
|
basic interface for operating on entire messages:
|
|
|
|
[table Basic Interface
|
|
[[Name][Description]]
|
|
[[
|
|
[link beast.ref.http__read.overload3 [*read]]
|
|
][
|
|
Read a __message__ from a __SyncReadStream__.
|
|
]]
|
|
[[
|
|
[link beast.ref.http__async_read.overload2 [*async_read]]
|
|
][
|
|
Read a __message__ from an __AsyncReadStream__.
|
|
]]
|
|
[[
|
|
[link beast.ref.http__write.overload1 [*write]]
|
|
][
|
|
Write a __message__ to a __SyncWriteStream__.
|
|
]]
|
|
[[
|
|
[link beast.ref.http__async_write [*async_write]]
|
|
][
|
|
Write a __message__ to an __AsyncWriteStream__.
|
|
]]
|
|
]
|
|
|
|
All synchronous stream operations come in two varieties. One which throws
|
|
an exception upon error, and another which accepts as the last parameter an
|
|
argument of type [link beast.ref.error_code `error_code&`]. If an error
|
|
occurs this argument will be set to contain the error code.
|
|
|
|
|
|
|
|
[heading Reading]
|
|
|
|
Because a serialized header is not length-prefixed, algorithms which
|
|
parse messages from a stream may read past the end of a message for
|
|
efficiency. To hold this surplus data, all stream read operations use
|
|
a passed-in __DynamicBuffer__ which must be persisted between calls.
|
|
Each read operation may consume bytes remaining in the buffer, and
|
|
leave behind new bytes. In this example we declare the buffer and a
|
|
message variable, then read a complete HTTP request synchronously:
|
|
|
|
[http_snippet_4]
|
|
|
|
In this example we used the __flat_buffer__. The parser in Beast is
|
|
optimized for structured HTTP data located in a single contiguous memory
|
|
buffer ("flat buffer"). Any dynamic buffer will work with reads. However,
|
|
when not using a flat buffer the implementation may perform an additional
|
|
memory allocation to restructure the input into a single buffer.
|
|
|
|
[tip
|
|
User-defined implementations of __DynamicBuffer__ may avoid additional
|
|
parser memory allocation, if those implementations guarantee that
|
|
returned buffer sequences will always have length one.
|
|
]
|
|
|
|
Messages may also be read asynchronously. When performing asynchronous
|
|
stream read operations, the buffer and message variables must remain
|
|
valid until the operation has completed. Beast asynchronous initiation
|
|
functions use Asio's completion handler model. Here we read a message
|
|
asynchronously. When the operation completes the message in the error
|
|
code indicating the result is printed:
|
|
|
|
[http_snippet_5]
|
|
|
|
If a read stream algorithm cannot complete its operation without exceeding
|
|
the maximum specified size of the dynamic buffer provided, the error
|
|
[link beast.ref.http__error `buffer_overflow`]
|
|
is returned. This may be used to impose a limit on the maximum size of an
|
|
HTTP message header for protection from buffer overflow attacks. The following
|
|
code will generate an error:
|
|
|
|
[http_snippet_6]
|
|
|
|
|
|
|
|
[heading Writing]
|
|
|
|
A set of free functions allow serialization of an entire HTTP message to
|
|
a stream. If a response has no declared content length, and no chunked
|
|
transfer encoding, the end of the message is indicated by the server closing
|
|
the connection. When sending such a response, Beast will return the
|
|
[link beast.ref.http__error `error::end_of_stream`]
|
|
from the write algorithm to indicate
|
|
to the caller that the connection should be closed. This example
|
|
constructs and sends a response whose body length is determined by
|
|
the number of octets received prior to the server closing the connection:
|
|
|
|
[http_snippet_7]
|
|
|
|
The asynchronous version could be used instead:
|
|
|
|
[http_snippet_8]
|
|
|
|
[endsect]
|