beast doc/test work

This commit is contained in:
Vinnie Falco
2016-04-20 10:15:02 -04:00
parent f07cd8ceb4
commit ca2384f230
27 changed files with 308 additions and 166 deletions

View File

@@ -19,4 +19,5 @@
* trim public interface of rfc2616.h to essentials only * trim public interface of rfc2616.h to essentials only
* Use new http routines in JSONRPCClient * Use new http routines in JSONRPCClient
* Remove or change http::headers alias * Remove or change http::headers alias
* Do something about the methods.hpp and fields.hpp type headers
* Fix index in docs

View File

@@ -103,43 +103,51 @@ WARN_LOGFILE =
# Configuration options related to the input files # Configuration options related to the input files
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
INPUT = \ INPUT = \
../beast/asio/append_buffers.h \ ../include/beast/async_completion.hpp \
../beast/asio/async_completion.h \ ../include/beast/basic_streambuf.hpp \
../beast/asio/basic_streambuf.h \ ../include/beast/bind_handler.hpp \
../beast/asio/bind_handler.h \ ../include/beast/buffer_cat.hpp \
../beast/asio/buffers_adapter.h \ ../include/beast/buffers_adapter.hpp \
../beast/asio/consuming_buffers.h \ ../include/beast/buffers_debug.hpp \
../beast/asio/handler_alloc.h \ ../include/beast/consuming_buffers.hpp \
../beast/asio/prepare_buffers.h \ ../include/beast/handler_alloc.hpp \
../beast/asio/static_streambuf.h \ ../include/beast/http.hpp \
../beast/asio/streambuf.h \ ../include/beast/placeholders.hpp \
../beast/asio/streambuf_readstream.h \ ../include/beast/prepare_buffers.hpp \
../beast/asio/type_check.h \ ../include/beast/static_streambuf.hpp \
../beast/http/basic_headers.h \ ../include/beast/streambuf.hpp \
../beast/http/basic_parser.h \ ../include/beast/streambuf_readstream.hpp \
../beast/http/chunk_encode.h \ ../include/beast/type_check.hpp \
../beast/http/empty_body.h \ ../include/beast/websocket.hpp \
../beast/http/error.h \ ../include/beast/http/basic_headers.hpp \
../beast/http/message.h \ ../include/beast/http/basic_parser.hpp \
../beast/http/parser.h \ ../include/beast/http/chunk_encode.hpp \
../beast/http/read.h \ ../include/beast/http/empty_body.hpp \
../beast/http/resume_context.h \ ../include/beast/http/error.hpp \
../beast/http/stream.h \ ../include/beast/http/fields.hpp \
../beast/http/streambuf_body.h \ ../include/beast/http/headers.hpp \
../beast/http/string_body.h \ ../include/beast/http/message.hpp \
../beast/http/type_check.h \ ../include/beast/http/method.hpp \
../beast/http/write.h \ ../include/beast/http/parser.hpp \
../beast/wsproto/error.h \ ../include/beast/http/read.hpp \
../beast/wsproto/option.h \ ../include/beast/http/resume_context.hpp \
../beast/wsproto/rfc6455.h \ ../include/beast/http/rfc2616.hpp \
../beast/wsproto/socket.h \ ../include/beast/http/streambuf_body.hpp \
../beast/wsproto/static_string.h \ ../include/beast/http/string_body.hpp \
../beast/wsproto/teardown.h \ ../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
EXCLUDE = ../beast/http/URL.h EXCLUDE =
EXCLUDE_SYMLINKS = NO EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS = EXCLUDE_SYMBOLS =

View File

