From 30d0e9b1e7beebb147c4482262fef50de4d5a85d Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Mon, 1 May 2017 15:21:20 -0700 Subject: [PATCH] WebSocket doc work --- CHANGELOG.md | 1 + doc/overview.qbk | 42 ++++++++++++++++++++++++---- doc/websocket.qbk | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05752ea1..ac4fc4b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Simplify get_lowest_layer test * Add test_allocator to extras/test * More flat_streambuf tests +* WebSocket doc work -------------------------------------------------------------------------------- diff --git a/doc/overview.qbk b/doc/overview.qbk index 9f33aa73..4dfc9525 100644 --- a/doc/overview.qbk +++ b/doc/overview.qbk @@ -35,11 +35,6 @@ 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: @@ -57,6 +52,41 @@ 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. +There are no provisions for enabling Beast to compile using the stand-alone +version of Asio. Beast relies on other parts of Boost in addition to Asio. +There are no immediate plans to offer a version of Beast that works with +the stand-alone Asio. + +[heading Audience] + +Beast is aimed at network programmers who have know some Boost.Asio. While +experience is not strictly necessary, the documentation and interfaces assume +a reasonable grasp of how Asio works. In particular, users who wish to write +asynchronous programs with Beast should already have knowledge and experience +of Asio's asynchronous interfaces and general style of asynchronous programming +using callbacks or coroutines. + +The supplied WebSocket and HTTP interfaces are low-level. The library does not +provide out of the box solutions for implementing clients or servers. For +example, users must provide their own code to make connections, handle +timeouts, reconnect a dropped connection, accept incoming connections, or +manage connection resources on a server. + +Beast's HTTP interfaces are similarly low level, providing functionality +only for modelling HTTP messages and reading and writing them to sockets or +streams. Higher level functions such as HTTP Basic Authentication, +mime/multipart encoding, cookies, automatic handling of redirects, gzipped +transfer encodings, caching, or proxying (to name a few) are not directly +provided, but nothing stops users from creating these features using +Beast's HTTP message types. + +Instead, the library is intended to be a building block for creating higher +level libraries. It implements just enough of the HTTP and WebSocket protocol +to allow users to create useful objects and algorithms which may then be +composed to produce useful applications. It is the desire of the author that +this library will become the foundation for a new generation of network +libraries. + [heading Motivation] Beast is built on Boost.Asio. A proposal to add networking functionality to the @@ -109,6 +139,6 @@ 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. +supporting its early development. [endsect] diff --git a/doc/websocket.qbk b/doc/websocket.qbk index 494b27a3..b4544c24 100644 --- a/doc/websocket.qbk +++ b/doc/websocket.qbk @@ -212,6 +212,76 @@ void do_accept(boost::asio::ip::tcp::socket& sock) } ``` +[heading Decorators] + +Often, callers may need the handshake HTTP request and response objects +generated by the implementation to contain additional HTTP fields. Some +examples include: + +* Setting the "User-Agent" or "Server" fields to a custom value +* Announcing a subprotocol by setting the "Sec-WebSocket-Protocol" field +* Adding fields used for HTTP's Basic Authentication + +To achieve this, the websocket interface provides the functions +[link beast.ref.websocket__stream.handshake_ex `handshake_ex`], +[link beast.ref.websocket__stream.async_handshake_ex `async_handshake_ex`], +[link beast.ref.websocket__stream.accept_ex `accept_ex`], and +[link beast.ref.websocket__stream.async_accept_ex `async_accept_ex`] +which allow passing of an additional decorator parameter. This parameter is +a function object to invoke which takes a writable reference to the handshake +message. The function is called after the implementation creates the message, +providing an opportunity for further modification. For client handshakes +using +[link beast.ref.websocket__stream.handshake_ex `handshake_ex`] or +[link beast.ref.websocket__stream.async_handshake_ex `async_handshake_ex`], +the message is passed as a reference to +[link beast.ref.websocket__request_type `request_type`]. Here is an example +that sets the user agent for a client request: + +``` + ws.handshake_ex("ws.example.com:80", "/", + [](request_type& req) + { + req.fields.insert("User-Agent", "Beast Example"); + }); +``` + +For server handshakes using +[link beast.ref.websocket__stream.accept_ex `accept_ex`], and +[link beast.ref.websocket__stream.async_accept_ex `async_accept_ex`] the function +object receives the message as a reference to +[link beast.ref.websocket__response_type `response_type`]. +Here is an example that sets the server field: + +``` + ws.accept_ex( + [](response_type& res) + { + res.fields.insert("Server", "Beast Example"); + }); +``` + +[heading Response Filtering] + +When a client receives an HTTP Upgrade response from the server indicating +a successful upgrade, the caller may wish to perform additional validation +on the received HTTP response message. For example, to check that the +response to a basic authentication challenge is valid. To achieve this, +the functions +[link beast.ref.websocket__stream.handshake `handshake`], +[link beast.ref.websocket__stream.handshake_ex `handshake_ex`] or +[link beast.ref.websocket__stream.async_handshake `async_handshake`], +[link beast.ref.websocket__stream.async_handshake_ex `async_handshake_ex`], +have an additional set of overloads which store the received HTTP message +in the callers parameter, which must be a reference to type +[link beast.ref.websocket__response_type `response_type`], like this: + +``` + response_type res; + ws.handshake(res, "ws.example.com:80", "/"); + // res now contains the complete HTTP response. +``` + [endsect]