• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2    Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3
4    Distributed under the Boost Software License, Version 1.0. (See accompanying
5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7    Official repository: https://github.com/boostorg/beast
8]
9
10[section Handshaking]
11
12[/-----------------------------------------------------------------------------]
13
14[heading Client Role]
15
16A WebSocket session begins when a client sends the HTTP/1.1
17[@https://tools.ietf.org/html/rfc7230#section-6.7 Upgrade]
18request for
19[@https://tools.ietf.org/html/rfc6455#section-1.3 WebSocket]
20on an established connection, and the server sends an appropriate response
21indicating that the request was accepted and that the connection has been
22upgraded. The Upgrade request must include the
23[@https://tools.ietf.org/html/rfc7230#section-5.4 Host]
24field, and the
25[@https://tools.ietf.org/html/rfc7230#section-5.3 target]
26of the resource to request.
27A typical HTTP Upgrade request created and sent by the implementation
28will look like this:
29
30[table WebSocket HTTP Upgrade Request
31[[Wire Format][Description]]
32[[
33```
34    GET / HTTP/1.1
35    Host: www.example.com
36    Upgrade: websocket
37    Connection: upgrade
38    Sec-WebSocket-Key: 2pGeTR0DsE4dfZs2pH+8MA==
39    Sec-WebSocket-Version: 13
40    User-Agent: Boost.Beast/216
41```
42][
43    The host and target parameters become part of the Host field
44    and request-target in the resulting HTTP request. The key is
45    generated by the implementation. Callers who wish to add,
46    modify, or inspect fields may set the ['decorator] option
47    on the stream (described later).
48]]]
49
50The
51[link beast.ref.boost__beast__websocket__stream `websocket::stream`]
52member functions
53[link beast.ref.boost__beast__websocket__stream.handshake `handshake`] and
54[link beast.ref.boost__beast__websocket__stream.async_handshake `async_handshake`]
55are used to send the request with the required host and target strings. This
56code connects to the IP address returned from a hostname lookup, then performs
57the WebSocket handshake in the client role.
58
59[code_websocket_2_1]
60
61When a client receives an HTTP Upgrade response from the server indicating
62a successful upgrade, the caller may wish to perform additional validation
63on the received HTTP response message. For example, to check that the
64response to a basic authentication challenge is valid. To achieve this,
65overloads of the handshake member function allow the caller to store the
66received HTTP message in an output reference argument of type
67[link beast.ref.boost__beast__websocket__response_type `response_type`]
68as follows:
69
70[code_websocket_2_2]
71
72[/-----------------------------------------------------------------------------]
73
74[heading Server Role]
75
76For servers accepting incoming connections, the
77[link beast.ref.boost__beast__websocket__stream `websocket::stream`]
78can read the incoming upgrade request and automatically reply. If the handshake
79meets the requirements, the stream sends back the upgrade response with a
80[@https://tools.ietf.org/html/rfc6455#section-4.2.2 ['101 Switching Protocols]]
81status code. If the handshake does not meet the requirements, or falls outside
82the range of allowed parameters specified by stream options set previously by
83the caller, the stream sends back an HTTP response with a status code indicating
84an error. Depending on the keep alive setting, the connection may remain open
85for a subsequent handshake attempt. A typical HTTP Upgrade response created and
86sent by the implementation upon receiving an upgrade request handshake will
87look like this:
88
89[table WebSocket Upgrade HTTP Response
90[[Wire Format][Description]]
91[[
92    ```
93    HTTP/1.1 101 Switching Protocols
94    Upgrade: websocket
95    Connection: upgrade
96    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
97    Server: Boost.Beast
98    ```
99][
100    The
101    [@https://tools.ietf.org/html/rfc6455#section-11.3.3 ['Sec-WebSocket-Accept]]
102    field value is generated from the request in a fashion specified by
103    the WebSocket protocol.
104]]]
105
106The
107[link beast.ref.boost__beast__websocket__stream `stream`]
108member functions
109[link beast.ref.boost__beast__websocket__stream.accept `accept`] and
110[link beast.ref.boost__beast__websocket__stream.async_accept `async_accept`]
111are used to read the WebSocket HTTP Upgrade request handshake from a stream
112already connected to an incoming peer, and then send the WebSocket HTTP
113Upgrade response, as shown:
114
115[code_websocket_2_3]
116
117[heading Handshake Buffering]
118
119It is possible for servers to read data from the stream and decide later
120that the buffered bytes should be interpreted as a WebSocket upgrade
121request. To address this usage, overloads of
122[link beast.ref.boost__beast__websocket__stream.accept `accept`] and
123[link beast.ref.boost__beast__websocket__stream.async_accept `async_accept`]
124which accept an additional buffer sequence parameter are provided.
125
126In this example, the server reads the initial HTTP request header into a
127dynamic buffer, then later uses the buffered data to attempt a websocket
128upgrade.
129
130[code_websocket_2_4]
131
132[heading Inspecting HTTP Requests]
133
134When implementing an HTTP server that also supports WebSocket, the
135server usually reads the HTTP request from the client. To detect when
136the incoming HTTP request is a WebSocket Upgrade request, the function
137[link beast.ref.boost__beast__websocket__is_upgrade `is_upgrade`] may be used.
138
139Once the caller determines that the HTTP request is a WebSocket Upgrade,
140additional overloads of
141[link beast.ref.boost__beast__websocket__stream.accept `accept`] and
142[link beast.ref.boost__beast__websocket__stream.async_accept `async_accept`]
143are provided which receive the entire HTTP request header as an object
144to perform the handshake. By reading the request manually, the program
145can handle normal HTTP requests as well as upgrades. The program may
146also enforce policies based on the HTTP fields, such as Basic
147Authentication. In this example, the request is first read in
148using the HTTP algorithms, and then passed to a newly constructed
149stream:
150
151[code_websocket_2_5]
152
153[heading Subprotocols]
154
155The WebSocket protocol understands the concept of subprotocols. If the client
156is requesting one of a set of subprotocols it will set the header
157[@https://tools.ietf.org/html/rfc6455#section-11.3.4 Sec-WebSocket-Protocol]
158in the initial WebSocket Upgrade HTTP request. It is up to the server to
159parse the header and select one of the protocols to accept. The server
160indicates the selected protocol by setting the
161[@https://tools.ietf.org/html/rfc6455#section-11.3.4 Sec-WebSocket-Protocol]
162header in the accept header.
163
164This is accomplished with a
165[link beast.ref.boost__beast__websocket__stream_base__decorator `decorator`].
166
167The code that follows demonstrates how a server reads an HTTP request, identifies it
168as a WebSocket Upgrade, and then checks for a preferred matching subprotocol before
169performing the WebSocket handshake:
170
171[code_websocket_2_6]
172
173
174[/-----------------------------------------------------------------------------]
175
176[endsect]
177