@@ -42,7 +42,7 @@
Beast is a cross-platform C++ library built on Boost, containing two modules Beast is a cross-platform C++ library built on Boost, containing two modules
implementing widely used network protocols. Beast.HTTP offers a universal implementing widely used network protocols. Beast.HTTP offers a universal
model for describing, sending, and receiving HTTP messages while Beast.WSProto model for describing, sending, and receiving HTTP messages while Beast.WebSocket
provides a complete implementation of the WebSocket protocol. Their design provides a complete implementation of the WebSocket protocol. Their design
achieves these goals: achieves these goals:
@@ -97,12 +97,11 @@ flavor of the library.
All examples and identifiers mentioned in this document are written as All examples and identifiers mentioned in this document are written as
if the following statements are in effect: if the following statements are in effect:
``` ```
#include <beast/http.h> #include <boost/asio.hpp>
#include <beast/wsproto.h> #include <beast/http.hpp>
#include <beast/websocket.hpp>
using namespace beast; using namespace beast;
using namespace beast::http;
using namespace boost::asio; using namespace boost::asio;
using namespace boost::asio::ip;
``` ```
] ]
@@ -110,16 +109,16 @@ Use HTTP to request the root page from a website and receive the response:
``` ```
std::string const host = "boost.org"; std::string const host = "boost.org";
io_service ios; io_service ios;
tcp::resolver r(ios); ip::tcp::resolver r(ios);
tcp::socket sock(ios); ip::tcp::socket sock(ios);
connect(sock, r.resolve(tcp::resolver::query{host, "http"})); connect(sock, r.resolve(ip::tcp::resolver::query{host, "http"}));
request<empty_body> req(method_t::http_get, "/", 11); http::request<http::empty_body> req(http::method_t::http_get, "/", 11);
req.headers.replace("Host", host + ":" + std::to_string(sock.remote_endpoint().port())); req.headers.replace("Host", host + ":" + std::to_string(sock.remote_endpoint().port()));
req.headers.replace("User-Agent", "Beast"); req.headers.replace("User-Agent", "Beast");
write(sock, prepare(req, connection(close))); write(sock, req);
parsed_response<streambuf_body> resp; http::response<http::streambuf_body> resp;
read(sock, resp); read(sock, resp);
... ...
``` ```
@@ -132,12 +131,12 @@ Establish a WebSocket connection, send a message and receive the reply:
tcp::socket sock(ios); tcp::socket sock(ios);
connect(sock, r.resolve(tcp::resolver::query{host, "ws"})); connect(sock, r.resolve(tcp::resolver::query{host, "ws"}));
wsproto::socket<tcp::socket&> ws(sock); websocket::stream<ip::tcp::socket&> ws(sock);
ws.handshake(); ws.handshake();
ws.write(ws, buffer("Hello, world!")); ws.write(ws, buffer("Hello, world!"));
streambuf sb; streambuf sb;
wsproto::opcode op; websocket::opcode op;
ws.read(ws, op, sb); ws.read(ws, op, sb);
ws.close(); // WebSocket protocol close ws.close(); // WebSocket protocol close
@@ -165,7 +164,7 @@ documentation is based.
[include http.qbk] [include http.qbk]
[include wsproto.qbk] [include websocket.qbk]
[include types.qbk] [include types.qbk]
[include design.qbk] [include design.qbk]
[section:quickref Quick Reference] [section:quickref Quick Reference]

View File

