Refactor docs

This commit is contained in:
Vinnie Falco
2019-02-23 21:00:58 -08:00
parent 50be985254
commit d9400ce618
64 changed files with 1357 additions and 383 deletions

View File

@@ -0,0 +1,45 @@
[/
Copyright (c) 2016-2019 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)
Official repository: https://github.com/boostorg/beast
]
[section Quick Look]
[/block'''<?dbhtml stop-chunking?>''']
These complete programs are intended to quickly impress upon readers
the flavor of the library. Source code and build scripts for them are
located in the [source_file example] directory.
[section:http_client Simple HTTP Client __example__]
Use HTTP to make a GET request to a website and print the response:
File: [source_file example/http/client/sync/http_client_sync.cpp]
[example_http_client]
[endsect]
[section:websocket_client Simple WebSocket Client __example__]
Establish a WebSocket connection, send a message and receive the reply:
File: [source_file example/websocket/client/sync/websocket_client_sync.cpp]
[example_websocket_client]
[endsect]
[include 1a_bishop_fox.qbk]
[include 1b_autobahn.qbk]
[endsect]

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -7,12 +7,7 @@
Official repository: https://github.com/boostorg/beast
]
[section Reports]
[block'''<?dbhtml stop-chunking?>''']
[section Security Review (Bishop Fox)]
[section:security_review_bishop_fox Security Review (Bishop Fox) __video__]
Since 2005, [@https://www.bishopfox.com/ Bishop Fox] has provided
security consulting services to the Fortune 1000, high-tech startups,
@@ -35,36 +30,14 @@ manual exploitation and review of these issues to validate the findings.
[@https://vinniefalco.github.io/BeastAssets/Beast%20-%20Hybrid%20Application%20Assessment%202017%20-%20Assessment%20Report%20-%2020171114.pdf [*Beast - Hybrid Application Assessment 2017]]
[block'''
[/ "Securing Boost.Beast: A Non-Traditional Source Code Review"]
'''
<mediaobject>
<videoobject>
<videodata fileref="https://www.youtube.com/embed/4TtyYbGDAj0?rel=0"
align="center" contentwidth="560" contentdepth="315"/>
align="center" contentwidth="560" contentdepth="315"/>
</videoobject>
</mediaobject>
''']
[endsect]
[section WebSocket (Autobahn|Testsuite)]
The
[@https://github.com/crossbario/autobahn-testsuite Autobahn WebSockets Testsuite]
provides a fully automated test suite to
verify client and server implementations of The WebSocket Protocol
for specification conformance and implementation robustness.
The test suite will check an implementation by doing basic
WebSocket conversations, extensive protocol compliance
verification and performance and limits testing.
Autobahn|Testsuite is used across the industry and
contains over 500 test cases.
[@https://vinniefalco.github.io/BeastAssets/reports/autobahn/index.html [*Autobahn|Testsuite WebSocket Results]]
[endsect]
'''
[endsect]

View File

@@ -0,0 +1,25 @@
[/
Copyright (c) 2016-2019 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)
Official repository: https://github.com/boostorg/beast
]
[section:websocket_autobahn_testsuite WebSocket (Autobahn|Testsuite)]
The
[@https://github.com/crossbario/autobahn-testsuite Autobahn WebSockets Testsuite]
provides a fully automated test suite to
verify client and server implementations of The WebSocket Protocol
for specification conformance and implementation robustness.
The test suite will check an implementation by doing basic
WebSocket conversations, extensive protocol compliance
verification and performance and limits testing.
Autobahn|Testsuite is used across the industry and
contains over 500 test cases.
[@https://vinniefalco.github.io/BeastAssets/reports/autobahn/index.html [*Autobahn|Testsuite WebSocket Results]]
[endsect]

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -58,7 +58,7 @@ Beast requires:
* [*C++11:] Robust support for most language features.
* [*Boost:] Beast only works with Boost, not stand-alone Asio
* [*OpenSSL:] Optional, for using TLS/Secure sockets.
* [*OpenSSL:] Required to build the tests, examples, and to use TLS/Secure sockets.
Tested with these compilers: msvc-14+, gcc 4.8.4+, clang 3.6+.
@@ -99,7 +99,7 @@ prefer to keep your issue or question confidential please email the author at
[heading Credits]
[section Credits]
Boost.Asio is the inspiration behind which all of the interfaces and
implementation strategies are built. Some parts of the documentation are
@@ -137,4 +137,6 @@ for his generous participation and source code contributions.
[include 1_reports.qbk]
[endsect]
[include 1_quick_look.qbk]

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -7,46 +7,13 @@
Official repository: https://github.com/boostorg/beast
]
[section Quick Start]
[block'''<?dbhtml stop-chunking?>''']
These complete programs are intended to quickly impress upon readers
the flavor of the library. Source code and build scripts for them are
located in the [source_file example] directory.
[section HTTP Client]
Use HTTP to make a GET request to a website and print the response:
File: [source_file example/http/client/sync/http_client_sync.cpp]
[example_http_client]
[endsect]
[section WebSocket Client]
Establish a WebSocket connection, send a message and receive the reply:
File: [source_file example/websocket/client/sync/websocket_client_sync.cpp]
[example_websocket_client]
[endsect]
[endsect]
[section Examples]
[block'''<?dbhtml stop-chunking?>''']
Source code and build scripts for these programs are located
in the [source_file example] directory.
[template example_src[path name] '''<ulink url="../../'''[path]'''">'''[name]'''</ulink>''']
[/-----------------------------------------------------------------------------]
[section Clients]
@@ -97,7 +64,7 @@ before disconnecting. All asynchronous clients support timeouts.
[endsect]
[/-----------------------------------------------------------------------------]
[section Servers]
@@ -166,7 +133,7 @@ support timeouts.
[endsect]
[/-----------------------------------------------------------------------------]
[section Servers (Advanced)]
@@ -211,93 +178,56 @@ and illustrate the implementation of advanced features.
[endsect]
[/-----------------------------------------------------------------------------]
[section:chat_server Chat Server __video__ __new__]
[section CppCon 2018]
This example demonstrates a websocket chat server, allowing multiple
users to connect and participate in live, group messaging. It comes
with a tiny front end implemented in JavaScript and HTML5 which runs
in any browser. The example is accompanied by a one hour presentation
which provides a discussion of networking concepts, followed by in-depth
explanation of how the client and server are constructed. This talk
was delivered at [@https://cppcon.org CppCon 2018]. The source code
in the Beast example contains improvements to the original program.
This talk was given at [@https://cppcon.org CppCon 2018]. In this
presentation, we develop a multi-user chat server written in C++ using
Beast WebSocket, which uses a provided chat client written in HTML and
JavaScript. An improved, multi-threaded version of this program is
included here
[source_file example/websocket/server/chat-multi].
[table Chat WebSocket Server and JavaScript Client
[[Component] [Features] [Sources]]
[
[Server]
[[itemized_list
[C++]
[Timeouts]
[Multi-threaded]
[Broadcast to multiple peers]
[Dual protocols: HTTP and WebSocket]
[Clean exit via SIGINT (CTRL+C) or SIGTERM (kill)]
]]
[[source_file example/websocket/server/chat-multi]]
][
[Client]
[[itemized_list
[JavaScript / HTML5]
[Runs in the browser]
[Delivered by the server]
[Only 60 lines total including UI]
[Completely portable graphics]
]]
[[source_file example/websocket/server/chat-multi/chat_client.html]]
]]
[block'''
[/ "Get rich quick! Using Boost.Beast WebSockets and Networking TS"]
'''
<mediaobject>
<videoobject>
<videodata fileref="https://www.youtube.com/embed/7FQwAjELMek"
align="center" contentwidth="560" contentdepth="315"/>
</videoobject>
</mediaobject>
''']
'''
[endsect]
[section Common Files]
Some of the examples use one or more shared header files, they are
listed here along with a description of their use:
[table
[[Source File] [Description]]
[
[[source_file example/common/detect_ssl.hpp]]
[
This contains the detect SSL algorithm including the
synchronous and asynchronous initiating functions, described
in the documentation. It is used by the "flex" servers which
support both plain and SSL sessions on the same port.
]
][
[[source_file example/common/root_certificates.hpp]]
[
This contains the root SSL certificates used in the SSL client
examples. These certificates are used to verify the signatures
of SSL certificates presented by remote servers. They represent
a subset of the public keys usually installed as part of the
operating system or browser, so they may not identify every
possible server.
]
][
[[source_file example/common/server_certificate.hpp]]
[
This file contains a self-signed SSL certificate used by the
SSL server examples. It has not been validated by a Certificate
Authority ("CA") so connecting to an example HTTP server using
a browser may generate security warnings.
]
]]
[endsect]
[section Documentation Samples]
Here are all of the example functions and classes presented
throughout the documentation, they can be included and used
in your program without modification
* [source_file example/doc/http_examples.hpp]
[endsect]
[section Composed Operations]
This program shows how to use Beast's network foundations to build a
composable asynchronous initiation function with associated composed
operation implementation. This is a complete, runnable version of
the example described in
[link beast.using_io.writing_composed_operations.echo Writing Composed Operations: Echo].
* [source_file example/echo-op/echo_op.cpp]
[endsect]
[/-----------------------------------------------------------------------------]
[endsect]

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -7,7 +7,7 @@
Official repository: https://github.com/boostorg/beast
]
[section:asio_refresher Refresher]
[section:asio_refresher Refresher __new__]
To use Beast effectively, a prior understanding of Networking is required.
This section reviews these concepts as a reminder and guide for further
@@ -22,7 +22,11 @@ Data may be reliably transferred across a connection in both directions
([@https://en.wikipedia.org/wiki/Duplex_(telecommunications) ['full-duplex]])
with bytes arriving in the same order they were sent. These connections, along
with the objects and types used to represent them, are collectively termed
[link beast.concepts.streams ['streams]].
[link beast.concepts.streams ['streams]]. The computer or device attached
to the network is called a
[@https://en.wikipedia.org/wiki/Host_(network) ['host]], and the
program on the other end of an established connection is called a
[@https://en.wikipedia.org/wiki/Peer-to-peer ['peer]].
The
[@https://en.wikipedia.org/wiki/Internet ['internet]]
@@ -33,7 +37,13 @@ popular protocol is
which this library relies on exclusively. The protocol takes care of the
low level details so that applications see a
['stream], which is the reliable, full-duplex connection carrying the ordered
set of bytes described above.
set of bytes described above. A
[@https://en.wikipedia.org/wiki/Server_(computing) ['server]]
is a powerful, always-on host at a well-known network name or network address
which provides data services. A
[@https://en.wikipedia.org/wiki/Client_(computing) ['client]]
is a transient peer which connects to a server to exchange data, and goes
offline.
A vendor supplies a program called a
[@https://en.wikipedia.org/wiki/Device_driver ['device driver]],
@@ -121,8 +131,9 @@ Beast provides a well-rounded collection of dynamic buffer types such as
[link beast.ref.boost__beast__flat_buffer `flat_buffer`],
[link beast.ref.boost__beast__multi_buffer `multi_buffer`], and
[link beast.ref.boost__beast__static_buffer `static_buffer`].
In the following function, the contents of a stream are read into a dynamic
buffer until it contains a newline character, using
The following function reads data from a
[link beast.ref.boost__beast__tcp_stream `tcp_stream`]
into a dynamic buffer until it encountering a newline character, using
[@boost:/doc/html/boost_asio/reference/buffers_iterator.html `net::buffers_iterator`]
to treat the contents of the buffer as a range of characters:
@@ -177,9 +188,7 @@ results, which may include the error code and other specific information.
An asynchronous operation is said to be
['completed]
after the completion handler is queued. The code that follows shows how some
text may be written to a
[@boost:/doc/html/boost_asio/reference/ip__tcp/socket.html `net::socket`]
asynchronously, invoking a lambda when the
text may be written to a socket asynchronously, invoking a lambda when the
operation is complete:
[code_core_1_refresher_3s]
@@ -202,7 +211,10 @@ Or these associations may be specified non-intrusively, by specializing
the class templates
[@boost:/doc/html/boost_asio/reference/associated_allocator.html `net::associated_allocator`]
and
[@boost:/doc/html/boost_asio/reference/associated_executor.html `net::associated_executor`].
[@boost:/doc/html/boost_asio/reference/associated_executor.html `net::associated_executor`]:
[code_core_1_refresher_7]
The function
[@boost:/doc/html/boost_asio/reference/bind_executor.html `net::bind_executor`]
may be used when the caller wants to change the executor of a completion
@@ -233,7 +245,7 @@ object meeting the named requirements for asynchronous reading, writing, or
both. This example shows an algorithm which writes some text to an
asynchronous stream:
[code_core_1_refresher_7]
[code_core_1_refresher_8]
[/-----------------------------------------------------------------------------]
@@ -285,42 +297,43 @@ launched with
In both of these cases, an object with a specific type is used in place of
the completion handler, and the return value of the initiating function
is transformed from `void` to `std::future<std::size_t>` or `std::size_t`.
The return type transformation is supported by customization points in the
initiating function signature. Here is the signature for `net::async_write`:
The handler is sometimes called a
[@boost:/doc/html/boost_asio/reference/asynchronous_operations#boost_asio.reference.asynchronous_operations.completion_tokens_and_handlers ['CompletionToken]]
when used in this context. The return type transformation is supported by
customization points in the initiating function signature. Here is the
signature for
[@boost:/doc/html/boost_asio/reference/async_write/overload1.html `net::async_write`]:
[code_core_1_refresher_8]
[code_core_1_refresher_9]
The type of the function's return value is determined by the
[@boost:/doc/html/boost_asio/reference/async_result.html `net::async_result`]
customization point, which comes with specializations for common library
types such as `std::future` and may also be specialized for user-defined
types. The universal model also provides the
[@boost:/doc/html/boost_asio/reference/async_completion.html `net::async_completion`]
customization point for transforming
the `handler` argument (called a
[@boost:/doc/html/boost_asio/reference/asynchronous_operations/completion_token.html ['CompletionToken]]
in this context) into an underlying completion handler to be invoked when the
operation is complete. This transformed, internal handler is responsible for
the finalizing step that delivers the result of the operation to the caller.
For example, when using `net::use_future` the internal handler will deliver
the result by calling `std::promise::set_value` on the promise object
returned by the initiating function.
types. The body of the initiating function calls the
[@boost:/doc/html/boost_asio/reference/async_inititate.html `net::async_initiate`]
helper to capture the arguments and forward them to the specialization of
`async_result`. An additional "initiation function" object is provided which
`async_result` may use to immediately launch the operation, or defer the launch
of the operation until some point in the future (this is called "lazy
execution"). The initiation function object receives the internal completion
handler which matches the signature expected by the initiating function:
[code_core_1_refresher_10]
This transformed, internal handler is responsible for the finalizing step that
delivers the result of the operation to the caller. For example, when using
`net::use_future` the internal handler will deliver the result by calling
[@https://en.cppreference.com/w/cpp/thread/promise/set_value `std::promise::set_value`]
on the promise object returned by the initiating function.
[/-----------------------------------------------------------------------------]
[heading Using Networking]
[warning
Beast does not manage sockets, make outgoing connections,
accept incoming connections, handle timeouts, close endpoints,
do name lookups, deal with TLS certificates, perform authentication,
or otherwise handle any aspect of connection management. This is
left to the interfaces already existing on the underlying streams.
]
Library stream algorithms require a __socket__, __ssl_stream__, or other
__Stream__ object that has already established communication with a remote
peer. This example is provided as a reminder of how to work with
Most library stream algorithms require a __socket__, __ssl_stream__, or
other __Stream__ object that has already established communication with
a remote peer. This example is provided as a reminder of how to work with
sockets:
[snippet_core_2]

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -9,7 +9,7 @@
[section Stream Types]
[section:stream_types Streams]
A __Stream__ is a communication channel where data is reliably transferred as
an ordered sequence of bytes. Streams are either synchronous or asynchronous,

View File

@@ -0,0 +1,217 @@
[/
Copyright (c) 2016-2019 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)
Official repository: https://github.com/boostorg/beast
]
[section:timeouts Timeouts __example__ __new__]
Network programs must handle adverse connection conditions; the most common
is that a connected peer goes offline unexpectedly. Protocols have no way of
identifying this reliably: the peer is offline after all, and unable to send
a message announcing the absence. A peer can go offline for various reasons:
[itemized_list
[The peer experiences a power loss]
[The peer becomes disconnected from the network]
[The local host becomes disconnected from the network]
[The network itself becomes unavailable]
]
To determine when a peer is offline or idle, a program will implement a
[@https://en.wikipedia.org/wiki/Timeout_(computing) timeout]
algorithm, which closes the connection after a specified amount of time if
some condition is met. For example, if no data is received for the duration.
A timeout may be used to:
[itemized_list
[Drop malicious or poorly performing hosts]
[Close idle connections to free up resources]
[Determine if a peer is offline or no longer available]
]
Traditionally, programs use a
[@boost:/doc/html/boost_asio/reference/steady_timer.html `net::steady_timer`]
to determine when a timeout occurs, and then call
[@boost:/doc/html/boost_asio/reference/basic_socket/close/overload2.html `close`]
on the socket to release the resources. The complexity of managing a separate
timer is often a source of
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1269r0.html#timers frustration]
for non-experts.
[note
For portability reasons, networking does not provide timeouts
or cancellation features for synchronous stream operations.
]
To simplify the handling of timeouts, these provided types wrap a
[@boost:/doc/html/boost_asio/reference/basic_stream_socket.html `net::basic_stream_socket`]
to provide additional features:
[table
[[Name][Features]]
[
[[link beast.ref.boost__beast__tcp_stream `tcp_stream`]]
[[itemized_list
[Timeouts for logical operations]
[[@boost:/doc/html/boost_asio/reference/ip__tcp.html `net::ip::tcp`] protocol]
[[@boost:/doc/html/boost_asio/reference/executor.html `net::executor`] executor]
[[link beast.ref.boost__beast__unlimited_rate_policy `unlimited_rate_policy`] rate limits]
]]
][
[[link beast.ref.boost__beast__basic_stream `basic_stream`]]
[[itemized_list
[Timeouts for logical operations]
[Configurable __Protocol__ type]
[Configurable __Executor__ type]
[Configurable __RatePolicy__ type]
]]
]]
[/-----------------------------------------------------------------------------]
[heading Construction]
The `tcp_stream` is designed as a replacement for
[@boost:/doc/html/boost_asio/reference/ip__tcp/socket.html `net::ip::tcp::socket`].
Any program which currently uses a socket, can switch to a `tcp_stream` and achieve
the features above (although some interfaces are different, see below).
Networking now allows I/O objects to construct with any instance of
__ExecutionContext__ or __Executor__ objects. Here we construct a stream which
uses a particular I/O context to dispatch completion handlers:
[code_core_3_timeouts_1]
Alternatively, we can construct the stream from an executor:
[code_core_3_timeouts_2]
The function
[link beast.ref.boost__beast__make_strand `make_strand`] returns a strand
constructed from an execution context or executor. When a
[@boost:/doc/html/boost_asio/reference/strand.html `net::strand`]
is chosen for the stream's executor, all completion handlers which do not
already have an associated executor will use the strand. This is both a
notational convenience (no need for `strand::wrap` or `bind_executor` at
call sites) and a measure of safety, as it is no longer possible to forget
to use the strand.
[code_core_3_timeouts_3]
[/-----------------------------------------------------------------------------]
[heading Connecting]
Before data can be exchanged, the stream needs to be connected to a peer.
The following code sets a timeout for an asynchronous connect operation.
In Beast, functions to connect to a range of endpoints (such as the range
returned by
[@boost:/doc/html/boost_asio/reference/ip__basic_resolver/resolve/overload3.html `net::ip::tcp::resolver::resolve`])
are members of the class rather than free functions such as
[@boost:/doc/html/boost_asio/reference/async_connect.html `net::async_connect`].
[code_core_3_timeouts_4]
A server will use an acceptor bound to a particular IP address and port to
listen to and receive incoming connection requests. The acceptor returns
an ordinary socket. A `tcp_stream` can be move-constructed from the
underlying `basic_stream_socket` thusly:
[code_core_3_timeouts_5]
[/-----------------------------------------------------------------------------]
[heading Reading and Writing]
Timeouts apply to the logical operation, expressed as a series of asynchronous
calls, rather than just the next call. This code reads a line from the stream
and writes it back. Both the read and the write must complete within 30 seconds
from when the timeout was set; the timer is not reset between operations.
[code_core_3_timeouts_6]
Since reads and writes can take place concurrently, it is possible to have
two simultaneous logical operations where each operation either only reads,
or only writes. The beginning of a new read or write operation will use
the most recently set timeout. This will not affect operations that are
already outstanding.
[code_core_3_timeouts_7]
When a timeout is set, it cancels any previous read or write timeout for which
no outstanding operation is in progress. Algorithms which loop over logical
operations simply need to set the timeout once before the logical operation,
it is not necessary to call `expires_never` in this case. Here we implement
an algorithm which continuously echoes lines back, with a timeout. This example
is implemented as a complete function.
[code_core_3_timeouts_1f]
[/-----------------------------------------------------------------------------]
[heading https_get]
It is important to note that all of the examples thus far which perform
reads and writes with a timeout, make use of the existing networking stream
algorithms. As these algorithms are written generically to work with any
object meeting the stream requirements, they transparently support timeouts
when used with `tcp_stream`. This can be used to enable timeouts for stream
wrappers that do not currently support timeouts.
The following code establishes an encrypted connection, writes an HTTP
request, reads the HTTP response, and closes the connection gracefully.
If these operations take longer than 30 seconds total, a timeout occurs.
This code is intended to show how `tcp_stream` can be used to enable
timeouts across unmodified stream algorithms which were not originally
written to support timing out, and how a blocking algorithm may be written
from asynchronous intermediate operations.
[code_core_3_timeouts_2f]
[/-----------------------------------------------------------------------------]
[heading Rate Limiting]
The
[link beast.ref.boost__beast__basic_stream `basic_stream`]
class template supports an additional `RatePolicy` template parameter. Objects
of this type must meet the requirements of __RatePolicy__. They are used to
implement rate limiting or bandwidth management. The default policy for
`basic_stream` and `tcp_stream` is
[link beast.ref.boost__beast__unlimited_rate_policy `unlimited_rate_policy`],
which places no limits on reading and writing. The library comes with the
[link beast.ref.boost__beast__simple_rate_policy `simple_rate_policy`],
allowing for independent control of read and write limits expressed in terms
of bytes per second. The follow code creates an instance of the basic stream
with a simple rate policy, and sets the read and write limits:
[code_core_3_timeouts_8]
More sophisticated rate policies can be implemented as user-defined types which
meet the requirements of __RatePolicy__. Here, we develop a rate policy that
measures the instantaneous throughput of reads and writes. First we write a
small utility class that applies an exponential smoothing function to a series
of discrete rate samples, to calculate instantaneous throughput.
[code_core_3_timeouts_3f]
Then we define our rate policy object. We friend the type
[link beast.ref.boost__beast__rate_policy_access `rate_policy_access`] to
allow our implementation to be private, but still allow the `basic_stream`
access to call the required functions. This lets us avoid having to write
a cumbersome friend declaration for the `basic_stream` class template.
Public members of rate policy objects become part of the stream object's
interface, through a call to `rate_policy`.
[code_core_3_timeouts_4f]
To use our new policy we declare an instance of the stream, and then use it
with stream algorithms as usual. At any time, we can determine the current
read or write rates by calling into the policy.
[code_core_3_timeouts_9]
[endsect]

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -7,7 +7,7 @@
Official repository: https://github.com/boostorg/beast
]
[section Layered Streams]
[section Layered Streams __new__]
Networking's __ssl_stream__ is a class template meeting the requirements
of both synchronous and asynchronous read and write streams, implemented
@@ -17,7 +17,7 @@ layer object internally, while allowing external access through the
observer `net::ssl::stream::next_layer()`. This declares an SSL stream
which uses a regular TCP/IP socket as the next layer:
[code_core_3_layers_1]
[code_core_4_layers_1]
Objects using this design pattern are referred to in networking as "a
stack of stream layers". In Beast we use the term ['layered stream],
@@ -26,13 +26,13 @@ As with the SSL stream, __websocket_stream__ is a class template
parameterized on a next layer object. This declares a websocket
stream which uses a regular TCP/IP socket as the next layer:
[code_core_3_layers_2]
[code_core_4_layers_2]
If a Secure WebSockets stream is desired, this is accomplished simply
by changing the type of the next layer and adjusting the constructor
arguments to match:
[code_core_3_layers_3]
[code_core_4_layers_3]
Higher level abstractions can be developed in this fashion by nesting
stream layers to arbitrary degree. The stack of stream layers effectively
@@ -88,7 +88,7 @@ facilities for authoring and working with layered streams:
puts a layered stream into non-blocking mode by retrieving the
TCP/IP socket in the lowest layer and changing the socket option:
[code_core_3_layers_4]
[code_core_4_layers_4]
]]
[[
[link beast.ref.boost__beast__http__icy_stream `http::icy_stream`]
@@ -114,13 +114,15 @@ facilities for authoring and working with layered streams:
]]
]
[heading Example]
[section Counted Stream __example__ __new__]
This example shows the definition of a layered stream which keeps individual
counts of the total number of bytes read from and written to the next layer.
It meets the requirements for synchronous and asynchronous read and write
streams:
[code_core_3_layers_5]
[code_core_4_layers_5]
[endsect]
[endsect]

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -110,7 +110,7 @@ composed operations:
]]
]
[include 6a_echo.qbk]
[include 6b_detect_ssl.qbk]
[include 7a_echo.qbk]
[include 7b_detect_ssl.qbk]
[endsect]

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -7,7 +7,7 @@
Official repository: https://github.com/boostorg/beast
]
[section:echo Echo]
[section:echo Echo __example__ __new__]
This example develops an initiating function called [*echo].
The operation will read up to the first newline on a stream, and
@@ -17,6 +17,10 @@ initiation function. For our echo operation the only inputs are the
stream and the completion token. The output is the error code which
is usually included in all completion handler signatures.
[tip
The source for for this example is [source_file example/echo-op/echo_op.cpp].
]
[example_core_echo_op_2]
Now that we have a declaration, we will define the body of the function.

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -7,7 +7,7 @@
Official repository: https://github.com/boostorg/beast
]
[section:detect_ssl Detect SSL]
[section:detect_ssl Detect SSL __example__ __new__]
In this example we will build a simple function to detect the presence of the
[@https://tools.ietf.org/html/rfc2246#section-7.4 TLS client handshake]

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -7,7 +7,7 @@
Official repository: https://github.com/boostorg/beast
]
[section:using_io Using Networking]
[section:using_io Networking __new__]
This library uses the
[@http://cplusplus.github.io/networking-ts/draft.pdf Networking Technical Specification],
@@ -75,9 +75,9 @@ namespace is used to qualify Networking identifiers. For Boost.Beast,
`net` will be an alias for the `boost::asio` namespace.
To further ease of use, this library provides an extensive collection
of types and algorithms. This section of the documentation explains these types and algorithms, provides examples
of usage, and also provides refreshers and tutorials for working with
networking.
of types and algorithms. This section of the documentation explains these
types and algorithms, provides examples of usage, and also provides
refreshers and tutorials for working with networking.
[heading Abbreviations]
@@ -91,9 +91,10 @@ effect:
[include 1_refresher.qbk]
[include 2_streams.qbk]
[include 3_layers.qbk]
[include 4_buffers.qbk]
[include 5_files.qbk]
[include 6_composed.qbk]
[include 3_timeouts.qbk]
[include 4__layers.qbk]
[include 5_buffers.qbk]
[include 6_files.qbk]
[include 7_composed.qbk]
[endsect]

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -125,7 +125,7 @@ the response:
[section Incremental Read]
[section:incremental_read Incremental Read __example__]
This function uses
[link beast.ref.boost__beast__http__buffer_body `buffer_body`]

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -58,7 +58,7 @@ C++14 example we print the header first, followed by the body:
[section Write To std::ostream]
[section:write_to_std_ostream Write To std::ostream __example__]
The standard library provides the type `std::ostream` for performing high
level write operations on character streams. The variable `std::cout` is

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -85,7 +85,7 @@ The parser provides a few options which may be set before parsing begins:
[section Read From std::istream]
[section:read_from_std_istream Read From std::istream __example__]
The standard library provides the type `std::istream` for performing high
level read operations on character streams. The variable `std::cin` is based

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -93,7 +93,7 @@ those bodies may be parsed or serialized.
[section File Body]
[section:file_body File Body __example__]
Use of the flexible __Body__ concept customization point enables authors to
preserve the self-contained nature of the __message__ object while allowing

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -15,7 +15,7 @@ a variety of scenarios.
[section Change Body Type]
[section:change_body_type Change Body Type __example__]
Sophisticated servers may wish to defer the choice of the Body template type
until after the header is available. Then, a body type may be chosen
@@ -35,7 +35,7 @@ type depending on the method verb:
[section Expect 100-continue (Client)]
[section:expect_100_continue_client Expect 100-continue (Client) __example__]
The Expect field with the value "100-continue" in a request is special. It
indicates that the after sending the message header, a client desires an
@@ -54,7 +54,7 @@ this client action looks like this:
[section Expect 100-continue (Server)]
[section:expect_100_continue_server Expect 100-continue (Server) __example__]
The Expect field with the value "100-continue" in a request is special. It
indicates that the after sending the message header, a client desires an
@@ -72,7 +72,7 @@ synchronous version of this server action looks like this:
[section HEAD request (Client)]
[section:head_request_client HEAD request (Client) __example__]
The
[@https://tools.ietf.org/html/rfc7231#section-4.3.2 HEAD request]
@@ -90,7 +90,7 @@ with the value `true`, as shown in this example:
[section HEAD response (Server)]
[section:head_response_server HEAD response (Server) __example__]
When a server receives a
[@https://tools.ietf.org/html/rfc7231#section-4.3.2 HEAD request],
@@ -103,7 +103,7 @@ if the method was GET, except that the body is omitted.
[section HTTP Relay]
[section:http_relay HTTP Relay __example__]
An HTTP proxy acts as a relay between client and server. The proxy reads a
request from the client and sends it to the server, possibly adjusting some
@@ -123,7 +123,7 @@ and a __parser__ to achieve its goal:
[section Send Child Process Output]
[section:send_child_process_output Send Child Process Output __example__]
Sometimes it is necessary to send a message whose body is not conveniently
described by a single container. For example, when implementing an HTTP relay

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -7,7 +7,7 @@
Official repository: https://github.com/boostorg/beast
]
[section:decorator Custom HTTP Fields]
[section:decorator Custom HTTP Fields __new__]
For programs which need to modify either the outgoing WebSocket HTTP Upgrade
request, the outgoing WebSocket HTTP Upgrade response, or both, the stream

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -7,7 +7,7 @@
Official repository: https://github.com/boostorg/beast
]
[section:RatePolicy RatePolicy]
[section:RatePolicy RatePolicy __new__]
An instance of [*RatePolicy] is associated with a
[link beast.ref.boost__beast__basic_stream `basic_stream`],

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -57,6 +57,7 @@ The following video presentation was delivered at
in 2016. It provides a light introduction to some of the earliest
interfaces of Beast (which have since changed).
[/ "Introducing Beast..."]
[block'''
<mediaobject>
<videoobject>

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -9,7 +9,7 @@
<iframe width="560" height="315" src="https://www.youtube.com/embed/WsUnnYEKPnI?rel=0" frameborder="0" allowfullscreen></iframe>
]
[section HTTP Message Container]
[section:http_message_container HTTP Message Container __video__]
The following video presentation was delivered at
[@https://cppcon.org/ CppCon]
@@ -18,6 +18,7 @@ process for the HTTP message container used in Beast. The slides and code
used are available in the
[@https://github.com/vinniefalco/CppCon2017 GitHub repository].
[/ "Make Classes Great Again! (Using Concepts for Customization Points)"]
[block'''
<mediaobject>
<videoobject>

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "../../../../tools/boostbook/dtd/boostbook.dtd">
<!--
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -30,6 +30,8 @@
[template include_file[path][^<'''<ulink url="../../../../'''[path]'''">'''[path]'''</ulink>'''>]]
[template issue[n] '''<ulink url="https://github.com/boostorg/beast/issues/'''[n]'''">#'''[n]'''</ulink>''']
[template example_src[path name] '''<ulink url="../../'''[path]'''">'''[name]'''</ulink>''']
[def __N3747__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf [*N3747]]]
[def __NetTS__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4771.pdf Networking TS]]
[def __rfc6455__ [@https://tools.ietf.org/html/rfc6455 rfc6455]]
@@ -90,6 +92,7 @@
[def __Fields__ [link beast.concepts.Fields ['Fields]]]
[def __FieldsWriter__ [link beast.concepts.FieldsWriter ['FieldsWriter]]]
[def __File__ [link beast.concepts.File ['File]]]
[def __RatePolicy__ [link beast.concepts.RatePolicy ['RatePolicy]]]
[def __Stream__ [link beast.concepts.streams ['Stream]]]
[def __SyncStream__ [link beast.concepts.streams.SyncStream ['SyncStream]]]
@@ -111,6 +114,14 @@
[def __flat_static_buffer_base__ [link beast.ref.boost__beast__flat_static_buffer_base `flat_static_buffer_base`]]
[def __websocket_stream__ [link beast.ref.boost__beast__websocket__stream `websocket::stream`]]
[/ Dingbat Legend]
[def __new__ [role green \u2605]]
[def __example__ \U0001f4a1]
[def __video__ \U0001f3a6]
[def __report__ \U0001f4cb]
[def __star__ \u2b50]
[/
VFALCO unfortunately quickbook wants relative paths and we have no
variables so all of the .cpp and .hpp files are placed here to keep
@@ -130,17 +141,24 @@
[import ../../test/doc/websocket_snippets.cpp]
[import ../../test/doc/core_1_refresher.cpp]
[import ../../test/doc/core_3_layers.cpp]
[import ../../test/doc/core_3_timeouts.cpp]
[import ../../test/doc/core_4_layers.cpp]
[import ../../test/doc/http_10_custom_parser.cpp]
[import ../../test/doc/websocket_3_handshake.cpp]
[import ../../include/boost/beast/core/detect_ssl.hpp]
[import ../../test/beast/core/rate_policy.cpp]
[section:quickref Reference]
'''
<emphasis role="green">&#128946;</emphasis> indicates an item that is new in this version.
'''
__new__ indicates a new or updated section in this version.
__example__ contains example source code.
__video__ contains video presentation content
[section:quickref Reference __new__]
__new__ indicates an item that is new in this version.
[xinclude quickref.xml]
[endsect]
[block'''<reference id="beast_hidden"><title>This Page Intentionally Left Blank 1/2</title>''']
@@ -151,9 +169,9 @@
[include release_notes.qbk]
[include 01_intro/0_intro.qbk]
[include 02_examples/0_examples.qbk]
[include 03_core/0_core.qbk]
[include 01_intro/_intro.qbk]
[include 02_examples/_examples.qbk]
[include 03_core/_core.qbk]
[include 04_http/0_http.qbk]
[include 05_http_examples/0_http_examples.qbk]
[include 06_websocket/0_websocket.qbk]

View File

@@ -2,7 +2,7 @@
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "../../../../tools/boostbook/dtd/boostbook.dtd">
<!--
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -23,8 +23,8 @@
<entry valign="top">
<bridgehead renderas="sect3">Classes&nbsp;<emphasis role="normal">(1 of 2)</emphasis></bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__async_op_base">async_op_base</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__basic_stream">basic_stream</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__async_op_base">async_op_base</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__basic_stream">basic_stream</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__file">file</link></member>
<member><link linkend="beast.ref.boost__beast__file_mode">file_mode</link></member>
<member><link linkend="beast.ref.boost__beast__file_posix">file_posix</link></member>
@@ -33,56 +33,55 @@
<member><link linkend="beast.ref.boost__beast__flat_buffer">flat_buffer</link></member>
<member><link linkend="beast.ref.boost__beast__flat_static_buffer">flat_static_buffer</link></member>
<member><link linkend="beast.ref.boost__beast__flat_static_buffer_base">flat_static_buffer_base</link></member>
<member><link linkend="beast.ref.boost__beast__flat_stream">flat_stream</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__flat_stream">flat_stream</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__handler_ptr">handler_ptr</link></member>
<member><link linkend="beast.ref.boost__beast__iequal">iequal</link></member>
<member><link linkend="beast.ref.boost__beast__iless">iless</link></member>
<member><link linkend="beast.ref.boost__beast__rate_policy_access">rate_policy_access</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__saved_handler">saved_handler</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__rate_policy_access">rate_policy_access</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Classes&nbsp;<emphasis role="normal">(2 of 2)</emphasis></bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__saved_handler">saved_handler</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__span">span</link></member>
<member><link linkend="beast.ref.boost__beast__simple_rate_policy">simple_rate_policy</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__ssl_stream">ssl_stream</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__simple_rate_policy">simple_rate_policy</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__static_string">static_string</link></member>
<member><link linkend="beast.ref.boost__beast__stable_async_op_base">stable_async_op_base</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__stable_async_op_base">stable_async_op_base</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__string_param">string_param</link></member>
<member><link linkend="beast.ref.boost__beast__string_view">string_view</link></member>
<member><link linkend="beast.ref.boost__beast__tcp_stream">tcp_stream</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__unlimited_rate_policy">unlimited_rate_policy</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__tcp_stream">tcp_stream</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__unlimited_rate_policy">unlimited_rate_policy</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
</simplelist>
<bridgehead renderas="sect3">Constants</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__condition">condition</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__error">error</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__condition">condition</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__error">error</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__file_mode">file_mode</link></member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Functions</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__allocate_stable">allocate_stable</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__async_detect_ssl">async_detect_ssl</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__beast_close_socket">beast_close_socket</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__bind_front_handler">bind_front_handler</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__allocate_stable">allocate_stable</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__async_detect_ssl">async_detect_ssl</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__beast_close_socket">beast_close_socket</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__bind_front_handler">bind_front_handler</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__bind_handler">bind_handler</link></member>
<member><link linkend="beast.ref.boost__beast__close_socket">close_socket</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__detect_ssl">detect_ssl</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__close_socket">close_socket</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__detect_ssl">detect_ssl</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__generic_category">generic_category</link></member>
<member><link linkend="beast.ref.boost__beast__get_lowest_layer">get_lowest_layer</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__get_lowest_layer">get_lowest_layer</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__iequals">iequals</link></member>
<member><link linkend="beast.ref.boost__beast__make_strand">make_strand</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__make_strand">make_strand</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__to_static_string">to_static_string</link></member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Type Traits</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__executor_type">executor_type</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__lowest_layer_type">lowest_layer_type</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__executor_type">executor_type</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__lowest_layer_type">lowest_layer_type</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__has_get_executor">has_get_executor</link></member>
<member><link linkend="beast.ref.boost__beast__is_async_read_stream">is_async_read_stream</link></member>
<member><link linkend="beast.ref.boost__beast__is_async_write_stream">is_async_write_stream</link></member>
@@ -92,6 +91,10 @@
<member><link linkend="beast.ref.boost__beast__is_sync_stream">is_sync_stream</link></member>
<member><link linkend="beast.ref.boost__beast__is_sync_write_stream">is_sync_write_stream</link></member>
</simplelist>
<bridgehead renderas="sect3">SSL</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__ssl_stream">ssl_stream</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Aliases</bridgehead>
@@ -107,7 +110,7 @@
<simplelist type="vert" columns="1">
<member><link linkend="beast.concepts.streams.AsyncStream">AsyncStream</link></member>
<member><link linkend="beast.concepts.File">File</link></member>
<member><link linkend="beast.concepts.RatePolicy">RatePolicy</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.concepts.RatePolicy">RatePolicy</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.concepts.streams.Stream">Stream</link></member>
<member><link linkend="beast.concepts.streams.SyncStream">SyncStream</link></member>
</simplelist>
@@ -133,7 +136,7 @@
<member><link linkend="beast.ref.boost__beast__buffers_cat_view">buffers_cat_view</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_prefix_view">buffers_prefix_view</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_suffix">buffers_suffix</link></member>
<member><link linkend="beast.ref.boost__beast__dynamic_buffer_ref_wrapper">dynamic_buffer_ref_wrapper</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__dynamic_buffer_ref_wrapper">dynamic_buffer_ref_wrapper</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__multi_buffer">multi_buffer</link></member>
<member><link linkend="beast.ref.boost__beast__static_buffer">static_buffer</link></member>
<member><link linkend="beast.ref.boost__beast__static_buffer_base">static_buffer_base</link></member>
@@ -141,15 +144,15 @@
</entry><entry valign="top">
<bridgehead renderas="sect3">Functions</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__buffer_size">buffer_size</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__buffer_size">buffer_size</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__buffers_cat">buffers_cat</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_front">buffers_front</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_prefix">buffers_prefix</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_range">buffers_range</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__buffers_range_ref">buffers_range_ref</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__buffers_range">buffers_range</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__buffers_range_ref">buffers_range_ref</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__buffers_to_string">buffers_to_string</link></member>
<member><link linkend="beast.ref.boost__beast__dynamic_buffer_ref">dynamic_buffer_ref</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__make_printable">make_printable</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__dynamic_buffer_ref">dynamic_buffer_ref</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__make_printable">make_printable</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__ostream">ostream</link></member>
<member><link linkend="beast.ref.boost__beast__read_size">read_size</link></member>
<member><link linkend="beast.ref.boost__beast__read_size_or_throw">read_size_or_throw</link></member>
@@ -157,10 +160,10 @@
</entry><entry valign="top">
<bridgehead renderas="sect3">Type Traits</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__buffers_type">buffers_type</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__buffers_iterator_type">buffers_iterator_type</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__is_const_buffer_sequence">is_const_buffer_sequence</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__is_mutable_buffer_sequence">is_mutable_buffer_sequence</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__buffers_type">buffers_type</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__buffers_iterator_type">buffers_iterator_type</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__is_const_buffer_sequence">is_const_buffer_sequence</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__is_mutable_buffer_sequence">is_mutable_buffer_sequence</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
</simplelist>
</entry><entry valign="top">
<bridgehead renderas="sect3">Concepts</bridgehead>
@@ -299,8 +302,9 @@
<bridgehead renderas="sect3">Options</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__websocket__permessage_deflate">permessage_deflate</link></member>
<member><link linkend="beast.ref.boost__beast__websocket__stream_base.suggested_settings">suggested_settings</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__websocket__stream_base__timeout">timeout</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__websocket__stream_base.suggested_settings">suggested_settings</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__websocket__stream_base__decorator">decorator</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__websocket__stream_base__timeout">timeout</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
</simplelist>
<bridgehead renderas="sect3">Constants</bridgehead>
<simplelist type="vert" columns="1">
@@ -365,7 +369,7 @@
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__http__icy_stream">http::icy_stream</link></member>
<member><link linkend="beast.ref.boost__beast__test__fail_count">test::fail_count</link></member>
<member><link linkend="beast.ref.boost__beast__test__handler">test::handler</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__test__handler">test::handler</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__test__stream">test::stream</link></member>
</simplelist>
</entry>
@@ -373,9 +377,9 @@
<bridgehead renderas="sect3">Functions</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__test__connect">test::connect</link></member>
<member><link linkend="beast.ref.boost__beast__test__any_handler">test::any_handler</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__test__fail_handler">test::fail_handler</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__test__success_handler">test::success_handler</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__test__any_handler">test::any_handler</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__test__fail_handler">test::fail_handler</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
<member><link linkend="beast.ref.boost__beast__test__success_handler">test::success_handler</link>&nbsp;<emphasis role="green">&#9733;</emphasis></member>
</simplelist>
</entry>
<entry valign="top">

View File

@@ -1,5 +1,5 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Copyright (c) 2016-2019 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)
@@ -11,32 +11,20 @@
[/-----------------------------------------------------------------------------]
[/
* [phrase library..[@/libs/beast/ Beast]:]
[*YUUUGE Update!] The
[link beast.quickref [*reference]] shows a star
'''
<emphasis role="green">&#128946;</emphasis>
'''
next to each new item.
* [role red [*Beast needs your help!]]
[role red [*BIG Update!]] The
[link beast.quickref [*reference]] shows a star [role green \u2605] next to each new item.
* [*Beast needs your help!]
* [@https://github.com/boostorg/beast/wiki/Companies-and-Individuals-Using-Beast [*Tell Us]]
how you or your company use Beast.
* Please
[@https://github.com/boostorg/beast/issues/new report]
any bugs, feature requests, or general feedback.
* Don't forget to
'''
&#11088;&#11088;&#11088;
'''
[@https://github.com/boostorg/beast [*star the repository]]
'''
&#11088;&#11088;&#11088;
'''
!
* Chat with us at the [*#beast] and [*#boost] channels in the
[@https://cppalliance.org/slack/ [*C++ Slack Workspace]].
* Don't forget to \u2b50 \u2b50 \u2b50
[@https://github.com/boostorg/beast [*star the repository]]
\u2b50 \u2b50 \u2b50 !
* [role green [*More tutorials]], code like the pros!
* [link beast.using_io.asio_refresher Networking Refresher] teaches you from the ground up.
* Updated [link beast.using_io.writing_composed_operations.echo Asynchronous Echo] example
@@ -68,16 +56,11 @@
* All asynchronous operations use Asio's
[@boost:/doc/html/boost_asio/reference/async_initiate.html `async_initiate`]
for efficient integration with Coroutines TS.
* '''
&#9889;
'''
[*['faster compilation]], define `BOOST_BEAST_SPLIT_COMPILATION` and include
* \u26a1 [*['faster compilation]], define `BOOST_BEAST_SPLIT_COMPILATION` and include
[@../../include/boost/beast/src.hpp src.hpp] in one of your .cpp files!
* See the full [link beast.release_notes [*Release Notes]] for a complete list
of changes.
]
[/-----------------------------------------------------------------------------]
[heading Boost 1.70]

View File

@@ -42,19 +42,22 @@ template<typename> class stream;
namespace boost {
namespace beast {
/** A stream socket wrapper with timeouts, bandwidth limits, and associated executor.
/** A stream socket wrapper with timeouts, an executor, and a rate limit policy.
This stream wraps a `net::basic_stream_socket` to provide
the following features:
@li Optional timeouts may be specified for each logical asynchronous
operation performing any reading, writing, or connecting.
@li An <em>Executor</em> may be associated with the stream, which will
be used to invoke any completion handlers which do not already have
an associated executor. This achieves support for
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html">[P1322R0] Networking TS enhancement to enable custom I/O executors</a>.
@li Timeouts may be specified for each logical asynchronous operation
performing any reading, writing, or connecting.
@li A <em>RatePolicy</em> may be associated with the stream, to implement
rate limiting through the policy's interface.
Although the stream supports multiple concurrent outstanding asynchronous
operations, the stream object is not thread-safe. The caller is responsible
for ensuring that the stream is accessed from only one thread at a time.

View File

@@ -91,14 +91,13 @@ private:
/** A rate policy with unlimited throughput.
This rate policy places no restrictions on read and write
bandwidth utilization.
This rate policy object does not apply any rate limit.
@par Concepts
@li <em>RatePolicy</em>
@see @ref beast::basic_stream
@see beast::basic_stream, beast::tcp_stream
*/
class unlimited_rate_policy
{
@@ -137,7 +136,7 @@ class unlimited_rate_policy
//------------------------------------------------------------------------------
/** A rate policy with simple, configurable limits on read and write throughput.
/** A rate policy with simple, configurable limits on reads and writes.
This rate policy allows for simple individual limits on the amount
of bytes per second allowed for reads and writes.

View File

@@ -12,17 +12,21 @@
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/basic_stream.hpp>
#include <boost/beast/core/rate_policy.hpp>
#include <boost/asio/executor.hpp>
#include <boost/asio/ip/tcp.hpp>
namespace boost {
namespace beast {
/** A TCP/IP stream socket with timeouts, rate limits, and polymorphic executor.
/** A TCP/IP stream socket with timeouts and a polymorphic executor.
@see basic_stream
*/
using tcp_stream = basic_stream<net::ip::tcp, net::executor>;
using tcp_stream = basic_stream<
net::ip::tcp,
net::executor,
unlimited_rate_policy>;
} // beast
} // boost

View File

@@ -21,7 +21,8 @@ add_executable (tests-doc
snippets.ipp
core_snippets.cpp
core_1_refresher.cpp
core_3_layers.cpp
core_3_timeouts.cpp
core_4_layers.cpp
http_10_custom_parser.cpp
http_examples.cpp
http_snippets.cpp

View File

@@ -20,7 +20,8 @@ alias run-tests :
[ compile http_snippets.cpp ]
[ compile websocket_snippets.cpp ]
[ run core_1_refresher.cpp $(TEST_MAIN) ]
[ run core_3_layers.cpp $(TEST_MAIN) ]
[ run core_3_timeouts.cpp $(TEST_MAIN) ]
[ run core_4_layers.cpp $(TEST_MAIN) ]
[ run http_10_custom_parser.cpp $(TEST_MAIN) ]
[ run http_examples.cpp $(TEST_MAIN) ]
[ run websocket_3_handshake.cpp $(TEST_MAIN) ]
@@ -29,7 +30,8 @@ alias run-tests :
exe fat-tests :
$(TEST_MAIN)
core_1_refresher.cpp
core_3_layers.cpp
core_3_timeouts.cpp
core_4_layers.cpp
http_10_custom_parser.cpp
http_examples.cpp
websocket_3_handshake.cpp

View File

@@ -84,6 +84,8 @@ snippets()
}
}
//------------------------------------------------------------------------------
//[code_core_1_refresher_1
template <class ConstBufferSequence>
std::string string_from_buffers (ConstBufferSequence const& buffers)
@@ -111,6 +113,8 @@ std::string string_from_buffers (ConstBufferSequence const& buffers)
}
//]
//------------------------------------------------------------------------------
//[code_core_1_refresher_2
// Read a line ending in '\n' from a socket, returning
// the number of characters up to but not including the newline
@@ -144,9 +148,10 @@ std::size_t read_line(net::ip::tcp::socket& sock, DynamicBuffer& buffer)
buffer.commit(sock.read_some(buffer.prepare(bytes_to_read)));
}
}
//]
//------------------------------------------------------------------------------
//[code_core_1_refresher_3
// Meets the requirements of SyncReadStream
struct sync_read_stream
@@ -172,6 +177,7 @@ struct sync_write_stream
std::size_t write_some(ConstBufferSequence const& buffers, error_code& ec);
};
//]
template<class MutableBufferSequence>
std::size_t sync_read_stream::read_some(MutableBufferSequence const&)
{
@@ -195,6 +201,8 @@ std::size_t sync_write_stream::write_some(ConstBufferSequence const&, error_code
BOOST_STATIC_ASSERT(is_sync_read_stream<sync_read_stream>::value);
BOOST_STATIC_ASSERT(is_sync_write_stream<sync_write_stream>::value);
//------------------------------------------------------------------------------
//[code_core_1_refresher_4
template <class SyncWriteStream>
void hello (SyncWriteStream& stream)
@@ -209,6 +217,8 @@ void hello (SyncWriteStream& stream)
}
//]
//------------------------------------------------------------------------------
//[code_core_1_refresher_5
template <class SyncWriteStream>
void hello (SyncWriteStream& stream, error_code& ec)
@@ -223,17 +233,25 @@ void hello (SyncWriteStream& stream, error_code& ec)
}
//]
//------------------------------------------------------------------------------
} // (anon)
} // beast
} // boost
//[code_core_1_refresher_6
// Intrusively specify an associated allocator and executor
// The following is a completion handler expressed
// as a function object, with a nested associated
// allocator and a nested associated executor.
struct handler
{
using allocator_type = std::allocator<char>;
allocator_type get_allocator() const noexcept;
using executor_type = net::io_context::executor_type;
using executor_type = boost::asio::io_context::executor_type;
executor_type get_executor() const noexcept;
void operator()(error_code, std::size_t);
void operator()(boost::beast::error_code, std::size_t);
};
//]
inline auto handler::get_allocator() const noexcept ->
@@ -244,14 +262,69 @@ inline auto handler::get_allocator() const noexcept ->
inline auto handler::get_executor() const noexcept ->
executor_type
{
static net::io_context ioc;
static boost::asio::io_context ioc;
return ioc.get_executor();
}
inline void handler::operator()(error_code, std::size_t)
inline void handler::operator()(
boost::beast::error_code, std::size_t)
{
}
//[code_core_1_refresher_7
namespace boost {
namespace asio {
template<class Allocator>
struct associated_allocator<handler, Allocator>
{
using type = std::allocator<void>;
static
type
get(handler const& h,
Allocator const& alloc = Allocator{}) noexcept;
};
template<class Executor>
struct associated_executor<handler, Executor>
{
using type = boost::asio::executor;
static
type
get(handler const& h,
Executor const& ex = Executor{}) noexcept;
};
} // boost
} // asio
//]
template<class Allocator>
auto
boost::asio::associated_allocator<handler, Allocator>::
get(handler const&, Allocator const&) noexcept -> type
{
return {};
}
template<class Executor>
auto
boost::asio::associated_executor<handler, Executor>::
get(handler const&, Executor const&) noexcept -> type
{
return {};
}
//------------------------------------------------------------------------------
namespace boost {
namespace beast {
namespace {
//------------------------------------------------------------------------------
//[code_core_1_refresher_8
template <class AsyncWriteStream, class WriteHandler>
void async_hello (AsyncWriteStream& stream, WriteHandler&& handler)
{
@@ -261,33 +334,60 @@ void async_hello (AsyncWriteStream& stream, WriteHandler&& handler)
}
//]
//[code_core_1_refresher_8
//------------------------------------------------------------------------------
//[code_core_1_refresher_9
template<
class AsyncWriteStream,
class ConstBufferSequence,
class WriteHandler>
class CompletionToken>
auto
async_write(
AsyncWriteStream& stream,
ConstBufferSequence const& buffers,
WriteHandler&& handler) ->
typename net::async_result< // return-type customization point
typename std::decay<WriteHandler>::type, // type used to specialize async_result
void(error_code, std::size_t) // signature of the corresponding completion handler
CompletionToken&& token) // a handler, or a special object.
->
typename net::async_result< // return-type customization point.
typename std::decay<CompletionToken>::type, // type used to specialize async_result.
void(error_code, std::size_t) // underlying completion handler signature.
>::return_type;
//]
struct run_async_write
{
template<class... Args>
void
operator()(Args&&...)
{
}
};
template<
class AsyncWriteStream,
class ConstBufferSequence,
class CompletionToken>
auto
async_write(
AsyncWriteStream& stream,
ConstBufferSequence const& buffers,
CompletionToken&& token) ->
typename net::async_result<
typename std::decay<CompletionToken>::type,
void(error_code, std::size_t)
>::return_type
{
net::async_completion<
WriteHandler, // completion handler customization point
void(error_code, std::size_t) // signature of the corresponding completion handler
> init(handler); // variable which holds the corresponding completion handler
//[code_core_1_refresher_10
return net::async_initiate<
CompletionToken,
void(error_code, std::size_t)>(
run_async_write{}, // the "initiation" object.
token, // must be first.
stream, // additional captured arguments are
buffers); // forwarded to the initiation object.
(void)init.completion_handler; // the underlying completion handler used for the operation
// ...launch the operation (omitted for clarity)
return init.result.get();
}
//]
}
//------------------------------------------------------------------------------
} // (anon)

View File

@@ -0,0 +1,647 @@
//
// Copyright (c) 2016-2019 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)
//
// Official repository: https://github.com/boostorg/beast
//
#include "snippets.hpp"
#include <boost/beast/_experimental/unit_test/suite.hpp>
#include <boost/beast/_experimental/test/stream.hpp>
#include <boost/beast/core/async_op_base.hpp>
#include <boost/beast/core/buffers_prefix.hpp>
#include <boost/beast/core/error.hpp>
#include <boost/beast/core/flat_buffer.hpp>
#include <boost/beast/core/stream_traits.hpp>
#include <boost/beast/core/tcp_stream.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/ssl/ssl_stream.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/read.hpp>
#include <cstdlib>
#include <utility>
namespace boost {
namespace beast {
namespace {
struct handler_type
{
template<class... Args>
void operator()(Args&&...)
{
}
};
void
core_3_timeouts_snippets()
{
handler_type handler;
#include "snippets.ipp"
{
//[code_core_3_timeouts_1
// `ioc` will be used to dispatch completion handlers
tcp_stream stream(ioc);
//]
}
{
//[code_core_3_timeouts_2
// The resolver is used to look up the IP addresses for a domain name
net::ip::tcp::resolver resolver(ioc);
// The stream will use the same executor as the resolver
tcp_stream stream(resolver.get_executor());
//]
}
{
//[code_core_3_timeouts_3
// The strand will be used to invoke all completion handlers
tcp_stream stream(make_strand(ioc));
//]
net::ip::tcp::resolver resolver(ioc);
//[code_core_3_timeouts_4
// Set the logical operation timer to 30 seconds
stream.expires_after (std::chrono::seconds(30));
// If the connection is not established within 30 seconds,
// the operation will be canceled and the handler will receive
// error::timeout as the error code.
stream.async_connect(resolver.resolve("www.example.com", "http"),
[](error_code ec, net::ip::tcp::endpoint ep)
{
if(ec == error::timeout)
std::cerr << "async_connect took too long\n";
else if(! ec)
std::cout << "Connected to " << ep << "\n";
}
);
// The timer is still running. If we don't want the next
// operation to time out 30 seconds relative to the previous
// call to `expires_after`, we need to turn it off before
// starting another asynchronous operation.
stream.expires_never();
//]
}
{
//[code_core_3_timeouts_5
// The acceptor is used to listen and accept incoming connections.
// We construct the acceptor to use a new strand, and listen
// on the loopback address with an operating-system assigned port.
net::ip::tcp::acceptor acceptor(make_strand(ioc));
acceptor.bind(net::ip::tcp::endpoint(net::ip::make_address_v4("127.0.0.1"), 0));
acceptor.listen(0);
// This blocks until a new incoming connection is established.
// Upon success, the function returns a new socket which is
// connected to the peer. The socket will have its own executor,
// which in the call below is a new strand for the I/O context.
net::ip::tcp::socket s = acceptor.accept(make_strand(ioc));
// Construct a new tcp_stream from the connected socket.
// The stream will use the strand created when the connection
// was accepted.
tcp_stream stream(std::move(s));
//]
//[code_core_3_timeouts_6
flat_buffer b;
// Set the logical operation timer to 30 seconds.
stream.expires_after (std::chrono::seconds(30));
// Read a line from the stream into our dynamic buffer.
// The function dynamic_buffer_ref is used because Asio
// treats these buffers as non-owning references, but
// Beast uses them as first-class containers.
net::async_read_until(stream, dynamic_buffer_ref(b), '\n',
[&b, &stream](error_code ec, std::size_t bytes_transferred)
{
if(ec)
return;
// read_until can read past the '\n', these will end up in
// our buffer but we don't want to echo those extra received
// bytes. `bytes_transferred` will be the number of bytes
// up to and including the '\n'. We use `buffers_prefix` so
// that extra data is not written.
net::async_write(stream, buffers_prefix(bytes_transferred, b.data()),
[&b](error_code ec, std::size_t bytes_transferred)
{
// Consume the line from the buffer
b.consume(bytes_transferred);
if(ec)
std::cerr << "Error: " << ec.message() << "\n";
});
});
//]
//[code_core_3_timeouts_7
flat_buffer b2;
// Set the logical operation timer to 15 seconds.
stream.expires_after (std::chrono::seconds(15));
// Read another line from the stream into our dynamic buffer.
// The operation will time out after 15 seconds.
net::async_read_until(stream, dynamic_buffer_ref(b2), '\n', handler);
// Set the logical operation timer to 30 seconds.
stream.expires_after (std::chrono::seconds(30));
// Write the contents of the other buffer.
// This operation will time out after 30 seconds.
net::async_write(stream, b.data(), handler);
//]
}
{
//[code_core_3_timeouts_8
// To declare a stream with a rate policy, it is necessary to
// write out all of the template parameter types.
//
// `simple_rate_policy` is default constructible, but
// if the choice of RatePolicy is not DefaultConstructible,
// an instance of the type may be passed to the constructor.
basic_stream<net::ip::tcp, net::executor, simple_rate_policy> stream(ioc);
// The policy object, which is default constructed, or
// decay-copied upon construction, is attached to the stream
// and may be accessed through the function `rate_policy`.
//
// Here we set individual rate limits for reading and writing
stream.rate_policy().read_limit(10000); // bytes per second
stream.rate_policy().write_limit(850000); // bytes per second
//]
}
}
//[code_core_3_timeouts_1f
/** This function echoes back received lines from a peer, with a timeout.
The algorithm terminates upon any error (including timeout).
*/
template <class Protocol, class Executor>
void do_async_echo (basic_stream<Protocol, Executor>& stream)
{
// This object will hold our state when reading the line.
struct echo_line
{
basic_stream<Protocol, Executor>& stream;
// The shared pointer is used to extend the lifetime of the
// buffer until the last asynchronous operation completes.
std::shared_ptr<flat_buffer> buffer;
// This starts a new operation to read and echo a line
void operator()()
{
// If a line is not sent and received within 30 seconds, then
// the connection will be closed and this algorithm will terminate.
stream.expires_after(std::chrono::seconds(30));
// Read a line from the stream into our dynamic buffer, with a timeout
net::async_read_until(stream, dynamic_buffer_ref(*buffer), '\n', std::move(*this));
}
// This function is called when the read completes
void operator()(error_code ec, std::size_t bytes_transferred)
{
if(ec)
return;
net::async_write(stream, buffers_prefix(bytes_transferred, buffer->data()),
[this](error_code ec, std::size_t bytes_transferred)
{
buffer->consume(bytes_transferred);
if(! ec)
{
// Run this algorithm again
echo_line{stream, std::move(buffer)}();
}
else
{
std::cerr << "Error: " << ec.message() << "\n";
}
});
}
};
// Create the operation and run it
echo_line{stream, std::make_shared<flat_buffer>()}();
}
//]
//[code_core_3_timeouts_2f
/** Request an HTTP resource from a TLS host and return it as a string, with a timeout.
This example uses fibers (stackful coroutines) and its own I/O context.
*/
std::string
https_get (std::string const& host, std::string const& target, error_code& ec)
{
// It is the responsibility of the algorithm to clear the error first.
ec = {};
// We use our own I/O context, to make this function blocking.
net::io_context ioc;
// This context is used to hold client and server certificates.
// We do not perform certificate verification in this example.
net::ssl::context ctx(net::ssl::context::sslv23);
// This string will hold the body of the HTTP response, if any.
std::string result;
// Note that Networking TS does not come with spawn. This function
// launches a "fiber" which is a coroutine that has its own separately
// allocated stack.
boost::asio::spawn(ioc,
[&](boost::asio::yield_context yield)
{
// We use the Beast ssl_stream wrapped around a beast tcp_stream.
ssl_stream<tcp_stream> stream(ioc, ctx);
// The resolver will be used to look up the IP addresses for the host name
net::ip::tcp::resolver resolver(ioc);
// First, look up the name. Networking has its own timeout for this.
// The `yield` object is a CompletionToken which specializes the
// `net::async_result` customization point to make the fiber work.
//
// This call will appear to "block" until the operation completes.
// It isn't really blocking. Instead, the fiber implementation saves
// the call stack and suspends the function until the asynchronous
// operation is complete. Then it restores the call stack, and resumes
// the function to the statement following the async_resolve. This
// allows an asynchronous algorithm to be expressed synchronously.
auto const endpoints = resolver.async_resolve(host, "https", {}, yield[ec]);
if(ec)
return;
// The function `get_lowest_layer` retrieves the "bottom most" object
// in the stack of stream layers. In this case it will be the tcp_stream.
// This timeout will apply to all subsequent operations collectively.
// That is to say, they must all complete within the same 30 second
// window.
get_lowest_layer(stream).expires_after(std::chrono::seconds(30));
// `tcp_stream` range connect algorithms are member functions, unlike net::
get_lowest_layer(stream).async_connect(endpoints, yield[ec]);
if(ec)
return;
// Perform the TLS handshake
stream.async_handshake(net::ssl::stream_base::client, yield[ec]);
if(ec)
return;
// Send an HTTP GET request for the target
{
http::request<http::empty_body> req;
req.method(http::verb::get);
req.target(target);
req.version(11);
req.set(http::field::server, host);
req.set(http::field::user_agent, "Beast");
http::async_write(stream, req, yield[ec]);
if(ec)
return;
}
// Now read the response
flat_buffer buffer;
http::response<http::string_body> res;
http::async_read(stream, buffer, res, yield[ec]);
if(ec)
return;
// Try to perform the TLS shutdown handshake
stream.async_shutdown(yield[ec]);
// `net::ssl::error::stream_truncated`, also known as an SSL "short read",
// indicates the peer closed the connection without performing the
// required closing handshake (for example, Google does this to
// improve performance). Generally this can be a security issue,
// but if your communication protocol is self-terminated (as
// it is with both HTTP and WebSocket) then you may simply
// ignore the lack of close_notify.
//
// https://github.com/boostorg/beast/issues/38
//
// https://security.stackexchange.com/questions/91435/how-to-handle-a-malicious-ssl-tls-shutdown
//
// When a short read would cut off the end of an HTTP message,
// Beast returns the error beast::http::error::partial_message.
// Therefore, if we see a short read here, it has occurred
// after the message has been completed, so it is safe to ignore it.
if(ec == net::ssl::error::stream_truncated)
ec = {};
else if(ec)
return;
// Set the string to return to the caller
result = std::move(res.body());
});
// `run` will dispatch completion handlers, and block until there is
// no more "work" remaining. When this call returns, the operations
// are complete and we can give the caller the result.
ioc.run();
return result;
}
//]
//[code_core_3_timeouts_3f
class window
{
std::size_t value_ = 0;
// The size of the exponential window, in seconds.
// This should be a power of two.
static std::size_t constexpr Window = 4;
public:
/** Returns the number of elapsed seconds since the given time, and adjusts the time.
This function returns the number of elapsed seconds since the
specified time point, rounding down. It also moves the specified
time point forward by the number of elapsed seconds.
@param since The time point from which to calculate elapsed time.
The function will modify the value, by adding the number of elapsed
seconds to it.
@return The number of elapsed seconds.
*/
template<class Clock, class Duration>
static
std::chrono::seconds
get_elapsed(std::chrono::time_point<Clock, Duration>& since) noexcept
{
auto const elapsed = std::chrono::duration_cast<
std::chrono::seconds>(Clock::now() - since);
since += elapsed;
return elapsed;
}
/// Returns the current value, after adding the given sample.
std::size_t
update(std::size_t sample, std::chrono::seconds elapsed) noexcept
{
// Apply exponential decay.
//
// This formula is fast (no division or multiplication) but inaccurate.
// It overshoots by `n*(1-a)/(1-a^n), where a=(window-1)/window`.
// Could be good enough for a rough approximation, but if relying
// on this for production please perform tests!
auto count = elapsed.count();
while(count--)
value_ -= (value_ + Window - 1) / Window;
value_ += sample;
return value_ / Window;
}
/// Returns the current value
std::size_t
value() const noexcept
{
return value_ / Window;
}
};
//]
//[code_core_3_timeouts_4f
/** A RatePolicy to measure instantaneous throughput.
This measures the rate of transfer for reading and writing
using a simple exponential decay function.
*/
class rate_gauge
{
// The clock used to measure elapsed time
using clock_type = std::chrono::steady_clock;
// This implements an exponential smoothing window function.
// The value `Seconds` is the size of the window in seconds.
clock_type::time_point when_;
std::size_t read_bytes_ = 0;
std::size_t write_bytes_ = 0;
window read_window_;
window write_window_;
// Friending this type allows us to mark the
// member functions required by RatePolicy as private.
friend class rate_policy_access;
// Returns the number of bytes available to read currently
// Required by RatePolicy
std::size_t
available_read_bytes() const noexcept
{
// no limit
return (std::numeric_limits<std::size_t>::max)();
}
// Returns the number of bytes available to write currently
// Required by RatePolicy
std::size_t
available_write_bytes() const noexcept
{
// no limit
return (std::numeric_limits<std::size_t>::max)();
}
// Called every time bytes are read
// Required by RatePolicy
void
transfer_read_bytes(std::size_t n) noexcept
{
// Add this to our running total of bytes read
read_bytes_ += n;
}
// Called every time bytes are written
// Required by RatePolicy
void
transfer_write_bytes(std::size_t n) noexcept
{
// Add this to our running total of bytes written
write_bytes_ += n;
}
// Called approximately once per second
// Required by RatePolicy
void
on_timer()
{
// Calculate elapsed time in seconds, and adjust our time point
auto const elapsed = window::get_elapsed(when_);
// Skip the update when elapsed==0,
// otherwise the measurement will have jitter
if(elapsed.count() == 0)
return;
// Add our samples and apply exponential decay
read_window_.update(read_bytes_, elapsed);
write_window_.update(write_bytes_, elapsed);
// Reset our counts of bytes transferred
read_bytes_ = 0;
write_bytes_ = 0;
}
public:
rate_gauge()
: when_(clock_type::now())
{
}
/// Returns the current rate of reading in bytes per second
std::size_t
read_bytes_per_second() const noexcept
{
return read_window_.value();
}
/// Returns the current rate of writing in bytes per second
std::size_t
write_bytes_per_second() const noexcept
{
return write_window_.value();
}
};
//]
void
core_3_timeouts_snippets2()
{
#include "snippets.ipp"
{
//[code_core_3_timeouts_9
// This stream will use our new rate_gauge policy
basic_stream<net::ip::tcp, net::executor, rate_gauge> stream(ioc);
//...
// Print the current rates
std::cout <<
stream.rate_policy().read_bytes_per_second() << " bytes/second read\n" <<
stream.rate_policy().write_bytes_per_second() << " bytes/second written\n";
//]
}
}
} // (anon)
template class basic_stream<net::ip::tcp, net::executor, rate_gauge>;
struct core_3_timeouts_test
: public beast::unit_test::suite
{
void
testWindow()
{
window w;
std::size_t v0 = w.value();
std::size_t const N = 100000;
for(std::size_t n = 1; n <= 2; ++n)
{
for(std::size_t i = 0;;++i)
{
auto const v = w.update(n * N, std::chrono::seconds(n));
if(v == v0)
{
BEAST_PASS();
#if 0
log <<
"update(" << n*N << ", " << n <<
") converged to " << w.value() <<
" in " << i << std::endl;
#endif
break;
}
if(i > 1000)
{
BEAST_FAIL();
break;
}
v0 = v;
}
}
}
void
run() override
{
testWindow();
BEAST_EXPECT(&core_3_timeouts_snippets);
BEAST_EXPECT(&core_3_timeouts_snippets2);
BEAST_EXPECT((&do_async_echo<net::ip::tcp, net::io_context::executor_type>));
BEAST_EXPECT(&https_get);
}
};
BEAST_DEFINE_TESTSUITE(beast,doc,core_3_timeouts);
} // beast
} // boost

View File

@@ -15,7 +15,6 @@
#include <boost/beast/core/error.hpp>
#include <boost/beast/core/stream_traits.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/async_result.hpp>
#include <cstdlib>
#include <utility>
@@ -23,31 +22,31 @@ namespace boost {
namespace beast {
void
core_3_layers_snippets()
core_4_layers_snippets()
{
#include "snippets.ipp"
{
//[code_core_3_layers_1
//[code_core_4_layers_1
net::ssl::stream<net::ip::tcp::socket> ss(ioc, ctx);
//]
}
{
//[code_core_3_layers_2
//[code_core_4_layers_2
websocket::stream<net::ip::tcp::socket> ws(ioc);
//]
}
//[code_core_3_layers_3
//[code_core_4_layers_3
websocket::stream<net::ssl::stream<net::ip::tcp::socket>> ws(ioc, ctx);
//]
}
//[code_core_3_layers_4
//[code_core_4_layers_4
// Set non-blocking mode on a stack of stream
// layers with a regular socket at the lowest layer.
@@ -63,7 +62,7 @@ void set_non_blocking (Stream& stream)
//]
//[code_core_3_layers_5
//[code_core_4_layers_5
// A layered stream which counts the bytes read and bytes written on the next layer
template <class NextLayer>
@@ -229,7 +228,7 @@ BOOST_STATIC_ASSERT(is_sync_write_stream<counted_stream<test::stream>>::value);
BOOST_STATIC_ASSERT(is_async_read_stream<counted_stream<test::stream>>::value);
BOOST_STATIC_ASSERT(is_async_write_stream<counted_stream<test::stream>>::value);
struct core_3_layers_test
struct core_4_layers_test
: public beast::unit_test::suite
{
struct handler
@@ -242,7 +241,7 @@ struct core_3_layers_test
void
run() override
{
BEAST_EXPECT(&core_3_layers_snippets);
BEAST_EXPECT(&core_4_layers_snippets);
BEAST_EXPECT(&set_non_blocking<net::ip::tcp::socket>);
BEAST_EXPECT(&counted_stream<test::stream>::get_executor);
@@ -271,7 +270,7 @@ struct core_3_layers_test
}
};
BEAST_DEFINE_TESTSUITE(beast,doc,core_3_layers);
BEAST_DEFINE_TESTSUITE(beast,doc,core_4_layers);
} // beast
} // boost