beast/doc/qbk/06_websocket/02_handshaking.qbk
Vinnie Falco ab9a4c66e0 Doc work
2019-02-26 07:21:04 -08:00

156 lines
6.0 KiB
Plaintext

[/
Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Official repository: https://github.com/boostorg/beast
]
[section Handshaking]
[/-----------------------------------------------------------------------------]
[heading Client Role]
A WebSocket session begins when a client sends the HTTP/1.1
[@https://tools.ietf.org/html/rfc7230#section-6.7 Upgrade]
request for
[@https://tools.ietf.org/html/rfc6455#section-1.3 WebSocket]
on an established connection, and the server sends an appropriate response
indicating that the request was accepted and that the connection has been
upgraded. The Upgrade request must include the
[@https://tools.ietf.org/html/rfc7230#section-5.4 Host]
field, and the
[@https://tools.ietf.org/html/rfc7230#section-5.3 target]
of the resource to request.
A typical HTTP Upgrade request created and sent by the implementation
will look like this:
[table WebSocket HTTP Upgrade Request
[[Wire Format][Description]]
[[
```
GET / HTTP/1.1
Host: www.example.com
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Key: 2pGeTR0DsE4dfZs2pH+8MA==
Sec-WebSocket-Version: 13
User-Agent: Boost.Beast/216
```
][
The host and target parameters become part of the Host field
and request-target in the resulting HTTP request. The key is
generated by the implementation. Callers who wish to add,
modify, or inspect fields may set the ['decorator] option
on the stream (described later).
]]]
The
[link beast.ref.boost__beast__websocket__stream `websocket::stream`]
member functions
[link beast.ref.boost__beast__websocket__stream.handshake `handshake`] and
[link beast.ref.boost__beast__websocket__stream.async_handshake `async_handshake`]
are used to send the request with the required host and target strings. This
code connects to the IP address returned from a hostname lookup, then performs
the WebSocket handshake in the client role.
[code_websocket_2_1]
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,
overloads of the handshake member function allow the caller to store the
received HTTP message in an output reference argument of type
[link beast.ref.boost__beast__websocket__response_type `response_type`]
as follows:
[code_websocket_2_2]
[/-----------------------------------------------------------------------------]
[heading Server Role]
For servers accepting incoming connections, the
[link beast.ref.boost__beast__websocket__stream `websocket::stream`]
can read the incoming upgrade request and automatically reply. If the handshake
meets the requirements, the stream sends back the upgrade response with a
[@https://tools.ietf.org/html/rfc6455#section-4.2.2 ['101 Switching Protocols]]
status code. If the handshake does not meet the requirements, or falls outside
the range of allowed parameters specified by stream options set previously by
the caller, the stream sends back an HTTP response with a status code indicating
an error. Depending on the keep alive setting, the connection may remain open
for a subsequent handshake attempt. A typical HTTP Upgrade response created and
sent by the implementation upon receiving an upgrade request handshake will
look like this:
[table WebSocket Upgrade HTTP Response
[[Wire Format][Description]]
[[
```
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Server: Boost.Beast
```
][
The
[@https://tools.ietf.org/html/rfc6455#section-11.3.3 ['Sec-WebSocket-Accept]]
field value is generated from the request in a fashion specified by
the WebSocket protocol.
]]]
The
[link beast.ref.boost__beast__websocket__stream `stream`]
member functions
[link beast.ref.boost__beast__websocket__stream.accept `accept`] and
[link beast.ref.boost__beast__websocket__stream.async_accept `async_accept`]
are used to read the WebSocket HTTP Upgrade request handshake from a stream
already connected to an incoming peer, and then send the WebSocket HTTP
Upgrade response, as shown:
[code_websocket_2_3]
[heading Handshake Buffering]
It is possible for servers to read data from the stream and decide later
that the buffered bytes should be interpreted as a WebSocket upgrade
request. To address this usage, overloads of
[link beast.ref.boost__beast__websocket__stream.accept `accept`] and
[link beast.ref.boost__beast__websocket__stream.async_accept `async_accept`]
which accept an additional buffer sequence parameter are provided.
In this example, the server reads the initial HTTP request header into a
dynamic buffer, then later uses the buffered data to attempt a websocket
upgrade.
[code_websocket_2_4]
[heading Inspecting HTTP Requests]
When implementing an HTTP server that also supports WebSocket, the
server usually reads the HTTP request from the client. To detect when
the incoming HTTP request is a WebSocket Upgrade request, the function
[link beast.ref.boost__beast__websocket__is_upgrade `is_upgrade`] may be used.
Once the caller determines that the HTTP request is a WebSocket Upgrade,
additional overloads of
[link beast.ref.boost__beast__websocket__stream.accept `accept`] and
[link beast.ref.boost__beast__websocket__stream.async_accept `async_accept`]
are provided which receive the entire HTTP request header as an object
to perform the handshake. By reading the request manually, the program
can handle normal HTTP requests as well as upgrades. The program may
also enforce policies based on the HTTP fields, such as Basic
Authentication. In this example, the request is first read in
using the HTTP algorithms, and then passed to a newly constructed
stream:
[code_websocket_2_5]
[/-----------------------------------------------------------------------------]
[endsect]