@@ -46,48 +46,45 @@ both Boost.Asio and the HTTP protocol specification described in
All examples and identifiers mentioned in this document are written as All examples and identifiers mentioned in this document are written as
if the following declarations are in effect: if the following declarations are in effect:
``` ```
#include <beast/http.h> #include <boost/asio.hpp>
using namespace beast::http; #include <beast/http.hpp>
using namespace beast;
using namespace boost::asio; using namespace boost::asio;
``` ```
Create a HTTP request: Create a HTTP request:
``` ```
request<string_body> req({method_t::http_get, "/", 11}); http::request<http::empty_body> req({http::method_t::http_get, "/", 11});
req.headers.insert("Host", "127.0.0.1:80"); req.headers.insert("Host", "127.0.0.1:80");
req.headers.insert("User-Agent", "Beast.HTTP"); req.headers.insert("User-Agent", "Beast.HTTP");
``` ```
To send a message it must first be prepared through a call to `prepare`. This When sending a message, the Content-Length and Transfer-Encoding are set
customization point transforms the `message` into a `prepared_message`, automatically based on the properties of the body. Depending on the HTTP
filling in some standard HTTP behavior and allowing the Body associated with version of the message and properties of the message body, the implementation
the message to perform preparatory steps. For example, a string body may set will automaticaly chunk-encode the data sent on the wire:
the Content-Length and Content-Type appropriately.
``` ```
void send_request(ip::tcp::socket& sock, ip::tcp::socket sock(ios);
request<string_body>&& req) ...
{ http::response<http::string_body> resp({200, "OK", 11});
// Send the request on the socket resp.headers.insert("Server", "Beast.HTTP");
write(sock, prepare(req, connection(keep_alive)); resp.body = "The command was successful";
write(sock, resp);
} }
``` ```
Messages can be read from the network and parsed into a `parsed_message` object, Receiving a message is simple, declare a value of type message and call `read`.
which extends the `message` by adding parse-specific metadata such as the
keep-alive which is context sensitive (depending on the HTTP version for
example). When preparing a response for sending, `prepare` must be called with
an additional parameter, the corresponding parsed request. The implementation
inspects the contents of the request to set dependent fields of the response.
This example reads a message, builds a response, and sends it. This example reads a message, builds a response, and sends it.
``` ```
void handle_connection(ip::tcp::socket& sock) void handle_connection(ip::tcp::socket& sock)
{ {
parsed_request<string_body> req; request<string_body> req;
read(sock, req); read(sock, req);
response<string_body> resp; response<string_body> resp;
... ...
write(sock, prepare(resp, req)); write(sock, resp);
} }
``` ```

View File

