[/ Copyright (c) 2013-2017 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:client Handshaking (Clients)] A WebSocket session begins when a client sends the HTTP [@https://tools.ietf.org/html/rfc7230#section-6.7 Upgrade] request for [@https://tools.ietf.org/html/rfc6455#section-1.3 websocket], and the server sends an appropriate HTTP response indicating that the request was accepted and that the connection has been upgraded. The HTTP 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. The stream member functions [link beast.ref.websocket__stream.handshake.overload1 `handshake`] and [link beast.ref.websocket__stream.async_handshake.overload1 `async_handshake`] are used to send the request with the required host and target strings. ``` ... ws.set_option(websocket::keep_alive(true)); ws.handshake("localhost", "/"); ``` The implementation will create and send an HTTP request that typically looks like this: [table WebSocket Upgrade HTTP Request [[Serialized Octets][Description]] [[ ``` GET / HTTP/1.1 Host: localhost Upgrade: websocket Connection: upgrade Sec-WebSocket-Key: 2pGeTR0DsE4dfZs2pH+8MA== Sec-WebSocket-Version: 13 User-Agent: Beast ``` ][ 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 may add fields or modify fields by providing a ['decorator], described below. ]]] [heading Decorators] If the caller wishes to add or modify fields, the member functions [link beast.ref.websocket__stream.handshake_ex `handshake_ex`] and [link beast.ref.websocket__stream.async_handshake_ex `async_handshake_ex`] are provided which allow an additional function object, called a ['decorator], to be passed. The decorator is invoked to modify the HTTP Upgrade request as needed. This example sets a subprotocol on the request: ``` void decorate(websocket::request_type& req) { req.fields.insert("Sec-WebSocket-Protocol", "xmpp;ws-chat"); } ... ws.handshake_ex("localhost", "/", &decorate); ``` The HTTP Upgrade request produced by the previous call will look thusly: [table Decorated WebSocket Upgrade HTTP Request [[Serialized Octets][Description]] [[ ``` GET / HTTP/1.1 Host: localhost Upgrade: websocket Connection: upgrade Sec-WebSocket-Key: 2pGeTR0DsE4dfZs2pH+8MA== Sec-WebSocket-Version: 13 Sec-WebSocket-Protocol: xmpp;ws-chat User-Agent: Beast ``` ][ Undefined behavior results if the decorator modifies the fields specific to perform the WebSocket Upgrade , such as the Upgrade and Connection fields. ]]] [heading 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, overloads of the handshake member function allow the caller to store the received HTTP message in an output reference argument as [link beast.ref.websocket__response_type `response_type`] as follows: ``` websocket::response_type res; ws.handshake(res, "localhost", "/"); if(! res.fields.exists("Sec-WebSocket-Protocol")) throw std::invalid_argument("missing subprotocols"); ``` [endsect]