Update and tidy documentation

This commit is contained in:
Vinnie Falco
2016-09-25 11:19:51 -04:00
parent 0821ca6e11
commit 9cc65c8850
25 changed files with 678 additions and 598 deletions

View File

@ -3,8 +3,9 @@
* Add missing rebind to handler_alloc * Add missing rebind to handler_alloc
* Fix error handling in http server examples * Fix error handling in http server examples
* Fix CMake scripts for MinGW * Fix CMake scripts for MinGW
* Better WebSocket decorator
* Use BOOST_ASSERT * Use BOOST_ASSERT
* Better WebSocket decorator
* Update and tidy documentation
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@ -15,15 +15,15 @@ using boostbook ;
using quickbook ; using quickbook ;
using doxygen ; using doxygen ;
xml beast_boostbook : master.qbk ; import quickbook ;
path-constant out : . ; path-constant here : . ;
install stylesheets install stylesheets
: :
$(broot)/doc/src/boostbook.css $(broot)/doc/src/boostbook.css
: :
<location>$(out)/html <location>$(here)/html
; ;
explicit stylesheets ; explicit stylesheets ;
@ -35,7 +35,7 @@ install images
images/body.png images/body.png
images/message.png images/message.png
: :
<location>$(out)/html/images <location>$(here)/html/images
; ;
explicit images ; explicit images ;
@ -44,40 +44,49 @@ install callouts
: :
[ glob $(broot)/doc/src/images/callouts/*.png ] [ glob $(broot)/doc/src/images/callouts/*.png ]
: :
<location>$(out)/html/images/callouts <location>$(here)/html/images/callouts
; ;
explicit callout ; explicit callout ;
boostbook doc install examples
: :
beast_boostbook [ glob ../examples/*.* ]
: :
<xsl:param>chapter.autolabel=0 <location>$(here)/html/examples
<xsl:param>boost.image.src=images/beast.png
<xsl:param>boost.image.alt="Beast Logo"
<xsl:param>boost.image.w=2400
<xsl:param>boost.image.h=80
<xsl:param>boost.root=$(broot)
<xsl:param>chapter.autolabel=0
<xsl:param>chunk.first.sections=1 # Chunk the first top-level section?
<xsl:param>chunk.section.depth=8 # Depth to which sections should be chunked
<xsl:param>generate.section.toc.level=1 # Control depth of TOC generation in sections
<xsl:param>toc.max.depth=2 # How many levels should be created for each TOC?
<xsl:param>toc.section.depth=2 # How deep should recursive sections appear in the TOC?
:
<location>temp
<dependency>stylesheets
<dependency>images
; ;
#explicit doc ; explicit examples ;
# <xsl:param>nav.layout=none
# <format>html:<xsl:param>location=../bin/doc/html
# <xsl:param>generate.toc="chapter nop section nop"
# <xsl:param>root.filename=index
# <xsl:param>output-root="../bin/html"
xml doc
:
master.qbk
:
<location>temp
<include>$(broot)/tools/boostbook/dtd
;
boostbook boostdoc
:
doc
:
<xsl:param>boost.root=$(broot)
<xsl:param>boost.image.src=images/beast.png
<xsl:param>boost.image.alt="Beast Logo"
<xsl:param>boost.image.w=1330
<xsl:param>boost.image.h=80
<xsl:param>chapter.autolabel=0
<xsl:param>chunk.section.depth=8 # Depth to which sections should be chunked
<xsl:param>chunk.first.sections=1 # Chunk the first top-level section?
<xsl:param>toc.section.depth=8 # How deep should recursive sections appear in the TOC?
<xsl:param>toc.max.depth=8 # How many levels should be created for each TOC?
<xsl:param>generate.section.toc.level=8 # Control depth of TOC generation in sections
<xsl:param>generate.toc="chapter nop section nop"
<include>$(broot)/tools/boostbook/dtd
:
<location>temp
<dependency>examples
<dependency>images
<dependency>stylesheets
;
#[include reference.qbk]
#[xinclude index.xml]

View File

@ -25,7 +25,7 @@ libraries:
* Let library users make the important decisions such as how to * Let library users make the important decisions such as how to
allocate memory or how to leverage flow control. allocate memory or how to leverage flow control.
Beast uses the [link beast.types.DynamicBuffer [*`DynamicBuffer`]] concept Beast uses the [link beast.ref.DynamicBuffer [*`DynamicBuffer`]] concept
presented in the Netwoking TS, and relies heavily on the Boost.Asio presented in the Netwoking TS, and relies heavily on the Boost.Asio
[*`ConstBufferSequence`] and [*`MutableBufferSequence`] concepts for passing [*`ConstBufferSequence`] and [*`MutableBufferSequence`] concepts for passing
buffers to functions. The authors have found the dynamic buffer and buffer buffers to functions. The authors have found the dynamic buffer and buffer

111
doc/examples.qbk Normal file
View File

@ -0,0 +1,111 @@
[/
Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]
[section:example Examples]
These usage examples are intended to quickly impress upon readers the
flavor of the library. They are complete programs which may be built
and run. Source code and build scripts for these programs may be found
in the examples directory.
[heading HTTP GET]
Use HTTP to request the root page from a website and print the response:
```
#include <beast/http.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <string>
int main()
{
// Normal boost::asio setup
std::string const host = "boost.org";
boost::asio::io_service ios;
boost::asio::ip::tcp::resolver r{ios};
boost::asio::ip::tcp::socket sock{ios};
boost::asio::connect(sock,
r.resolve(boost::asio::ip::tcp::resolver::query{host, "http"}));
// Send HTTP request using beast
beast::http::request_v1<beast::http::empty_body> req;
req.method = "GET";
req.url = "/";
req.version = 11;
req.headers.replace("Host", host + ":" + std::to_string(sock.remote_endpoint().port()));
req.headers.replace("User-Agent", "Beast");
beast::http::prepare(req);
beast::http::write(sock, req);
// Receive and print HTTP response using beast
beast::streambuf sb;
beast::http::response_v1<beast::http::streambuf_body> resp;
beast::http::read(sock, sb, resp);
std::cout << resp;
}
```
[heading WebSocket]
Establish a WebSocket connection, send a message and receive the reply:
```
#include <beast/core/to_string.hpp>
#include <beast/websocket.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <string>
int main()
{
// Normal boost::asio setup
std::string const host = "echo.websocket.org";
boost::asio::io_service ios;
boost::asio::ip::tcp::resolver r{ios};
boost::asio::ip::tcp::socket sock{ios};
boost::asio::connect(sock,
r.resolve(boost::asio::ip::tcp::resolver::query{host, "80"}));
// WebSocket connect and send message using beast
beast::websocket::stream<boost::asio::ip::tcp::socket&> ws{sock};
ws.handshake(host, "/");
ws.write(boost::asio::buffer("Hello, world!"));
// Receive WebSocket message, print and close using beast
beast::streambuf sb;
beast::websocket::opcode op;
ws.read(op, sb);
ws.close(beast::websocket::close_code::normal);
std::cout << to_string(sb.data()) << "\n";
}
```
[heading HTTP Crawl]
This example retrieves the page at each of the most popular domains
as measured by Alexa.
* [@examples/http_crawl.cpp]
[heading HTTP Server]
This example demonstrates both synchronous and asynchronous server
implementations. It also provides an example of implementing a [*Body]
type, in `file_body`.
* [@examples/file_body.hpp]
* [@examples/http_async_server.hpp]
* [@examples/http_sync_server.hpp]
* [@examples/http_server.cpp]
[heading Listings]
These are stand-alone listings of the HTTP and WebSocket examples.
* [@examples/http_example.cpp]
* [@examples/websocket_example.cpp]
[endsect]

View File

@ -5,138 +5,149 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:http HTTP]
[section:http Using HTTP]
[block '''
<informaltable frame="all"><tgroup cols="1"><colspec colname="a"/><tbody><row><entry valign="top"><simplelist>
<member><link linkend="beast.http.message">Message</link></member>
<member><link linkend="beast.http.headers">Headers</link></member>
<member><link linkend="beast.http.body">Body</link></member>
<member><link linkend="beast.http.algorithms">Algorithms</link></member>
<member><link linkend="beast.http.sockets">Sockets</link></member>
</simplelist></entry></row></tbody></tgroup></informaltable>
''']
Beast.HTTP offers programmers simple and performant models of HTTP messages and Beast.HTTP offers programmers simple and performant models of HTTP messages and
their associated operations including synchronous and asynchronous reading and their associated operations including synchronous and asynchronous reading and
writing of messages in the HTTP/1 wire format using Boost.Asio. writing of messages in the HTTP/1 wire format using Boost.Asio.
The HTTP protocol is described fully in
[@https://tools.ietf.org/html/rfc7230 rfc7230]
[section:motivation Motivation]
The HTTP protocol is pervasive in network applications. As C++ is a logical
choice for high performance network servers, there is great utility in solid
building blocks for manipulating, sending, and receiving HTTP messages
compliant with the Hypertext Transfer Protocol and the supplements that
follow. Unfortunately reliable implementations or industry standards do not
exist in C++.
Beast.HTTP is built on Boost.Asio and uses its own robust header-only HTTP/1
message parser modeled after the nodejs http-parser (written in C). A proposal
to add networking functionality to the C++ standard library, based on
Boost.Asio, is under consideration by the standards committee. Since the final
approved networking interface for the C++ standard library will likely closely
resemble the current interface of Boost.Asio, it is logical for Beast.HTTP to
use Boost.Asio as its network transport.
[endsect]
[section:scope Scope]
This library is designed to be a building block for creating higher level
libraries. It is not designed to be end-user facing. There is no convenient
class that implements the core of a web server, nor is there a convenient
class to quickly perform common operations such as fetching a file or
connecting and retrieving a document from a secure connection. These
use-cases are important, but this library does not try to do that. Instead,
it offers primitives that can be used to build those user-facing algorithms.
A HTTP message (referred to hereafter as "message") contains request or A HTTP message (referred to hereafter as "message") contains request or
response specific attributes, a series of zero or more name/value pairs response specific attributes, a series of zero or more name/value pairs
(collectively termed "headers"), and a series of octets called the message (collectively termed "headers"), and a series of octets called the message
body which may be zero in length. The HTTP protocol defines the client and body which may be zero in length. The HTTP protocol defines the client and
server roles: clients send messages called requests and servers send back server roles: clients send messages called requests and servers send back
messages called responses. `http::message` models both requests and responses. messages called responses.
Beast aims to offer this functionality:
* [*Model]: Provide a universal HTTP message class model.
* [*Build]: Construct a new message and manipulate its contents.
* [*Parse]: Deserialize a message from a network or memory stream in HTTP/1 wire format.
* [*Serialize]: Serialize a message into a network or memory stream in HTTP/1 wire format.
[note The documentation which follows assumes familiarity with
both Boost.Asio and the HTTP protocol specification described in
[@https://tools.ietf.org/html/rfc7230 rfc7230] ]
[endsect]
[section:usage Usage]
[note [note
Sample code and identifiers mentioned in this section are written The following documentation assumes familiarity with both Boost.Asio
as if the following declarations are in effect: and the HTTP protocol specification described in __rfc7230__. Sample code
and identifiers mentioned in this section are written as if the following
declarations are in effect:
``` ```
#include <beast/http.hpp> #include <beast/http.hpp>
using namespace beast; using namespace beast;
using namespace beast::http;
``` ```
] ]
In the paragraphs that follow we describe the available interfaces for [section:message Message]
performing typical operations such as interacting with a HTTP server
or handling simple requests. Subsequent sections cover the message model
and its customization points in more depth, for advanced applications.
[heading Declarations] The __message__ class template models HTTP/2 requests and responses, while the
derived class __message_v1__ models HTTP/1 requests and responses, adding the
required version field. These objects are complete: they contain
all the information required to permit the algorithms to operate. These objects
are first class: They may be returned from functions, moved, copied, passed
as arguments, and stored in containers. Request and response messages are
distinct types; functions may be overloaded on just one or the other if
desired. Because this class template supports HTTP/1 and HTTP/2, it is
sometimes referred to as the universal message model.
To do anything, a message must be declared. The message class template These class templates have three template parameters:
requires at minimum, a value indicating whether the message is a request
(versus a response), and a `Body` type. The choice of `Body` determines the
kind of container used to represent the message body. Here we will
declare a HTTP/1 request that has a `std::string` for the body container:
``` ```
http::message_v1<true, http::string_body> req; template<bool isRequest, class Body, class Headers>
class message;
template<bool isRequest, class Body, class Headers>
class message_v1;
``` ```
Two type aliases are provided for notational convenience when declaring * [*`isRequest`]: Controls whether or not the message is a request or response.
HTTP/1 messages. These two statements declare a request and a response Depending on the value, different data members will be present in the resulting
respectively: type.
* [*`Body`]: determines both the kind of container used to represent the
message body and the algorithms used to parse and serialize it.
* [*`Headers`]: determines the container used to represent the HTTP headers.
For notational convenience, the following template type aliases are provided:
``` ```
http::request_v1<http::string_body> req; template<class Body, class Headers = basic_headers<std::allocator<char>>>
http::response_v1<http::string_body> resp; using request = message<true, Body, Headers>;
template<class Body, class Headers = basic_headers<std::allocator<char>>>
using response = message<false, Body, Headers>;
template<class Body, class Headers = basic_headers<std::allocator<char>>>
using request_v1 = message_v1<true, Body, Headers>;
template<class Body, class Headers = basic_headers<std::allocator<char>>>
using response_v1 = message_v1<false, Body, Headers>;
``` ```
[heading Members] Although these aliases have a common base class, they have different fields
depending on whether the message is a request or a response. These simplified
declarations notionally illustrate the members of HTTP/1 messages:
Message objects are default constructible, with public access to data members.
Request and response objects have some common members, and some members unique
to the message type. These statements set all the members in each message:
``` ```
http::request_v1<http::string_body> req; template<class Body, class Headers>
struct request_v1
{
int version; 10 or 11
std::string method;
std::string url;
Headers headers;
typename Body::value_type body;
};
template<class Body, class Headers>
struct response_v1
{
int version; 10 or 11
int status;
std::string reason;
Headers headers;
typename Body::value_type body;
};
```
These statements set fields in request and response message objects:
```
request_v1<string_body> req;
req.method = "GET"; req.method = "GET";
req.url = "/index.html"; req.url = "/index.html";
req.version = 11; // HTTP/1.1 req.version = 11; // HTTP/1.1
req.headers.insert("User-Agent", "hello_world"); req.headers.insert("User-Agent", "Beast.HTTP");
req.body = ""; req.body = "";
http::response_v1<http::string_body> resp; response_v1<string_body> res;
resp.status = 404; res.status = 404;
resp.reason = "Not Found"; res.reason = "Not Found";
resp.version = 10; // HTTP/1.0 res.version = 10; // HTTP/1.0
resp.headers.insert("Server", "Beast.HTTP"); res.headers.insert("Server", "Beast.HTTP");
resp.body = "The requested resource was not found."; res.body = "The requested resource was not found.";
``` ```
[heading Headers] [endsect]
The `message::headers` member is a container for setting the field/value
pairs in the message. These statements change the values of the headers
in the message passed: [section:headers Headers]
The [*`Headers`] type represents a container that can set or retrieve the
headers in a message. Beast provides the
[link beast.ref.http__basic_headers `basic_headers`] class which serves
the needs for most users. It supports modification and inspection of values.
The field names are not case-sensitive.
These statements change the values of the headers in the message passed:
``` ```
template<class Body> template<class Body>
void set_fields(http::request_v1<Body>& req) void set_fields(request_v1<Body>& req)
{ {
if(! req.exists("User-Agent")) if(! req.exists("User-Agent"))
req.insert("User-Agent", "myWebClient"); req.insert("User-Agent", "myWebClient");
@ -148,17 +159,32 @@ in the message passed:
} }
``` ```
[heading Body] [heading Advanced]
The `message::body` member represents the message body. Depending on the This illustration shows more detail about the
`Body` template argument type, this could be a writable container. The [link beast.ref.http__message [*`message`]] class template (boilerplate
following types, provided by the library, are suitable choices for the present in the actual declaration has been removed for clarity):
`Body` type:
[$images/message.png [width 580px] [height 225px]]
User defined [*`Headers`] types are possible. To support serialization, the
type must meet the requirements of __FieldSequence__. To support parsing using
the provided parser, the type must provide the `insert` member function.
[endsect]
[section:body Body]
The message [*`Body`] template parameter controls both the type of the data
member of the resulting message object, and the algorithms used during parsing
and serialization. Beast provides three very common [*`Body`] types:
* [link beast.ref.http__empty_body [*`empty_body`:]] An empty message body. * [link beast.ref.http__empty_body [*`empty_body`:]] An empty message body.
Used in GET requests where there is no message body. Example: Used in GET requests where there is no message body. Example:
``` ```
http::request_v1<http::empty_body> req; request_v1<empty_body> req;
req.version = 11; req.version = 11;
req.method = "GET"; req.method = "GET";
req.url = "/index.html"; req.url = "/index.html";
@ -170,36 +196,83 @@ or response with simple text in the message body (such as an error message).
Has the same insertion complexity of `std::string`. This is the type of body Has the same insertion complexity of `std::string`. This is the type of body
used in the examples: used in the examples:
``` ```
http::response_v1<http::string_body> resp; response_v1<string_body> res;
static_assert(std::is_same<decltype(resp.body), std::string>::value); static_assert(std::is_same<decltype(res.body), std::string>::value);
resp.body = "Here is the data you requested"; res.body = "Here is the data you requested";
``` ```
* [link beast.ref.http__streambuf_body [*`streambuf_body`:]] A body with a * [link beast.ref.http__streambuf_body [*`streambuf_body`:]] A body with a
`value_type` of [link beast.ref.streambuf `streambuf`]: an efficient storage `value_type` of [link beast.ref.streambuf `streambuf`]: an efficient storage
object which uses multiple octet arrays of varying lengths to represent data. object which uses multiple octet arrays of varying lengths to represent data.
[heading Sockets] [heading Advanced]
User-defined types are possible for the message body, where the type meets the
[link beast.ref.Body [*`Body`]] requirements. This simplified class declaration
shows the customization points available to user-defined body types:
[$images/body.png [width 510px] [height 210px]]
* [*`value_type`]: Determines the type of the
[link beast.ref.http__message.body `message::body`] member. If this
type defines default construction, move, copy, or swap, then message objects
declared with this [*`Body`] will have those operations defined.
* [*`reader`]: An optional nested type meeting the requirements of
[link beast.ref.Reader [*`Reader`]]. If present, this defines the algorithm
used for parsing bodies of this type.
* [*`writer`]: An optional nested type meeting the requirements of
[link beast.ref.Writer [*`Writer`]]. If present, this defines the algorithm
used for serializing bodies of this type.
The examples included with this library provide a Body implementation that
serializing message bodies that come from a file.
[endsect]
[section:algorithms Algorithms]
In addition to the universal message model, Beast provides synchronous
algorithms which operate on HTTP/1 messages:
* [link beast.ref.http__read [*read]]: Parse a message from a stream
* [link beast.ref.http__write [*write]]: Serialize a message into its wire format on a stream
Asynchronous versions of these algorithms are also available:
* [link beast.ref.http__async_read [*async_read]]: Parse a message from a stream
* [link beast.ref.http__async_write [*async_write]]: Serialize a message into its wire format on a stream
[endsect]
[section:sockets Using Sockets]
The library provides simple free functions modeled after Boost.Asio to The library provides simple free functions modeled after Boost.Asio to
send and receive messages on TCP/IP sockets, SSL streams, or any object send and receive messages on TCP/IP sockets, SSL streams, or any object
which meets the Boost.Asio type requirements (SyncReadStream, SyncWriteStream, which meets the Boost.Asio type requirements (SyncReadStream, SyncWriteStream,
AsyncReadStream, and AsyncWriteStream depending on the types of operations AsyncReadStream, and AsyncWriteStream depending on the types of operations
performed). To send messages synchronously, use one of the `http:write` performed). To send messages synchronously, use one of the
functions: [link beast.ref.http__write `write`] functions:
``` ```
void send_request(boost::asio::ip::tcp::socket& sock) void send_request(boost::asio::ip::tcp::socket& sock)
{ {
http::request<http::empty_body> req; request<empty_body> req;
req.version = 11; req.version = 11;
req.method = "GET"; req.method = "GET";
req.url = "/index.html"; req.url = "/index.html";
... ...
http::write(sock, req); // Throws exception on error write(sock, req); // Throws exception on error
... ...
// Alternatively // Alternatively
boost::system::error:code ec; boost::system::error:code ec;
http::write(sock, req, ec); write(sock, req, ec);
if(ec) if(ec)
std::cerr << "error writing http message: " << ec.message(); std::cerr << "error writing http message: " << ec.message();
} }
@ -209,27 +282,27 @@ An asynchronous interface is available:
``` ```
void handle_write(boost::system::error_code); void handle_write(boost::system::error_code);
... ...
http::request_v1<http::empty_body> req; request_v1<empty_body> req;
... ...
http::async_write(sock, req, std::bind(&handle_write, std::placeholders::_1)); async_write(sock, req, std::bind(&handle_write, std::placeholders::_1));
``` ```
When the implementation reads messages from a socket, it can read bytes lying When the implementation reads messages from a socket, it can read bytes lying
after the end of the message if they are present (the alternative is to read after the end of the message if they are present (the alternative is to read
a single byte at a time which is unsuitable for performance reasons). To a single byte at a time which is unsuitable for performance reasons). To
store and re-use these extra bytes on subsequent messages, the read interface store and re-use these extra bytes on subsequent messages, the read interface
requires an additional parameter: a [link beast.types.DynamicBuffer [*`DynamicBuffer`]] requires an additional parameter: a [link beast.ref.DynamicBuffer [*`DynamicBuffer`]]
object. This example reads a message from the socket, with the extra bytes object. This example reads a message from the socket, with the extra bytes
stored in the streambuf parameter for use in a subsequent call to read: stored in the streambuf parameter for use in a subsequent call to read:
``` ```
boost::asio::streambuf sb; boost::asio::streambuf sb;
... ...
http::response_v1<http::string_body> resp; response_v1<string_body> res;
http::read(sock, sb, resp); // Throws exception on error read(sock, sb, res); // Throws exception on error
... ...
// Alternatively // Alternatively
boost::system::error:code ec; boost::system::error:code ec;
http::read(sock, sb, resp, ec); read(sock, sb, res, ec);
if(ec) if(ec)
std::cerr << "error reading http message: " << ec.message(); std::cerr << "error reading http message: " << ec.message();
``` ```
@ -241,116 +314,28 @@ called:
void handle_read(boost::system::error_code); void handle_read(boost::system::error_code);
... ...
boost::asio::streambuf sb; boost::asio::streambuf sb;
http::response_v1<http::string_body> resp; response_v1<string_body> res;
... ...
http::async_read(sock, resp, std::bind(&handle_read, std::placeholders::_1)); async_read(sock, res, std::bind(&handle_read, std::placeholders::_1));
``` ```
An alternative to using a `boost::asio::streambuf` is to use a An alternative to using a `boost::asio::streambuf` is to use a
[link beast.ref.streambuf `beast::streambuf`], which meets the requirements of __streambuf__, which meets the requirements of __DynamicBuffer__ and
[*`DynamicBuffer`] and is optimized for performance: is optimized for performance:
``` ```
void handle_read(boost::system::error_code); void handle_read(boost::system::error_code);
... ...
beast::streambuf sb; beast::streambuf sb;
http::response_v1<http::string_body> resp; response_v1<string_body> res;
http::read(sock, sb, resp); read(sock, sb, res);
``` ```
The `read` implementation can use any object meeting the requirements of The `read` implementation can use any object meeting the requirements of
[link beast.types.DynamicBuffer [*`DynamicBuffer`]], allowing callers to define custom __DynamicBuffer__, allowing callers to define custom
memory management strategies used by the implementation. memory management strategies used by the implementation.
[endsect] [endsect]
[section:advanced Advanced]
The spectrum of hardware and software platforms which perform these typical
HTTP operations is vast, ranging from powerful servers in large datacenters
to tiny resource-limited embedded devices. No single concrete implementation
of a class intended to model messages can efficiently serve all needs.
For example, an object that minimizes resources during parsing may not be
able to edit and change headers dynamically. A message that represents the
message body as a disk file may support sending but not parsing. Many efficient
and correct models of messages exist, supporting some or all of the
operations listed above.
[heading Message model]
The message class template and provided Body types are suitable for casual
library users. This section explains the message model for advanced users
who wish to take control over aspects of the implementation. We introduce
customization points for the header and body via class template arguments.
This illustration shows more detail about the
[link beast.ref.http__message [*`message`]] class template (boilerplate
present in the actual declaration has been removed for clarity):
[$images/message.png [width 580px] [height 225px]]
The default constructor, move special members, and copy special members are
all defaulted. A message is movable, copyable, or default constructible based
on the capabilities of its template arguments.
Messages modeled in this fashion are ['complete], containing all of the
information required to perform the supported set of operations. They are
['first-class types], returnable from functions and composable. HTTP
requests and responses are distinct types, allowing functions to be
overloaded on the type of message.
[endsect] [endsect]
[section:headers Headers Type]
The `Headers` type represents the field/value pairs present in every HTTP
message. These types implement the
[link beast.types.FieldSequence [*`FieldSequence`]]
concept. The value type of a field sequence is an object meeting the
requirements of [link beast.types.Field [*`Field`]]. The implementation can
serialize any instance of `Headers` that meets the field sequence requirements.
This example shows a function which returns `true` if the specified field
sequence has a connect field:
```
template<class FieldSequence>
bool
has_connect(FieldSequence const& fs)
{
return std::find_if(fs.begin(), fs.end(),
[&](auto const& field)
{
return ci_equal(field.name(), "Connect");
});
}
```
[endsect]
[section:body Body Type]
The `Body` template argument in the `message` class must meet the
[link beast.types.Body [*`Body`] requirements]. It provides customization
of the data member in the message, the algorithm for parsing, and the
algorithm for serialization:
[$images/body.png [width 510px] [height 210px]]
Instances of the optional nested types `writer` and `reader` perform
serialization and deserialization of the message body. If either or
both of these types are present, the message becomes serializable, parsable,
or both. They model [link beast.types.Reader [*`Reader`]] and
[link beast.types.Writer [*`Writer`]] respectively.
For specialized applications, users may implement their own types which
meet the requirements. The examples included with this library provide a
Body implementation used to serve files in a HTTP server.
[endsect]
[endsect]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 KiB

After

Width:  |  Height:  |  Size: 145 KiB

View File

@ -8,6 +8,7 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
--> -->
<section id="index"> <section id="beast.index">
<title>Index</title>
<index/> <index/>
</section> </section>

View File

@ -8,7 +8,7 @@
[library Beast [library Beast
[quickbook 1.6] [quickbook 1.6]
[copyright 2013 - 2016 Vinnie Falco] [copyright 2013 - 2016 Vinnie Falco]
[purpose C++ Library] [purpose Networking Protocol Library]
[license [license
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at (See accompanying file LICENSE_1_0.txt or copy at
@ -22,174 +22,75 @@
[template mdash[] '''&mdash; '''] [template mdash[] '''&mdash; ''']
[template indexterm1[term1] '''<indexterm><primary>'''[term1]'''</primary></indexterm>'''] [template indexterm1[term1] '''<indexterm><primary>'''[term1]'''</primary></indexterm>''']
[template indexterm2[term1 term2] '''<indexterm><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></indexterm>'''] [template indexterm2[term1 term2] '''<indexterm><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></indexterm>''']
[def __POSIX__ /POSIX/]
[def __Windows__ /Windows/]
[def __accept__ [@http://www.opengroup.org/onlinepubs/000095399/functions/accept.html `accept()`]]
[def __connect__ [@http://www.opengroup.org/onlinepubs/000095399/functions/connect.html `connect()`]]
[def __getpeername__ [@http://www.opengroup.org/onlinepubs/000095399/functions/getpeername.html `getpeername()`]]
[def __getsockname__ [@http://www.opengroup.org/onlinepubs/000095399/functions/getsockname.html `getsockname()`]]
[def __getsockopt__ [@http://www.opengroup.org/onlinepubs/000095399/functions/getsockopt.html `getsockopt()`]]
[def __ioctl__ [@http://www.opengroup.org/onlinepubs/000095399/functions/ioctl.html `ioctl()`]]
[def __recvfrom__ [@http://www.opengroup.org/onlinepubs/000095399/functions/recvfrom.html `recvfrom()`]]
[def __sendto__ [@http://www.opengroup.org/onlinepubs/000095399/functions/sendto.html `sendto()`]]
[def __setsockopt__ [@http://www.opengroup.org/onlinepubs/000095399/functions/setsockopt.html `setsockopt()`]]
[def __socket__ [@http://www.opengroup.org/onlinepubs/000095399/functions/socket.html `socket()`]]
[def __asio_handler_invoke__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asio_handler_invoke.html `asio_handler_invoke`]]
[def __asio_handler_allocate__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asio_handler_allocate.html `asio_handler_allocate`]]
[def __AsyncReadStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/AsyncReadStream.html [*AsyncReadStream]]]
[def __AsyncWriteStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/AsyncWriteStream.html [*AsyncWriteStream]]]
[def __Body__ [link beast.ref.Body [*`Body`]]]
[def __CompletionHandler__ [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/CompletionHandler.html [*CompletionHandler]]]
[def __ConstBufferSequence__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*`ConstBufferSequence`]]]
[def __DynamicBuffer__ [link beast.ref.DynamicBuffer [*`DynamicBuffer`]]]
[def __FieldSequence__ [link beast.ref.FieldSequence [*`FieldSequence`]]]
[def __message__ [link beast.ref.http__message `message`]]
[def __message_v1__ [link beast.ref.http__message_v1 `message_v1`]]
[def __MutableBufferSequence [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*MutableBufferSequence]]]
[def __rfc6455__ [@https://tools.ietf.org/html/rfc6455 rfc6455]]
[def __rfc7230__ [@https://tools.ietf.org/html/rfc7230 rfc7230]]
[def __streambuf__ [link beast.ref.streambuf `streambuf`]]
[def __SyncReadStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/SyncReadStream.html [*SyncReadStream]]]
[def __SyncWriteStream__ [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncWriteStream.html [*SyncWriteStream]]]
[def __void_or_deduced__ [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.return_type_of_an_initiating_function ['void-or-deduced]]]
Beast is a cross-platform, header-only C++ library built on Boost.Asio that
provides implementations of the HTTP and WebSocket protocols.
[section:intro Introduction] [variablelist
[[
Beast is a header-only, cross-platform C++ library built on Boost.Asio and [link beast.overview Overview]
Boost, containing two modules implementing widely used network protocols. ][
Beast.HTTP offers a universal model for describing, sending, and receiving An overview of features, requirements, and credits, plus
HTTP messages while Beast.WebSocket provides a complete implementation of rationale and design information.
the WebSocket protocol. Their design achieves these goals: ]]
[[
* [*Symmetry.] Interfaces are role-agnostic; the same interfaces can be [link beast.http Using HTTP]
used to build clients, servers, or both. ][
How to use Beast's HTTP interfaces in your applications.
* [*Ease of Use.] HTTP messages are modeled using simple, readily ]]
accessible objects. Functions and classes used to send and receive HTTP [[
or WebSocket messages are designed to resemble Boost.Asio as closely as [link beast.websocket Using WebSocket]
possible. Users familiar with Boost.Asio will be immediately comfortable ][
using this library. How to use Beast's WebSocket interfaces in your applications.
]]
* [*Flexibility.] Interfaces do not mandate specific implementation [[
strategies; important decisions such as buffer or thread management are [link beast.example Examples]
left to users of the library. ][
Examples that illustrate the use of Beast in more complex applications.
* [*Performance.] The implementation performs competitively, making it a ]]
realistic choice for building high performance network servers. [[
[link beast.quickref Reference]
* [*Scalability.] Development of network applications that scale to thousands ][
of concurrent connections is possible with the implementation. Detailed class and function reference.
]]
* [*Basis for further abstraction.] The interfaces facilitate the [[
development of other libraries that provide higher levels of abstraction. [link beast.index Index]
][
Book-style text index of Beast documentation.
]]
[section:requirements Requirements] ]
Beast requires:
* [*C++11.] A minimum of C++11 is needed.
* [*Boost.] Beast is built on Boost, especially Boost.Asio.
* [*OpenSSL.] If using TLS/Secure sockets (optional).
[note Tested compilers: msvc-14+, gcc 5+, clang 3.6+]
The library is [*header-only]. It is not necessary to add any .cpp files,
or to edit your existing build script or project file except to provide
that the include/ directory for beast is searched for include files.
[endsect]
[section:example Examples]
These usage examples are intended to quickly impress upon readers the
flavor of the library. They are complete programs which may be built
and run. Source code and build scripts for these programs may be found
in the examples directory.
Use HTTP to request the root page from a website and print the response:
```
#include <beast/http.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <string>
int main()
{
// Normal boost::asio setup
std::string const host = "boost.org";
boost::asio::io_service ios;
boost::asio::ip::tcp::resolver r{ios};
boost::asio::ip::tcp::socket sock{ios};
boost::asio::connect(sock,
r.resolve(boost::asio::ip::tcp::resolver::query{host, "http"}));
// Send HTTP request using beast
beast::http::request_v1<beast::http::empty_body> req;
req.method = "GET";
req.url = "/";
req.version = 11;
req.headers.replace("Host", host + ":" + std::to_string(sock.remote_endpoint().port()));
req.headers.replace("User-Agent", "Beast");
beast::http::prepare(req);
beast::http::write(sock, req);
// Receive and print HTTP response using beast
beast::streambuf sb;
beast::http::response_v1<beast::http::streambuf_body> resp;
beast::http::read(sock, sb, resp);
std::cout << resp;
}
```
Establish a WebSocket connection, send a message and receive the reply:
```
#include <beast/core/to_string.hpp>
#include <beast/websocket.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <string>
int main()
{
// Normal boost::asio setup
std::string const host = "echo.websocket.org";
boost::asio::io_service ios;
boost::asio::ip::tcp::resolver r{ios};
boost::asio::ip::tcp::socket sock{ios};
boost::asio::connect(sock,
r.resolve(boost::asio::ip::tcp::resolver::query{host, "80"}));
// WebSocket connect and send message using beast
beast::websocket::stream<boost::asio::ip::tcp::socket&> ws{sock};
ws.handshake(host, "/");
ws.write(boost::asio::buffer("Hello, world!"));
// Receive WebSocket message, print and close using beast
beast::streambuf sb;
beast::websocket::opcode op;
ws.read(op, sb);
ws.close(beast::websocket::close_code::normal);
std::cout << to_string(sb.data()) << "\n";
}
```
[endsect]
[section:credits Credits]
Boost.Asio is the inspiration behind which all of the interfaces and
implementation strategies are built. Some parts of the documentation are
written to closely resemble the wording and presentation of Boost.Asio
documentation. Credit goes to Christopher Kohloff for the wonderful
Asio library and the ideas upon which Beast is built.
Beast would not be possible without the considerable time and patience
contributed by David Schwartz, Edward Hennis, Howard Hinnant, Miguel Portilla,
Nikolaos Bougalis, Scott Determan, Scott Schurr, and Ripple Labs for
supporting its development.
[endsect]
[endsect]
[include overview.qbk]
[include http.qbk] [include http.qbk]
[include websocket.qbk] [include websocket.qbk]
[include examples.qbk]
[section:types Type Requirements] [include design.qbk]
[section:quickref Reference]
[xinclude quickref.xml]
[endsect]
[section:ref Reference]
[include types/Body.qbk] [include types/Body.qbk]
[include types/BufferSequence.qbk] [include types/BufferSequence.qbk]
[include types/DynamicBuffer.qbk] [include types/DynamicBuffer.qbk]
@ -199,13 +100,7 @@ supporting its development.
[include types/Reader.qbk] [include types/Reader.qbk]
[include types/Streams.qbk] [include types/Streams.qbk]
[include types/Writer.qbk] [include types/Writer.qbk]
[include reference.qbk]
[endsect] [endsect]
[include design.qbk]
[section:quickref Quick Reference]
[xinclude quickref.xml]
[endsect]
[include reference.qbk]
[section:idx Index]
[xinclude index.xml] [xinclude index.xml]
[endsect]

114
doc/overview.qbk Normal file
View File

@ -0,0 +1,114 @@
[/
Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]
[section:overview Introduction]
Beast is a header-only, cross-platform C++ library built on Boost.Asio and
parts of Boost, containing two modules implementing widely used network
protocols. Beast offers a universal HTTP message model, plus algorithms for
parsing and serializing HTTP/1 messages. Beast.WebSocket provides a complete
implementation of the WebSocket protocol. Their design achieves these goals:
* [*Symmetry.] Interfaces are role-agnostic; the same interfaces can be
used to build clients, servers, or both.
* [*Ease of Use.] HTTP messages are modeled using simple, readily
accessible objects. Functions and classes used to send and receive HTTP
or WebSocket messages are designed to resemble Boost.Asio as closely as
possible. Users familiar with Boost.Asio will be immediately comfortable
using this library.
* [*Flexibility.] Interfaces do not mandate specific implementation
strategies; important decisions such as buffer or thread management are
left to users of the library.
* [*Performance.] The implementation performs competitively, making it a
realistic choice for building high performance network servers.
* [*Scalability.] Development of network applications that scale to thousands
of concurrent connections is possible with the implementation.
* [*Basis for further abstraction.] The interfaces facilitate the
development of other libraries that provide higher levels of abstraction.
The HTTP portion of Beast is designed to be a low-level building block for
creating higher level libraries. It implements only the HTTP protocol, and
does not handle domain specific features (for example: cookies, redirects, or
deflate content encodings).
[heading Requirements]
Beast requires:
* [*C++11.] A minimum of C++11 is needed.
* [*Boost.] Beast is built on Boost, especially Boost.Asio.
* [*OpenSSL.] If using TLS/Secure sockets (optional).
[note Tested compilers: msvc-14+, gcc 5+, clang 3.6+]
The library is [*header-only]. It is not necessary to add any .cpp files,
or to add commands to your build script for building Beast. To link your
program successfully, you'll need to add the Boost.System library to link
with. If you use coroutines you'll also need the Boost.Coroutine library.
Please visit the Boost documentation for instructions on how to do this for
your particular build system.
[heading Motivation]
Beast is built on Boost.Asio A proposal to add networking functionality to the
C++ standard library, based on Boost.Asio, is under consideration by the
committee and on track for standardization. Since the final approved networking
interface for the C++ standard library will likely closely resemble the current
interface of Boost.Asio, the choice of Boost.Asio as the network transport
layer is prudent.
The HTTP protocol is pervasive in network applications. As C++ is a logical
choice for high performance network servers, there is great utility in solid
building blocks for manipulating, sending, and receiving HTTP messages
compliant with the Hypertext Transfer Protocol and the supplements that
follow. Unfortunately reliable implementations or industry standards do not
exist in C++. The development of higher level libraries is stymied by the
lack of a common set of low-level algorithms and types for interacting with
the HTTP protocol.
Today's web applications increasingly rely on alternatives to standard HTTP
to achieve performance and/or responsiveness. While WebSocket implementations
are widely available in common web development languages such as Javascript,
good implementations in C++ are scarce. A survey of existing C++ WebSocket
solutions reveals interfaces which lack symmetry, impose performance penalties,
and needlessly restrict implementation strategies.
Beast.WebSocket takes advantage of Boost.Asio's extensible asynchronous
model, handler allocation, and handler invocation hooks. Calls to
Beast.WebSocket asynchronous initiation functions allow callers the choice
of using a completion handler, stackful or stackless coroutines, futures,
or user defined customizations (for example, Boost.Fiber). The
implementation uses handler invocation hooks (__asio_handler_invoke__),
providing execution guarantees on composed operations in a manner identical
to Boost.Asio. The implementation also uses handler allocation hooks
(__asio_handler_allocate__) when allocating memory internally for composed
operations.
There is no need for inheritance or virtual members in a
[link beast.ref.websocket__stream `websocket::stream`].
All operations are templated and transparent to the compiler, allowing for
maximum inlining and optimization.
[heading Credits]
Boost.Asio is the inspiration behind which all of the interfaces and
implementation strategies are built. Some parts of the documentation are
written to closely resemble the wording and presentation of Boost.Asio
documentation. Credit goes to Christopher Kohloff for the wonderful
Asio library and the ideas upon which Beast is built.
Beast would not be possible without the considerable time and patience
contributed by David Schwartz, Edward Hennis, Howard Hinnant, Miguel Portilla,
Nikolaos Bougalis, Scott Determan, Scott Schurr, and Ripple Labs for
supporting its development.
[endsect]

View File

@ -71,12 +71,12 @@
</simplelist> </simplelist>
<bridgehead renderas="sect3">Concepts</bridgehead> <bridgehead renderas="sect3">Concepts</bridgehead>
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">
<member><link linkend="beast.types.Body">Body</link></member> <member><link linkend="beast.ref.Body">Body</link></member>
<member><link linkend="beast.types.Field">Field</link></member> <member><link linkend="beast.ref.Field">Field</link></member>
<member><link linkend="beast.types.FieldSequence">FieldSequence</link></member> <member><link linkend="beast.ref.FieldSequence">FieldSequence</link></member>
<member><link linkend="beast.types.Parser">Parser</link></member> <member><link linkend="beast.ref.Parser">Parser</link></member>
<member><link linkend="beast.types.Reader">Reader</link></member> <member><link linkend="beast.ref.Reader">Reader</link></member>
<member><link linkend="beast.types.Writer">Writer</link></member> <member><link linkend="beast.ref.Writer">Writer</link></member>
</simplelist> </simplelist>
</entry> </entry>
<entry valign="top"> <entry valign="top">
@ -181,11 +181,11 @@
<entry valign="top"> <entry valign="top">
<bridgehead renderas="sect3">Concepts</bridgehead> <bridgehead renderas="sect3">Concepts</bridgehead>
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">
<member><link linkend="beast.types.streams.AsyncStream">AsyncStream</link></member> <member><link linkend="beast.ref.streams.AsyncStream">AsyncStream</link></member>
<member><link linkend="beast.types.BufferSequence">BufferSequence</link></member> <member><link linkend="beast.ref.BufferSequence">BufferSequence</link></member>
<member><link linkend="beast.types.DynamicBuffer">DynamicBuffer</link></member> <member><link linkend="beast.ref.DynamicBuffer">DynamicBuffer</link></member>
<member><link linkend="beast.types.streams.Stream">Stream</link></member> <member><link linkend="beast.ref.streams.Stream">Stream</link></member>
<member><link linkend="beast.types.streams.SyncStream">SyncStream</link></member> <member><link linkend="beast.ref.streams.SyncStream">SyncStream</link></member>
</simplelist> </simplelist>
</entry> </entry>
</row> </row>

View File

@ -31,8 +31,6 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:ref Reference]
</xsl:text> </xsl:text>
<xsl:for-each select=" <xsl:for-each select="
compounddef[@kind = 'class' or @kind = 'struct'] | compounddef[@kind = 'class' or @kind = 'struct'] |
@ -59,7 +57,6 @@
</xsl:otherwise> </xsl:otherwise>
</xsl:choose> </xsl:choose>
</xsl:for-each> </xsl:for-each>
<xsl:text>&#xd;[endsect]</xsl:text>
</xsl:template> </xsl:template>
<!--========== Utilities ==========--> <!--========== Utilities ==========-->
@ -165,7 +162,7 @@
<xsl:text>``['implementation-defined]``</xsl:text> <xsl:text>``['implementation-defined]``</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="$type='void_or_deduced'"> <xsl:when test="$type='void_or_deduced'">
<xsl:text>``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.return_type_of_an_initiating_function ['void-or-deduced]]``</xsl:text> <xsl:text>__void_or_deduced__</xsl:text>
</xsl:when> </xsl:when>
<xsl:otherwise> <xsl:otherwise>
<xsl:value-of select="$type"/> <xsl:value-of select="$type"/>
@ -1528,47 +1525,50 @@
<xsl:text> </xsl:text> <xsl:text> </xsl:text>
<xsl:choose> <xsl:choose>
<xsl:when test="type = 'class AsyncStream'"> <xsl:when test="type = 'class AsyncStream'">
<xsl:text>class ``[link beast.types.streams.AsyncStream [*AsyncStream]]``</xsl:text> <xsl:text>class ``[link beast.ref.streams.AsyncStream [*AsyncStream]]``</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="type = 'class AsyncReadStream'"> <xsl:when test="type = 'class AsyncReadStream'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncReadStream.html [*AsyncReadStream]]``</xsl:text> <xsl:text>class __AsyncReadStream__</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="type = 'class AsyncWriteStream'"> <xsl:when test="type = 'class AsyncWriteStream'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncWriteStream.html [*AsyncWriteStream]]``</xsl:text> <xsl:text>class __AsyncWriteStream__</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="type = 'class Body'"> <xsl:when test="type = 'class Body'">
<xsl:text>class ``[link beast.types.Body [*Body]]``</xsl:text> <xsl:text>class ``[link beast.ref.Body [*Body]]``</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="type = 'class BufferSequence'"> <xsl:when test="type = 'class BufferSequence'">
<xsl:text>class ``[link beast.types.BufferSequence [*BufferSequence]]``</xsl:text> <xsl:text>class ``[link beast.ref.BufferSequence [*BufferSequence]]``</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="(type = 'class' or type = 'class...') and declname = 'BufferSequence'"> <xsl:when test="(type = 'class' or type = 'class...') and declname = 'BufferSequence'">
<xsl:value-of select="type"/> <xsl:value-of select="type"/>
<xsl:text> ``[link beast.types.BufferSequence [*BufferSequence]]``</xsl:text> <xsl:text> ``[link beast.ref.BufferSequence [*BufferSequence]]``</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="declname = 'CompletionHandler' or type = 'class CompletionHandler'"> <xsl:when test="declname = 'CompletionHandler' or type = 'class CompletionHandler'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/CompletionHandler.html [*CompletionHandler]]``</xsl:text> <xsl:text>class __CompletionHandler__</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="declname = 'ConstBufferSequence' or type = 'class ConstBufferSequence'"> <xsl:when test="declname = 'ConstBufferSequence' or type = 'class ConstBufferSequence'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*ConstBufferSequence]]``</xsl:text> <xsl:text>class __ConstBufferSequence__</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="declname = 'DynamicBuffer' or type = 'class DynamicBuffer'"> <xsl:when test="declname = 'DynamicBuffer' or type = 'class DynamicBuffer'">
<xsl:text>class ``[link beast.types.DynamicBuffer [*DynamicBuffer]]``</xsl:text> <xsl:text>class ``[link beast.ref.DynamicBuffer [*DynamicBuffer]]``</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="declname = 'MutableBufferSequence' or type = 'class MutableBufferSequence'"> <xsl:when test="declname = 'MutableBufferSequence' or type = 'class MutableBufferSequence'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*MutableBufferSequence]]``</xsl:text> <xsl:text>class __MutableBufferSequence__</xsl:text>
</xsl:when>
<xsl:when test="declname = 'Parser' or type = 'class Parser'">
<xsl:text>class ``[link beast.ref.Parser [*Parser]]``</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="declname = 'Stream' or type = 'class Stream'"> <xsl:when test="declname = 'Stream' or type = 'class Stream'">
<xsl:text>class ``[link beast.types.streams.Stream [*Stream]]``</xsl:text> <xsl:text>class ``[link beast.ref.streams.Stream [*Stream]]``</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="type = 'class SyncStream'"> <xsl:when test="type = 'class SyncStream'">
<xsl:text>class ``[link beast.types.streams.SyncStream [*SyncStream]]``</xsl:text> <xsl:text>class ``[link beast.ref.streams.SyncStream [*SyncStream]]``</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="declname = 'SyncReadStream' or type = 'class SyncReadStream'"> <xsl:when test="declname = 'SyncReadStream' or type = 'class SyncReadStream'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncReadStream.html [*SyncReadStream]]``</xsl:text> <xsl:text>class __SyncReadStream__</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="declname = 'SyncWriteStream' or type = 'class SyncWriteStream'"> <xsl:when test="declname = 'SyncWriteStream' or type = 'class SyncWriteStream'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncWriteStream.html [*SyncWriteStream]]``</xsl:text> <xsl:text>class __SyncWriteStream__</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="declname = 'T'"> <xsl:when test="declname = 'T'">

View File

@ -109,51 +109,6 @@ INPUT = \
../include/beast/websocket \ ../include/beast/websocket \
../include/beast/doc_debug.hpp \ ../include/beast/doc_debug.hpp \
../include/beast/async_completion.hpp \
../include/beast/basic_streambuf.hpp \
../include/beast/bind_handler.hpp \
../include/beast/buffer_cat.hpp \
../include/beast/buffers_adapter.hpp \
../include/beast/consuming_buffers.hpp \
../include/beast/handler_alloc.hpp \
../include/beast/http.hpp \
../include/beast/placeholders.hpp \
../include/beast/prepare_buffers.hpp \
../include/beast/static_streambuf.hpp \
../include/beast/streambuf.hpp \
../include/beast/streambuf_readstream.hpp \
../include/beast/to_string.hpp \
../include/beast/type_check.hpp \
../include/beast/websocket.hpp \
../include/beast/write_streambuf.hpp \
../include/beast/http/basic_headers.hpp \
../include/beast/http/basic_parser_v1.hpp \
../include/beast/http/body_writer.hpp \
../include/beast/http/chunk_encode.hpp \
../include/beast/http/empty_body.hpp \
../include/beast/http/error.hpp \
../include/beast/http/fields.hpp \
../include/beast/http/headers.hpp \
../include/beast/http/message.hpp \
../include/beast/http/message_v1.hpp \
../include/beast/http/method.hpp \
../include/beast/http/parse_error.hpp \
../include/beast/http/parser.hpp \
../include/beast/http/read.hpp \
../include/beast/http/resume_context.hpp \
../include/beast/http/rfc2616.hpp \
../include/beast/http/streambuf_body.hpp \
../include/beast/http/string_body.hpp \
../include/beast/http/type_check.hpp \
../include/beast/http/write.hpp \
../include/beast/websocket/error.hpp \
../include/beast/websocket/option.hpp \
../include/beast/websocket/rfc6455.hpp \
../include/beast/websocket/ssl.hpp \
../include/beast/websocket/static_string.hpp \
../include/beast/websocket/stream.hpp \
../include/beast/websocket/teardown.hpp \
INPUT_ENCODING = UTF-8 INPUT_ENCODING = UTF-8
FILE_PATTERNS = FILE_PATTERNS =
RECURSIVE = NO RECURSIVE = NO

View File

@ -5,7 +5,11 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:Body Body] [section:Body Body requirements]
A [*Body] type is supplied as a template argument to the __message__ class. It
controls both the type of the data member of the resulting message object, and
the algorithms used during parsing and serialization.
In this table: In this table:
@ -22,17 +26,12 @@ In this table:
will be not movable or not copyable. will be not movable or not copyable.
] ]
] ]
[
[`X:value_type{}`]
[]
[`DefaultConstructible`]
]
[ [
[`Body::reader`] [`Body::reader`]
[] []
[ [
If present, a type meeting the requirements of If present, a type meeting the requirements of
[link beast.types.Reader [*`Reader`]]. [link beast.ref.Reader [*`Reader`]].
Provides an implementation to parse the body. Provides an implementation to parse the body.
] ]
] ]
@ -41,7 +40,7 @@ In this table:
[] []
[ [
If present, a type meeting the requirements of If present, a type meeting the requirements of
[link beast.types.Writer [*`Writer`]]. [link beast.ref.Writer [*`Writer`]].
Provides an implementation to serialize the body. Provides an implementation to serialize the body.
] ]
] ]

View File

@ -5,7 +5,7 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:BufferSequence BufferSequence] [section:BufferSequence BufferSequence requirements]
A `BufferSequence` is a type meeting either of the following requirements: A `BufferSequence` is a type meeting either of the following requirements:

View File

@ -5,7 +5,7 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:DynamicBuffer DynamicBuffer] [section:DynamicBuffer DynamicBuffer requirements]
A dynamic buffer encapsulates memory storage that may be automatically resized A dynamic buffer encapsulates memory storage that may be automatically resized
as required, where the memory is divided into an input sequence followed by an as required, where the memory is divided into an input sequence followed by an
@ -27,7 +27,7 @@ implementation strategies:
* A sequence of one or more octet arrays of varying sizes. Additional octet * A sequence of one or more octet arrays of varying sizes. Additional octet
array objects are appended to the sequence to accommodate changes in the array objects are appended to the sequence to accommodate changes in the
size of the character sequence. This is the implementation approached size of the character sequence. This is the implementation approach
currently offered by [link beast.ref.basic_streambuf `basic_streambuf`]. currently offered by [link beast.ref.basic_streambuf `basic_streambuf`].
In the table below: In the table below:
@ -88,7 +88,7 @@ In the table below:
] ]
[ [
[`a.prepare(n)`] [`a.prepare(n)`]
[`X:mutable_buffers_type`] [`X::mutable_buffers_type`]
[ [
Returns a mutable buffer sequence u representing the output sequence, Returns a mutable buffer sequence u representing the output sequence,
and where `buffer_size(u) == n`. The dynamic buffer reallocates memory and where `buffer_size(u) == n`. The dynamic buffer reallocates memory

View File

@ -5,7 +5,7 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:Field Field] [section:Field Field requirements]
A [*`Field`] represents a single HTTP header field/value pair. A [*`Field`] represents a single HTTP header field/value pair.

View File

@ -5,10 +5,11 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:FieldSequence FieldSequence] [section:FieldSequence FieldSequence requirements]
A [*`FieldSequence`] is an iterable container whose value type meets A [*`FieldSequence`] is an iterable container whose value type meets
the requirements of [link beast.types.Field [*`Field`]]. the requirements of [link beast.ref.Field [*`Field`]]. Objects meeting
these requirements are serializable.
In this table: In this table:

View File

@ -5,9 +5,9 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:Parser Parser] [section:Parser Parser requirements]
A [*`Parser`] is used to deserialize HTTP/1 messages from [link beast.types.streams streams]. A [*`Parser`] is used to deserialize HTTP/1 messages from [link beast.ref.streams streams].
Objects of this type are used with [link beast.ref.http__parse http::parse] and Objects of this type are used with [link beast.ref.http__parse http::parse] and
[link beast.ref.http__async_parse http::async_parse]. [link beast.ref.http__async_parse http::async_parse].
@ -17,7 +17,7 @@ In this table:
* `a` denotes a value of type `X`. * `a` denotes a value of type `X`.
* `b` is a value meeting the requirements of [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/ConvertibleToConstBuffer.html [*`ConvertibleToConstBuffer`]]. * `b` is a value meeting the requirements of [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*`ConstBufferSequence`]].
* `ec` is a value of type [link beast.ref.error_code `error_code&`]. * `ec` is a value of type [link beast.ref.error_code `error_code&`].
@ -34,11 +34,11 @@ In this table:
[`a.write(b, ec)`] [`a.write(b, ec)`]
[`std::size_t`] [`std::size_t`]
[ [
Parses the octets in the specified input buffer sequentially until Sequentially parses the octets in the specified input buffer or input
an error occurs, the end of the buffer is reached, or a complete buffer sequence until an error occurs, the end of the buffer is reached,
HTTP/1 message has been parsed. If an error occurs, `ec` is set or a complete HTTP/1 message has been parsed. If an error occurs, `ec`
to the error code and parsing stops. This function returns the is set to the error code and parsing stops. Upon success, this function
number of bytes consumed from the input buffer. returns the number of bytes used from the input.
] ]
] ]
[ [

View File

@ -5,7 +5,7 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:Reader Reader] [section:Reader Reader requirements]
Parser implementations will construct the corresponding `reader` object Parser implementations will construct the corresponding `reader` object
during the parse. This customization point allows the Body to determine during the parse. This customization point allows the Body to determine

View File

@ -5,7 +5,7 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:streams Streams] [section:streams Streams requirements]
Stream types represent objects capable of performing synchronous or Stream types represent objects capable of performing synchronous or
asynchronous I/O. They are based on concepts from `boost::asio`. asynchronous I/O. They are based on concepts from `boost::asio`.

View File

@ -5,7 +5,7 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:Writer Writer] [section:Writer Writer requirements]
A `Writer` serializes the message body. The implementation creates an instance A `Writer` serializes the message body. The implementation creates an instance
of this type when serializing a message, and calls into it zero or more times of this type when serializing a message, and calls into it zero or more times

View File

@ -7,6 +7,22 @@
[section:websocket WebSocket] [section:websocket WebSocket]
[block '''
<informaltable frame="all"><tgroup cols="1"><colspec colname="a"/><tbody><row><entry valign="top"><simplelist>
<member><link linkend="beast.websocket.creation">Creation</link></member>
<member><link linkend="beast.websocket.connections">Making connections</link></member>
<member><link linkend="beast.websocket.handshaking">Handshaking</link></member>
<member><link linkend="beast.websocket.messages">Messages</link></member>
<member><link linkend="beast.websocket.frames">Frames</link></member>
<member><link linkend="beast.websocket.controlframes">Control frames</link></member>
<member><link linkend="beast.websocket.pongs">Pong messages</link></member>
<member><link linkend="beast.websocket.buffers">Buffers</link></member>
<member><link linkend="beast.websocket.async">Asynchronous interface</link></member>
<member><link linkend="beast.websocket.io_service">The io_service</link></member>
<member><link linkend="beast.websocket.threads">Thread Safety</link></member>
</simplelist></entry></row></tbody></tgroup></informaltable>
''']
The WebSocket Protocol enables two-way communication between a client The WebSocket Protocol enables two-way communication between a client
running untrusted code in a controlled environment to a remote host that has running untrusted code in a controlled environment to a remote host that has
opted-in to communications from that code. The protocol consists of an opening opted-in to communications from that code. The protocol consists of an opening
@ -22,48 +38,12 @@ C++ approach.
The WebSocket protocol is described fully in The WebSocket protocol is described fully in
[@https://tools.ietf.org/html/rfc6455 rfc6455] [@https://tools.ietf.org/html/rfc6455 rfc6455]
[note
The following documentation assumes familiarity with both
Boost.Asio and the WebSocket protocol specification described in __rfc6455__.
]
[section:motivation Motivation]
Today's web applications increasingly rely on alternatives to standard HTTP
to achieve performance and/or responsiveness. While WebSocket implementations
are widely available in common web development languages such as Javascript,
good implementations in C++ are scarce. A survey of existing C++ WebSocket
solutions reveals interfaces which lack symmetry, impose performance penalties,
and needlessly restrict implementation strategies.
Beast.WebSocket is built on Boost.Asio, a robust cross platform networking
framework that is part of Boost and also offered as a standalone library.
A proposal to add networking functionality to the C++ standard library,
based on Boost.Asio, is under consideration by the standards committee.
Since the final approved networking interface for the C++ standard library
will likely closely resemble the current interface of Boost.Asio, it is
logical for Beast.WebSocket to use Boost.Asio as its network transport.
Beast.WebSocket takes advantage of Boost.Asio's extensible asynchronous
model, handler allocation, and handler invocation hooks. Calls to
Beast.WebSocket asynchronous initiation functions allow callers the choice
of using a completion handler, stackful or stackless coroutines, futures,
or user defined customizations (for example, Boost.Fiber). The
implementation uses handler invocation hooks
([@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asio_handler_invoke.html `asio_handler_invoke`]),
providing execution guarantees on composed operations in a manner
identical to Boost.Asio. The implementation also uses handler allocation hooks
([@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asio_handler_allocate.html `asio_handler_allocate`])
when allocating memory internally for composed operations.
There is no need for inheritance or virtual members in a
[link beast.ref.websocket__stream `beast::websocket::stream`].
All operations are templated and transparent to the compiler, allowing for
maximum inlining and optimization.
[note The documentation which follows assumes familiarity with
both Boost.Asio and the WebSocket protocol specification described in
[@https://tools.ietf.org/html/rfc6455 rfc6455] ]
[endsect]
[section:creation Creation] [section:creation Creation]
@ -71,15 +51,15 @@ both Boost.Asio and the WebSocket protocol specification described in
The interface to Beast's WebSocket implementation is a single template The interface to Beast's WebSocket implementation is a single template
class [link beast.ref.websocket__stream `beast::websocket::stream`] which class [link beast.ref.websocket__stream `beast::websocket::stream`] which
wraps a "next layer" object. The next layer object must meet the requirements wraps a "next layer" object. The next layer object must meet the requirements
of [link beast.types.streams.SyncStream [*`SyncReadStream`]] if synchronous of [link beast.ref.streams.SyncStream [*`SyncReadStream`]] if synchronous
operations are performed, or operations are performed, or
[link beast.types.streams.AsyncStream [*`AsyncStream`]] if asynchronous [link beast.ref.streams.AsyncStream [*`AsyncStream`]] if asynchronous
operations are performed, or both. Arguments supplied during construction are operations are performed, or both. Arguments supplied during construction are
passed to next layer's constructor. Here we declare a websocket stream over passed to next layer's constructor. Here we declare a websocket stream over
a TCP/IP socket with ownership of the socket: a TCP/IP socket with ownership of the socket:
``` ```
boost::asio::io_service ios; boost::asio::io_service ios;
beast::websocket::stream<boost::asio::ip::tcp::socket> ws(ios); beast::websocket::stream<boost::asio::ip::tcp::socket> ws{ios};
``` ```
[heading Using SSL] [heading Using SSL]
@ -92,8 +72,8 @@ argument when constructing the stream.
#include <boost/asio/ssl.hpp> #include <boost/asio/ssl.hpp>
boost::asio::io_service ios; boost::asio::io_service ios;
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23};
beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ws(ios, ctx); beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ws{ios, ctx};
``` ```
[note [note
@ -108,7 +88,7 @@ to wrap an object that already exists. This socket can be moved in:
``` ```
boost::asio::ip::tcp::socket&& sock; boost::asio::ip::tcp::socket&& sock;
... ...
beast::websocket::stream<boost::asio::ip::tcp::socket> ws(std::move(sock)); beast::websocket::stream<boost::asio::ip::tcp::socket> ws{std::move(sock)};
``` ```
Or, the wrapper can be constructed with a non-owning reference. In Or, the wrapper can be constructed with a non-owning reference. In
@ -117,35 +97,37 @@ underlying socket being wrapped:
``` ```
boost::asio::ip::tcp::socket sock; boost::asio::ip::tcp::socket sock;
... ...
beast::websocket::stream<boost::asio::ip::tcp::socket&> ws(sock); beast::websocket::stream<boost::asio::ip::tcp::socket&> ws{sock};
``` ```
The layer being wrapped can be accessed through the websocket's "next layer", The layer being wrapped can be accessed through the websocket's "next layer",
permitting callers to interact directly with its interface. permitting callers to interact directly with its interface.
``` ```
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23};
beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> ws(ios, ctx); beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> ws{ios, ctx};
... ...
ws.next_layer().shutdown(); // ssl::stream shutdown ws.next_layer().shutdown(); // ssl::stream shutdown
``` ```
[important Initiating read and write operations on the next layer while [warning
websocket operations are being performed can break invariants, and Initiating read and write operations on the next layer while
result in undefined behavior. ] stream operations are being performed can break invariants, and
result in undefined behavior.
]
[endsect] [endsect]
[section:connecting Making connections] [section:connections Making connections]
Connections are established by using the interfaces which already exist Connections are established by using the interfaces which already exist
for the next layer. For example, making an outgoing connection: for the next layer. For example, making an outgoing connection:
``` ```
std::string const host = "mywebapp.com"; std::string const host = "mywebapp.com";
boost::asio::io_service ios; boost::asio::io_service ios;
boost::asio::ip::tcp::resolver r(ios); boost::asio::ip::tcp::resolver r{ios};
beast::websocket::stream<boost::asio::ip::tcp::socket> ws(ios); beast::websocket::stream<boost::asio::ip::tcp::socket> ws{ios};
boost::asio::connect(ws.next_layer(), boost::asio::connect(ws.next_layer(),
r.resolve(boost::asio::ip::tcp::resolver::query{host, "ws"})); r.resolve(boost::asio::ip::tcp::resolver::query{host, "ws"}));
``` ```
@ -154,12 +136,14 @@ Accepting an incoming connection:
``` ```
void do_accept(boost::asio::ip::tcp::acceptor& acceptor) void do_accept(boost::asio::ip::tcp::acceptor& acceptor)
{ {
beast::websocket::stream<boost::asio::ip::tcp::socket> ws(acceptor.get_io_service()); beast::websocket::stream<boost::asio::ip::tcp::socket> ws{acceptor.get_io_service()};
acceptor.accept(ws.next_layer()); acceptor.accept(ws.next_layer());
} }
``` ```
[note Examples use synchronous interfaces for clarity of exposition. ] [note
Examples use synchronous interfaces for clarity of exposition.
]
[endsect] [endsect]
@ -171,16 +155,17 @@ A WebSocket session begins when one side sends the HTTP Upgrade request
for websocket, and the other side sends an appropriate HTTP response for websocket, and the other side sends an appropriate HTTP response
indicating that the request was accepted and that the connection has indicating that the request was accepted and that the connection has
been upgraded. The HTTP Upgrade request must include the Host HTTP field, been upgraded. The HTTP Upgrade request must include the Host HTTP field,
and the URI of the resource to request. `handshake` is used to send the and the URI of the resource to request.
[link beast.ref.websocket__stream.handshake `handshake`] is used to send the
request with the required host and resource strings. request with the required host and resource strings.
``` ```
beast::websocket::stream<boost::asio::ip::tcp::socket> ws(ios); beast::websocket::stream<boost::asio::ip::tcp::socket> ws{ios};
... ...
ws.set_option(beast::websocket::keep_alive(true)); ws.set_option(beast::websocket::keep_alive(true));
ws.handshake("ws.example.com:80", "/cgi-bin/bitcoin-prices"); ws.handshake("ws.example.com:80", "/cgi-bin/bitcoin-prices");
``` ```
The [link beast.ref.websocket__stream `beast::websocket::stream`] automatically The [link beast.ref.websocket__stream `stream`] automatically
handles receiving and processing the HTTP response to the handshake request. handles receiving and processing the HTTP response to the handshake request.
The call to handshake is successful if a HTTP response is received with the The call to handshake is successful if a HTTP response is received with the
101 "Switching Protocols" status code. On failure, an error is returned or an 101 "Switching Protocols" status code. On failure, an error is returned or an
@ -190,7 +175,7 @@ open for a subsequent handshake attempt
Performing a handshake for an incoming websocket upgrade request operates Performing a handshake for an incoming websocket upgrade request operates
similarly. If the handshake fails, an error is returned or exception thrown: similarly. If the handshake fails, an error is returned or exception thrown:
``` ```
beast::websocket::stream<boost::asio::ip::tcp::socket> ws(ios); beast::websocket::stream<boost::asio::ip::tcp::socket> ws{ios};
... ...
ws.accept(); ws.accept();
``` ```
@ -205,7 +190,7 @@ void do_accept(boost::asio::ip::tcp::socket& sock)
boost::asio::streambuf sb; boost::asio::streambuf sb;
boost::asio::read_until(sock, sb, "\r\n\r\n"); boost::asio::read_until(sock, sb, "\r\n\r\n");
... ...
beast::websocket::stream<boost::asio::ip::tcp::socket&> ws(sock); beast::websocket::stream<boost::asio::ip::tcp::socket&> ws{sock};
ws.accept(sb.data()); ws.accept(sb.data());
... ...
} }
@ -218,10 +203,10 @@ void do_accept(boost::asio::ip::tcp::socket& sock)
{ {
boost::asio::streambuf sb; boost::asio::streambuf sb;
beast::http::request<http::empty_body> request; beast::http::request<http::empty_body> request;
beast::http::read(sock, request); beast::http::read(sock, sb, request);
if(beast::http::is_upgrade(request)) if(beast::http::is_upgrade(request))
{ {
websocket::stream<ip::tcp::socket&> ws(sock); websocket::stream<ip::tcp::socket&> ws{sock};
ws.accept(request); ws.accept(request);
... ...
} }
@ -244,15 +229,17 @@ void echo(beast::websocket::stream<boost::asio::ip::tcp::socket>& ws)
beast::websocket::opcode::value op; beast::websocket::opcode::value op;
ws.read(sb); ws.read(sb);
ws.set_option(beast::websocket::message_type(op)); ws.set_option(beast::websocket::message_type{op});
ws.write(sb.data()); ws.write(sb.data());
sb.consume(sb.size()); sb.consume(sb.size());
} }
``` ```
[important Calls to [link beast.ref.websocket__stream.set_option `set_option`] [important
must be made from the same implicit or explicit strand as that used to perform Calls to [link beast.ref.websocket__stream.set_option `set_option`]
other operations. ] must be made from the same implicit or explicit strand as that used
to perform other operations.
]
[endsect] [endsect]
@ -280,9 +267,9 @@ void echo(beast::websocket::stream<boost::asio::ip::tcp::socket>& ws)
if(fi.fin) if(fi.fin)
break; break;
} }
ws.set_option(beast::websocket::message_type(fi.op)); ws.set_option(beast::websocket::message_type{fi.op});
beast::consuming_buffers< beast::consuming_buffers<
beast::streambuf::const_buffers_type> cb(sb.data()); beast::streambuf::const_buffers_type> cb{sb.data()};
for(;;) for(;;)
{ {
using boost::asio::buffer_size; using boost::asio::buffer_size;
@ -321,7 +308,7 @@ of the frames making up the message. The automatic fragment size option
gives callers control over the size of these frames: gives callers control over the size of these frames:
``` ```
... ...
ws.set_option(beast::websocket::auto_fragment_size(8192)); ws.set_option(beast::websocket::auto_fragment_size{8192});
``` ```
The WebSocket protocol defines a procedure and control message for initiating The WebSocket protocol defines a procedure and control message for initiating
@ -342,9 +329,8 @@ error, a read operation is required. ]
[section:pongs Pong messages] [section:pongs Pong messages]
To receive pong control frames, callers may register a "pong callback" using To receive pong control frames, callers may register a "pong callback" using
[link beast.ref.websocket__stream.set_option `set_option`]: [link beast.ref.websocket__stream.set_option `set_option`]. The object provided
with this option should be callable with the following signature:
the following signature:
``` ```
void on_pong(ping_data const& payload); void on_pong(ping_data const& payload);
... ...
@ -373,7 +359,7 @@ handler of the corresponding read function.]
Because calls to read data may return a variable amount of bytes, the Because calls to read data may return a variable amount of bytes, the
interface to calls that read data require an object that meets the requirements interface to calls that read data require an object that meets the requirements
of [link beast.types.DynamicBuffer [*`DynamicBuffer`]]. This concept is modeled on of [link beast.ref.DynamicBuffer [*`DynamicBuffer`]]. This concept is modeled on
[@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/basic_streambuf.html `boost::asio::basic_streambuf`]. [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/basic_streambuf.html `boost::asio::basic_streambuf`].
The implementation does not perform queueing or buffering of messages. If The implementation does not perform queueing or buffering of messages. If
@ -429,7 +415,7 @@ use or require threads.
[section:safety Thread Safety] [section:threads Thread Safety]
Like a regular asio socket, a [link beast.ref.websocket__stream `stream`] is Like a regular asio socket, a [link beast.ref.websocket__stream `stream`] is
not thread safe. Callers are responsible for synchronizing operations on the not thread safe. Callers are responsible for synchronizing operations on the

View File

@ -71,9 +71,7 @@ template<class T>
struct is_Body struct is_Body
{ {
using type = std::integral_constant<bool, using type = std::integral_constant<bool,
has_value_type<T>::value && has_value_type<T>::value
std::is_default_constructible<
typename extract_value_type<T>::type>::value
>; >;
}; };
@ -92,7 +90,7 @@ class is_Parser
template<class U, class R = template<class U, class R =
std::is_convertible<decltype( std::is_convertible<decltype(
std::declval<U>().write( std::declval<U>().write(
std::declval<boost::asio::const_buffer const&>(), std::declval<boost::asio::const_buffers_1 const&>(),
std::declval<error_code&>())), std::declval<error_code&>())),
std::size_t>> std::size_t>>
static R check2(int); static R check2(int);

View File

@ -72,8 +72,8 @@ struct frame_info
For asynchronous operations, the type must support the For asynchronous operations, the type must support the
@b `AsyncStream` concept. @b `AsyncStream` concept.
@note A stream object must not be destroyed while there are @note A stream object must not be moved or destroyed while there
pending asynchronous operations associated with it. are pending asynchronous operations associated with it.
@par Concepts @par Concepts
@b `AsyncStream`, @b `AsyncStream`,
@ -1018,7 +1018,8 @@ public:
hold all the message payload bytes (which may be zero in length). hold all the message payload bytes (which may be zero in length).
Control frames encountered while reading frame or message data Control frames encountered while reading frame or message data
are handled automatically. Pings are replied to, pongs are noted, are handled automatically. Pings are replied to automatically,
pongs are routed to the pong callback if the option is set,
and close frames initiate the WebSocket close procedure. When a and close frames initiate the WebSocket close procedure. When a
close frame is received, this call will eventually return close frame is received, this call will eventually return
@ref error::closed. Because of the need to handle control frames, @ref error::closed. Because of the need to handle control frames,
@ -1053,7 +1054,8 @@ public:
hold all the message payload bytes (which may be zero in length). hold all the message payload bytes (which may be zero in length).
Control frames encountered while reading frame or message data Control frames encountered while reading frame or message data
are handled automatically. Pings are replied to, pongs are noted, are handled automatically. Pings are replied to automatically,
pongs are routed to the pong callback if the option is set,
and close frames initiate the WebSocket close procedure. When a and close frames initiate the WebSocket close procedure. When a
close frame is received, this call will eventually return close frame is received, this call will eventually return
@ref error::closed. Because of the need to handle control frames, @ref error::closed. Because of the need to handle control frames,
@ -1152,7 +1154,8 @@ public:
fi.fin == true, and zero bytes placed into the stream buffer. fi.fin == true, and zero bytes placed into the stream buffer.
Control frames encountered while reading frame or message data Control frames encountered while reading frame or message data
are handled automatically. Pings are replied to, pongs are noted, are handled automatically. Pings are replied to automatically,
pongs are routed to the pong callback if the option is set,
and close frames initiate the WebSocket close procedure. When a and close frames initiate the WebSocket close procedure. When a
close frame is received, this call will eventually return close frame is received, this call will eventually return
@ref error::closed. Because of the need to handle control frames, @ref error::closed. Because of the need to handle control frames,
@ -1190,7 +1193,8 @@ public:
fi.fin == true, and zero bytes placed into the stream buffer. fi.fin == true, and zero bytes placed into the stream buffer.
Control frames encountered while reading frame or message data Control frames encountered while reading frame or message data
are handled automatically. Pings are replied to, pongs are noted, are handled automatically. Pings are replied to automatically,
pongs are routed to the pong callback if the option is set,
and close frames initiate the WebSocket close procedure. When a and close frames initiate the WebSocket close procedure. When a
close frame is received, this call will eventually return close frame is received, this call will eventually return
@ref error::closed. Because of the need to handle control frames, @ref error::closed. Because of the need to handle control frames,
@ -1233,7 +1237,8 @@ public:
the stream buffer. the stream buffer.
Control frames encountered while reading frame or message data Control frames encountered while reading frame or message data
are handled automatically. Pings are replied to, pongs are noted, are handled automatically. Pings are replied to automatically,
pongs are routed to the pong callback if the option is set,
and close frames initiate the WebSocket close procedure. When a and close frames initiate the WebSocket close procedure. When a
close frame is received, this call will eventually return close frame is received, this call will eventually return
@ref error::closed. Because of the need to handle control frames, @ref error::closed. Because of the need to handle control frames,

20
index.html Normal file
View File

@ -0,0 +1,20 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="doc/html/index.html">doc/html/index.html</a>
<hr>
<tt>
Boost.Beast<br>
<br>
Copyright (C) 2013-2016 Vinnie Falco<br>
<br>
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or copy at
<a href=http://www.boost.org/LICENSE_1_0.txt>http://www.boost.org/LICENSE_1_0.txt</a>) <br>
<br>
</tt>
</body>
</html>