@@ -36,7 +36,6 @@
<member><link linkend="beast.ref.http__error_code">error_code</link></member> <member><link linkend="beast.ref.http__error_code">error_code</link></member>
<member><link linkend="beast.ref.http__message">message</link></member> <member><link linkend="beast.ref.http__message">message</link></member>
<member><link linkend="beast.ref.http__resume_context">resume_context</link></member> <member><link linkend="beast.ref.http__resume_context">resume_context</link></member>
<member><link linkend="beast.ref.http__stream">stream</link></member>
<member><link linkend="beast.ref.http__streambuf_body">streambuf_body</link></member> <member><link linkend="beast.ref.http__streambuf_body">streambuf_body</link></member>
<member><link linkend="beast.ref.http__string_body">string_body</link></member> <member><link linkend="beast.ref.http__string_body">string_body</link></member>
</simplelist> </simplelist>
@@ -67,30 +66,30 @@
<entry valign="top"> <entry valign="top">
<bridgehead renderas="sect3">Classes</bridgehead> <bridgehead renderas="sect3">Classes</bridgehead>
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">
<member><link linkend="beast.ref.wsproto__close_reason">close_reason</link></member> <member><link linkend="beast.ref.websocket__close_reason">close_reason</link></member>
<member><link linkend="beast.ref.wsproto__socket">socket</link></member> <member><link linkend="beast.ref.websocket__static_string">static_string</link></member>
<member><link linkend="beast.ref.wsproto__static_string">static_string</link></member> <member><link linkend="beast.ref.websocket__stream">stream</link></member>
</simplelist> </simplelist>
<bridgehead renderas="sect3">Options</bridgehead> <bridgehead renderas="sect3">Options</bridgehead>
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">
<member><link linkend="beast.ref.wsproto__auto_fragment_size">auto_fragment_size</link></member> <member><link linkend="beast.ref.websocket__auto_fragment_size">auto_fragment_size</link></member>
<member><link linkend="beast.ref.wsproto__decorate">decorate</link></member> <member><link linkend="beast.ref.websocket__decorate">decorate</link></member>
<member><link linkend="beast.ref.wsproto__keep_alive">keep_alive</link></member> <member><link linkend="beast.ref.websocket__keep_alive">keep_alive</link></member>
<member><link linkend="beast.ref.wsproto__read_buffer_size">read_buffer_size</link></member> <member><link linkend="beast.ref.websocket__read_buffer_size">read_buffer_size</link></member>
<member><link linkend="beast.ref.wsproto__read_message_max">read_message_max</link></member> <member><link linkend="beast.ref.websocket__read_message_max">read_message_max</link></member>
<member><link linkend="beast.ref.wsproto__write_buffer_size">write_buffer_size</link></member> <member><link linkend="beast.ref.websocket__write_buffer_size">write_buffer_size</link></member>
</simplelist> </simplelist>
</entry> </entry>
<entry valign="top"> <entry valign="top">
<bridgehead renderas="sect3">Functions</bridgehead> <bridgehead renderas="sect3">Functions</bridgehead>
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">
<member><link linkend="beast.ref.wsproto__async_teardown">async_teardown</link></member> <member><link linkend="beast.ref.websocket__async_teardown">async_teardown</link></member>
<member><link linkend="beast.ref.wsproto__teardown">teardown</link></member> <member><link linkend="beast.ref.websocket__teardown">teardown</link></member>
</simplelist> </simplelist>
<bridgehead renderas="sect3">Constants</bridgehead> <bridgehead renderas="sect3">Constants</bridgehead>
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">
<member><link linkend="beast.ref.wsproto__close_code">close_code</link></member> <member><link linkend="beast.ref.websocket__close_code">close_code</link></member>
<member><link linkend="beast.ref.wsproto__opcode">opcode</link></member> <member><link linkend="beast.ref.websocket__opcode">opcode</link></member>
</simplelist> </simplelist>
</entry> </entry>
</row> </row>
@@ -128,8 +127,8 @@
<entry valign="top"> <entry valign="top">
<bridgehead renderas="sect3">Functions</bridgehead> <bridgehead renderas="sect3">Functions</bridgehead>
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">
<member><link linkend="beast.ref.append_buffers">append_buffers</link></member>
<member><link linkend="beast.ref.bind_handler">bind_handler</link></member> <member><link linkend="beast.ref.bind_handler">bind_handler</link></member>
<member><link linkend="beast.ref.buffer_cat">buffer_cat</link></member>
<member><link linkend="beast.ref.prepare_buffer">prepare_buffer</link></member> <member><link linkend="beast.ref.prepare_buffer">prepare_buffer</link></member>
<member><link linkend="beast.ref.prepare_buffers">prepare_buffers</link></member> <member><link linkend="beast.ref.prepare_buffers">prepare_buffers</link></member>
</simplelist> </simplelist>

View File

