mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 21:07:26 +02:00
Update and tidy documentation
This commit is contained in:
@ -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
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -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]
|
|
@ -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
111
doc/examples.qbk
Normal 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]
|
401
doc/http.qbk
401
doc/http.qbk
@ -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 |
@ -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>
|
||||||
|
233
doc/master.qbk
233
doc/master.qbk
@ -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[] '''— ''']
|
[template 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
114
doc/overview.qbk
Normal 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]
|
@ -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>
|
||||||
|
@ -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>
[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'">
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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.
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
|
@ -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
|
||||||
|
@ -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`.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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
20
index.html
Normal 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>
|
Reference in New Issue
Block a user