mirror of
https://github.com/boostorg/beast.git
synced 2025-08-03 06:44:39 +02:00
Refactor docs
This commit is contained in:
45
doc/qbk/01_intro/1_quick_look.qbk
Normal file
45
doc/qbk/01_intro/1_quick_look.qbk
Normal 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]
|
@@ -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]
|
25
doc/qbk/01_intro/1b_autobahn.qbk
Normal file
25
doc/qbk/01_intro/1b_autobahn.qbk
Normal 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]
|
@@ -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]
|
@@ -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]
|
@@ -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]
|
||||
|
@@ -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,
|
||||
|
217
doc/qbk/03_core/3_timeouts.qbk
Normal file
217
doc/qbk/03_core/3_timeouts.qbk
Normal 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]
|
@@ -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]
|
@@ -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)
|
@@ -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)
|
@@ -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]
|
@@ -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.
|
@@ -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]
|
@@ -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]
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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`]
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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:RatePolicy RatePolicy]
|
||||
[section:RatePolicy RatePolicy __new__]
|
||||
|
||||
An instance of [*RatePolicy] is associated with a
|
||||
[link beast.ref.boost__beast__basic_stream `basic_stream`],
|
||||
|
@@ -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)
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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">🞲</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]
|
||||
|
@@ -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 <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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__basic_stream">basic_stream</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__async_op_base">async_op_base</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__basic_stream">basic_stream</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__flat_stream">flat_stream</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__saved_handler">saved_handler</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__rate_policy_access">rate_policy_access</link> <emphasis role="green">★</emphasis></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
<entry valign="top">
|
||||
<bridgehead renderas="sect3">Classes <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> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__ssl_stream">ssl_stream</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__simple_rate_policy">simple_rate_policy</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__stable_async_op_base">stable_async_op_base</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__unlimited_rate_policy">unlimited_rate_policy</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__tcp_stream">tcp_stream</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__unlimited_rate_policy">unlimited_rate_policy</link> <emphasis role="green">★</emphasis></member>
|
||||
</simplelist>
|
||||
<bridgehead renderas="sect3">Constants</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.ref.boost__beast__condition">condition</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__error">error</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__condition">condition</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__error">error</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__async_detect_ssl">async_detect_ssl</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__beast_close_socket">beast_close_socket</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__bind_front_handler">bind_front_handler</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__allocate_stable">allocate_stable</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__async_detect_ssl">async_detect_ssl</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__beast_close_socket">beast_close_socket</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__bind_front_handler">bind_front_handler</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__detect_ssl">detect_ssl</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__close_socket">close_socket</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__detect_ssl">detect_ssl</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__get_lowest_layer">get_lowest_layer</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__make_strand">make_strand</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__lowest_layer_type">lowest_layer_type</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__executor_type">executor_type</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__lowest_layer_type">lowest_layer_type</link> <emphasis role="green">★</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> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.concepts.RatePolicy">RatePolicy</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__dynamic_buffer_ref_wrapper">dynamic_buffer_ref_wrapper</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__buffer_size">buffer_size</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__buffers_range_ref">buffers_range_ref</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__buffers_range">buffers_range</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__buffers_range_ref">buffers_range_ref</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__make_printable">make_printable</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__dynamic_buffer_ref">dynamic_buffer_ref</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__make_printable">make_printable</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__buffers_iterator_type">buffers_iterator_type</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__is_const_buffer_sequence">is_const_buffer_sequence</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__is_mutable_buffer_sequence">is_mutable_buffer_sequence</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__buffers_type">buffers_type</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__buffers_iterator_type">buffers_iterator_type</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__is_const_buffer_sequence">is_const_buffer_sequence</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__is_mutable_buffer_sequence">is_mutable_buffer_sequence</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__websocket__stream_base__timeout">timeout</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__websocket__stream_base.suggested_settings">suggested_settings</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__websocket__stream_base__decorator">decorator</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__websocket__stream_base__timeout">timeout</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__handler">test::handler</link> <emphasis role="green">★</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> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__fail_handler">test::fail_handler</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__success_handler">test::success_handler</link> <emphasis role="green">🞲</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__any_handler">test::any_handler</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__fail_handler">test::fail_handler</link> <emphasis role="green">★</emphasis></member>
|
||||
<member><link linkend="beast.ref.boost__beast__test__success_handler">test::success_handler</link> <emphasis role="green">★</emphasis></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
<entry valign="top">
|
||||
|
@@ -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">🞲</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
|
||||
'''
|
||||
⭐⭐⭐
|
||||
'''
|
||||
[@https://github.com/boostorg/beast [*star the repository]]
|
||||
'''
|
||||
⭐⭐⭐
|
||||
'''
|
||||
!
|
||||
* 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.
|
||||
* '''
|
||||
⚡
|
||||
'''
|
||||
[*['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]
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
||||
|
647
test/doc/core_3_timeouts.cpp
Normal file
647
test/doc/core_3_timeouts.cpp
Normal 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
|
@@ -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
|
Reference in New Issue
Block a user