@@ -5,7 +5,7 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
] ]
[section:wsproto WSProto] [section:websocket WebSocket]
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
@@ -15,7 +15,7 @@ this technology is to provide a mechanism for browser-based applications that
need two-way communication with servers that does not rely on opening multiple need two-way communication with servers that does not rely on opening multiple
HTTP connections. HTTP connections.
Beast.WSProto provides developers with a robust WebSocket implementation Beast.WebSocket provides developers with a robust WebSocket implementation
built on Boost.Asio with a consistent asynchronous model using a modern built on Boost.Asio with a consistent asynchronous model using a modern
C++ approach. C++ approach.
@@ -33,17 +33,17 @@ good implementations in C++ are scarce. A survey of existing C++ WebSocket
solutions reveals interfaces which lack symmetry, impose performance penalties, solutions reveals interfaces which lack symmetry, impose performance penalties,
and needlessly restrict implementation strategies. and needlessly restrict implementation strategies.
Beast.WSProto is built on Boost.Asio, a robust cross platform networking 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. framework that is part of Boost and also offered as a standalone library.
A proposal to add networking functionality to the C++ standard library, A proposal to add networking functionality to the C++ standard library,
based on Boost.Asio, is under consideration by the standards committee. based on Boost.Asio, is under consideration by the standards committee.
Since the final approved networking interface for the C++ standard library Since the final approved networking interface for the C++ standard library
will likely closely resemble the current interface of Boost.Asio, it is will likely closely resemble the current interface of Boost.Asio, it is
logical for Beast.WSProto to use Boost.Asio as its network transport. logical for Beast.WebSocket to use Boost.Asio as its network transport.
Beast.WSProto takes advantage of Boost.Asio's extensible asynchronous Beast.WebSocket takes advantage of Boost.Asio's extensible asynchronous
model, handler allocation, and handler invocation hooks. Calls to model, handler allocation, and handler invocation hooks. Calls to
Beast.WSProto asynchronous initiation functions allow callers the choice Beast.WebSocket asynchronous initiation functions allow callers the choice
of using a completion handler, stackful or stackless coroutines, futures, of using a completion handler, stackful or stackless coroutines, futures,
or user defined customizations (for example, Boost.Fiber). The or user defined customizations (for example, Boost.Fiber). The
implementation uses handler invocation hooks (`asio_handler_invoke`), implementation uses handler invocation hooks (`asio_handler_invoke`),
@@ -52,7 +52,7 @@ identical to Boost.Asio. The implementation also uses handler allocation
hooks (`asio_handler_allocate`) when allocating memory internally for hooks (`asio_handler_allocate`) when allocating memory internally for
composed operations. composed operations.
There is no need for inheritance or virtual members in `wsproto::socket`. There is no need for inheritance or virtual members in `websocket::stream`.
All operations are templated and transparent to the compiler, allowing for All operations are templated and transparent to the compiler, allowing for
maximum inlining and optimization. maximum inlining and optimization.
@@ -67,25 +67,27 @@ both Boost.Asio and the WebSocket protocol specification described in
[section:creating Creating the socket] [section:creating Creating the socket]
The interface to Beast's WebSocket implementation is a single template The interface to Beast's WebSocket implementation is a single template
class which wraps an object meeting the requirements of `SyncStream` if class [link beast.ref.websocket__stream `websocket::stream`] which wraps a
synchronous operations are performed, `AsyncStream` if asynchronous "next layer" object. The next layer object must meet the requirements of
operations are performed, or both. Arguments supplied during construction `SyncReadStream` and `SyncWriteStream` if synchronous operations are performed,
are passed to the `Stream` constructor. Here we declare two websockets `AsyncReadStream` and `AsyncWriteStream` is asynchronous operations are
which contain the underlying stream: performed, or both. Arguments supplied during construction are passed to
next layer's constructor. Here we declare two websockets which have ownership
of the next layer:
``` ```
io_service ios; io_service ios;
wsproto::socket<tcp::socket> ws(ios); websocket::stream<ip::tcp::socket> ws(ios);
ssl::context ctx(ssl::context::sslv23); ssl::context ctx(ssl::context::sslv23);
wsproto::socket<ssl::stream<tcp::socket>> wss(ios, ctx); websocket::stream<ssl::stream<ip::tcp::socket>> wss(ios, ctx);
``` ```
For servers that can handshake in multiple protocols, it may be desired For servers that can handshake in multiple protocols, it may be desired
to wrap a socket that already exists. The socket can be moved in: to wrap an object that already exists. This socket can be moved in:
``` ```
tcp::socket&& sock; tcp::socket&& sock;
... ...
wsproto::socket<tcp::socket> ws(std::move(sock)); websocket::stream<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
@@ -94,14 +96,14 @@ underlying socket being wrapped:
``` ```
tcp::socket sock; tcp::socket sock;
... ...
wsproto::socket<tcp::socket&> ws(sock); websocket::stream<ip::tcp::socket&> ws(sock);
``` ```
The stream 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.
``` ```
ssl::context ctx(ssl::context::sslv23); ssl::context ctx(ssl::context::sslv23);
wsproto::socket<ssl::stream<tcp::socket>> ws(ios, ctx); websocket::stream<ssl::stream<ip::tcp::socket>> ws(ios, ctx);
... ...
ws.next_layer().shutdown(); // ssl::stream shutdown ws.next_layer().shutdown(); // ssl::stream shutdown
``` ```
@@ -116,13 +118,13 @@ result in undefined behavior. ]
[section:connecting Making connections] [section:connecting Making connections]
Connections are established by using the interfaces which already exist for Connections are established by using the interfaces which already exist
the wrapped stream. 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";
io_service ios; io_service ios;
tcp::resolver r(ios); tcp::resolver r(ios);
wsproto::socket<tcp::socket> ws(ios); websocket::stream<ip::tcp::socket> ws(ios);
connect(ws.next_layer(), r.resolve(tcp::resolver::query{host, "ws"})); connect(ws.next_layer(), r.resolve(tcp::resolver::query{host, "ws"}));
``` ```
@@ -130,7 +132,7 @@ Accepting an incoming connection:
``` ```
void do_accept(tcp::acceptor& acceptor) void do_accept(tcp::acceptor& acceptor)
{ {
wsproto::socket<tcp::socket> ws(acceptor.get_io_service()); websocket::stream<ip::tcp::socket> ws(acceptor.get_io_service());
acceptor.accept(ws.next_layer()); acceptor.accept(ws.next_layer());
} }
``` ```
@@ -147,16 +149,16 @@ 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. `wsproto::socket::hanshake` is and the URI of the resource to request. `hanshake` is used to send the
used to send the request with the required host and resource strings. request with the required host and resource strings.
``` ```
wsproto::socket<tcp::socket> ws(ios); websocket::stream<ip::tcp::socket> ws(ios);
... ...
ws.set_option(wsproto::keep_alive(true)); ws.set_option(websocket::keep_alive(true));
ws.handshake("ws.mywebapp.com:80", "/cgi-bin/bitcoin-prices"); ws.handshake("ws.mywebapp.com:80", "/cgi-bin/bitcoin-prices");
``` ```
The `wsproto::socket` automatically handles receiving and processing The `websocket::stream` automatically handles receiving and processing
the HTTP response to the handshake request. The call to handshake is the HTTP response to the handshake request. The call to handshake is
successful if a HTTP response is received with the 101 "Switching Protocols" successful if a HTTP response is received with the 101 "Switching Protocols"
status code. On failure, an error is returned or an exception is thrown. status code. On failure, an error is returned or an exception is thrown.
@@ -166,7 +168,7 @@ 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:
``` ```
wsproto::socket<tcp::socket> ws(ios); websocket::stream<ip::tcp::socket> ws(ios);
... ...
ws.accept(); ws.accept();
``` ```
@@ -181,7 +183,7 @@ void do_accept(tcp::socket& sock)
boost::asio::streambuf sb; boost::asio::streambuf sb;
read_until(sock, sb, "\r\n\r\n"); read_until(sock, sb, "\r\n\r\n");
... ...
wsproto::socket<tcp::socket&> ws(sock); websocket::stream<ip::tcp::socket&> ws(sock);
ws.accept(sb.data()); ws.accept(sb.data());
... ...
} }
@@ -193,13 +195,15 @@ obtained elsewhere:
void do_accept(tcp::socket& sock) void do_accept(tcp::socket& sock)
{ {
boost::asio::streambuf sb; boost::asio::streambuf sb;
http::parsed_request<http::empty_body> request; http::request<http::empty_body> request;
http::read(sock, request); http::read(sock, request);
... if(http::is_upgrade(request))
wsproto::socket<tcp::socket&> ws(sock); {
websocket::stream<ip::tcp::socket&> ws(sock);
ws.accept(request); ws.accept(request);
... ...
} }
}
``` ```
[note Identifiers in the `http` namespace are part of Beast.HTTP. ] [note Identifiers in the `http` namespace are part of Beast.HTTP. ]
@@ -214,20 +218,20 @@ After the WebSocket handshake is accomplished, callers may send and receive
messages using the message oriented interface. This interface requires that messages using the message oriented interface. This interface requires that
all of the buffers representing the message are known ahead of time: all of the buffers representing the message are known ahead of time:
``` ```
void echo(wsproto::socket<ip::tcp::socket>& ws) void echo(websocket::stream<ip::tcp::socket>& ws)
{ {
streambuf sb; streambuf sb;
wsproto::opcode::value op; websocket::opcode::value op;
ws.read(sb); ws.read(sb);
ws.set_option(wsproto::message_type(op)); ws.set_option(websocket::message_type(op));
wsproto::write(ws, sb.data()); websocket::write(ws, sb.data());
sb.consume(sb.size()); sb.consume(sb.size());
} }
``` ```
[important Calls to `wsproto::socket::set_option` must be made from the same [important Calls to `set_option` must be made from the same implicit
implicit or explicit strand as that used to perform other operations. ] or explicit strand as that used to perform other operations. ]
[endsect] [endsect]
@@ -245,18 +249,18 @@ message ahead of time:
For these cases, the frame oriented interface may be used. This For these cases, the frame oriented interface may be used. This
example reads and echoes a complete message using this interface: example reads and echoes a complete message using this interface:
``` ```
void echo(wsproto::socket<ip::tcp::socket>& ws) void echo(websocket::stream<ip::tcp::socket>& ws)
{ {
beast::streambuf sb; streambuf sb;
wsproto::frame_info fi; websocket::frame_info fi;
for(;;) for(;;)
{ {
ws.read_frame(fi, sb); ws.read_frame(fi, sb);
if(fi.fin) if(fi.fin)
break; break;
} }
ws.set_option(wsproto::message_type(fi.op)); ws.set_option(websocket::message_type(fi.op));
beast::consuming_buffers<streambuf::const_buffers_type> cb(sb.data()); consuming_buffers<streambuf::const_buffers_type> cb(sb.data());
for(;;) for(;;)
{ {
using boost::asio::buffer_size; using boost::asio::buffer_size;
@@ -285,7 +289,7 @@ During read operations, the implementation automatically reads and processes
WebSocket control frames such as ping, pong, and close. Pings are replied WebSocket control frames such as ping, pong, and close. Pings are replied
to as soon as possible, pongs are noted. The receipt of a close frame to as soon as possible, pongs are noted. The receipt of a close frame
initiates the WebSocket close procedure, eventually resulting in the initiates the WebSocket close procedure, eventually resulting in the
error code `wsproto::error::closed` being delivered to the caller in error code `websocket::error::closed` being delivered to the caller in
a subsequent read operation, assuming no other error takes place. a subsequent read operation, assuming no other error takes place.
To ensure timely delivery of control frames, large messages are broken up To ensure timely delivery of control frames, large messages are broken up
@@ -294,18 +298,18 @@ 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(wsproto::auto_fragment_size(8192)); ws.set_option(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
a close of the session. Handling of close initiated by the remote end of the a close of the session. Handling of close initiated by the remote end of the
connection is performed automatically. To manually initiate a close, use connection is performed automatically. To manually initiate a close, use
`wsproto::socket::close`: `websocket::stream::close`:
``` ```
ws.close(); ws.close();
``` ```
[note To receive the `wsproto::error::closed` error, a read operation [note To receive the `websocket::error::closed` error, a read operation
is required. ] is required. ]
[endsect] [endsect]
@@ -331,7 +335,7 @@ of the underlying TCP/IP connection.
Asynchronous versions are available for all functions: Asynchronous versions are available for all functions:
``` ```
wsproto::opcode op; websocket::opcode op;
ws.async_read(op, sb, ws.async_read(op, sb,
[](boost::system::error_code const& ec) [](boost::system::error_code const& ec)
{ {
@@ -343,11 +347,11 @@ Calls to asynchronous initiation functions support the extensible asynchronous
model developed by the Boost.Asio author, allowing for traditional completion model developed by the Boost.Asio author, allowing for traditional completion
handlers, stackful or stackless coroutines, and even futures: handlers, stackful or stackless coroutines, and even futures:
``` ```
void echo(wsproto::socket<ip::tcp::socket>& ws, void echo(websocket::stream<ip::tcp::socket>& ws,
boost::asio::yield_context yield) boost::asio::yield_context yield)
{ {
ws.async_read(sb, yield); ws.async_read(sb, yield);
std::future<wsproto::error_code> fut = std::future<websocket::error_code> fut =
ws.async_write, sb.data(), boost::use_future); ws.async_write, sb.data(), boost::use_future);
... ...
} }
@@ -370,7 +374,7 @@ threads are unavailable. Beast.WSProto itself does not use or require threads.
[section:safety Thread Safety] [section:safety Thread Safety]
Like a regular asio socket, a `wsproto::socket` is not thread safe. Callers Like a regular asio socket, a `websocket::stream` is not thread safe. Callers
are responsible for synchronizing operations on the socket using an implicit are responsible for synchronizing operations on the socket using an implicit
or explicit strand, as per the Asio documentation. The asynchronous interface or explicit strand, as per the Asio documentation. The asynchronous interface
supports one active read and one active write simultaneously. Undefined supports one active read and one active write simultaneously. Undefined

View File

@@ -7,27 +7,45 @@
import os ; import os ;
unit-test all : unit-test http_tests :
main.cpp
../src/beast_http_nodejs_parser.cpp ../src/beast_http_nodejs_parser.cpp
http/basic_headers.cpp
http/basic_parser.cpp
http/chunk_encode.cpp
http/empty_body.cpp
http/error.cpp
http/fields.cpp
http/headers.cpp
http/message.cpp
http/method.cpp
http/parser.cpp
http/read.cpp
http/reason.cpp
http/resume_context.cpp
http/rfc2616.cpp
http/streambuf_body.cpp
http/string_body.cpp
http/type_check.cpp
http/write.cpp
;
unit-test core_tests :
main.cpp
async_completion.cpp async_completion.cpp
base64.cpp
basic_streambuf.cpp basic_streambuf.cpp
basic_headers.cpp
bind_handler.cpp bind_handler.cpp
buffer_cat.cpp buffer_cat.cpp
buffers_adapter.cpp buffers_adapter.cpp
buffers_debug.cpp buffers_debug.cpp
chunk_encode.cpp
consuming_buffers.cpp consuming_buffers.cpp
empty_base_optimization.cpp
handler_alloc.cpp handler_alloc.cpp
message.cpp
placeholders.cpp placeholders.cpp
prepare_buffers.cpp prepare_buffers.cpp
rfc2616.cpp
static_streambuf.cpp static_streambuf.cpp
streambuf.cpp streambuf.cpp
streambuf_readstream.cpp streambuf_readstream.cpp
type_check.cpp type_check.cpp
main.cpp detail/base64.cpp
detail/empty_base_optimization.cpp
; ;

View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/basic_parser.hpp>

9
test/http/empty_body.cpp Normal file
View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/empty_body.hpp>

9
test/http/error.cpp Normal file
View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/error.hpp>

9
test/http/fields.cpp Normal file
View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/fields.hpp>

9
test/http/headers.cpp Normal file
View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/headers.hpp>

9
test/http/method.cpp Normal file
View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/method.hpp>

9
test/http/parser.cpp Normal file
View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/parser.hpp>

9
test/http/read.cpp Normal file
View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/read.hpp>

9
test/http/reason.cpp Normal file
View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/reason.hpp>

View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/resume_context.hpp>

View File

@@ -1,23 +1,13 @@
//------------------------------------------------------------------------------ //
/* // Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
This file is part of Beast: https://github.com/vinniefalco/Beast //
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.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)
Permission to use, copy, modify, and/or distribute this software for any //
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
// Test that header file is self-contained.
#include <beast/http/rfc2616.hpp> #include <beast/http/rfc2616.hpp>
#include <beast/detail/unit_test/suite.hpp> #include <beast/detail/unit_test/suite.hpp>
#include <string> #include <string>
#include <vector> #include <vector>

View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/streambuf_body.hpp>

View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/string_body.hpp>

9
test/http/type_check.cpp Normal file
View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/type_check.hpp>

9
test/http/write.cpp Normal file
View File

@@ -0,0 +1,9 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/write.hpp>