Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / beast / websocket / stream.hpp
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 #ifndef BOOST_BEAST_WEBSOCKET_STREAM_HPP
11 #define BOOST_BEAST_WEBSOCKET_STREAM_HPP
12
13 #include <boost/beast/core/detail/config.hpp>
14 #include <boost/beast/websocket/error.hpp>
15 #include <boost/beast/websocket/option.hpp>
16 #include <boost/beast/websocket/rfc6455.hpp>
17 #include <boost/beast/websocket/stream_base.hpp>
18 #include <boost/beast/websocket/stream_fwd.hpp>
19 #include <boost/beast/websocket/detail/hybi13.hpp>
20 #include <boost/beast/websocket/detail/impl_base.hpp>
21 #include <boost/beast/websocket/detail/pmd_extension.hpp>
22 #include <boost/beast/websocket/detail/prng.hpp>
23 #include <boost/beast/core/role.hpp>
24 #include <boost/beast/core/stream_traits.hpp>
25 #include <boost/beast/core/string.hpp>
26 #include <boost/beast/http/detail/type_traits.hpp>
27 #include <boost/asio/async_result.hpp>
28 #include <boost/asio/error.hpp>
29 #include <boost/shared_ptr.hpp>
30 #include <algorithm>
31 #include <cstdint>
32 #include <functional>
33 #include <limits>
34 #include <memory>
35 #include <type_traits>
36 #include <random>
37
38 namespace boost {
39 namespace beast {
40 namespace websocket {
41
42 /** The type of received control frame.
43
44     Values of this type are passed to the control frame
45     callback set using @ref stream::control_callback.
46 */
47 enum class frame_type
48 {
49     /// A close frame was received
50     close,
51
52     /// A ping frame was received
53     ping,
54
55     /// A pong frame was received
56     pong
57 };
58
59 namespace detail {
60 class frame_test;
61 } // detail
62
63 //--------------------------------------------------------------------
64
65 /** Provides message-oriented functionality using WebSocket.
66
67     The @ref stream class template provides asynchronous and blocking
68     message-oriented functionality necessary for clients and servers
69     to utilize the WebSocket protocol.
70
71     For asynchronous operations, the application must ensure
72     that they are are all performed within the same implicit
73     or explicit strand.
74
75     @par Thread Safety
76     @e Distinct @e objects: Safe.@n
77     @e Shared @e objects: Unsafe.
78     The application must also ensure that all asynchronous
79     operations are performed within the same implicit or explicit strand.
80
81     @par Example
82     To declare the @ref stream object with a @ref tcp_stream in a
83     multi-threaded asynchronous program using a strand, you may write:
84     @code
85     websocket::stream<tcp_stream> ws{net::io_context::strand(ioc)};
86     @endcode
87     Alternatively, for a single-threaded or synchronous application
88     you may write:
89     @code
90     websocket::stream<tcp_stream> ws(ioc);
91     @endcode
92
93     @tparam NextLayer The type representing the next layer, to which
94     data will be read and written during operations. For synchronous
95     operations, the type must support the <em>SyncStream</em> concept.
96     For asynchronous operations, the type must support the
97     <em>AsyncStream</em> concept.
98
99     @tparam deflateSupported A `bool` indicating whether or not the
100     stream will be capable of negotiating the permessage-deflate websocket
101     extension. Note that even if this is set to `true`, the permessage
102     deflate options (set by the caller at runtime) must still have the
103     feature enabled for a successful negotiation to occur.
104
105     @note A stream object must not be moved or destroyed while there
106     are pending asynchronous operations associated with it.
107
108     @par Concepts
109         @li <em>AsyncStream</em>
110         @li <em>DynamicBuffer</em>
111         @li <em>SyncStream</em>
112
113     @see
114         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
115         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
116         @li <a href="https://tools.ietf.org/html/rfc6455#section-7.1.2">Websocket Closing Handshake (RFC6455)</a>
117         @li <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">Websocket Close (RFC6455)</a>
118         @li <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">WebSocket Ping (RFC6455)</a>
119         @li <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">WebSocket Pong (RFC6455)</a>
120         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
121         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
122         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
123 */
124 template<
125     class NextLayer,
126     bool deflateSupported>
127 class stream
128 #if ! BOOST_BEAST_DOXYGEN
129     : private stream_base
130 #endif
131 {
132     struct impl_type;
133
134     boost::shared_ptr<impl_type> impl_;
135
136     using time_point = typename
137         std::chrono::steady_clock::time_point;
138
139     using control_cb_type =
140         std::function<void(frame_type, string_view)>;
141
142     friend class close_test;
143     friend class frame_test;
144     friend class ping_test;
145     friend class read2_test;
146     friend class read3_test;
147     friend class stream_test;
148     friend class write_test;
149
150     /*  The read buffer has to be at least as large
151         as the largest possible control frame including
152         the frame header.
153     */
154     static std::size_t constexpr max_control_frame_size = 2 + 8 + 4 + 125;
155     static std::size_t constexpr tcp_frame_size = 1536;
156
157     static time_point never() noexcept
158     {
159         return (time_point::max)();
160     }
161
162 public:
163     /// Indicates if the permessage-deflate extension is supported
164     using is_deflate_supported =
165         std::integral_constant<bool, deflateSupported>;
166
167     /// The type of the next layer.
168     using next_layer_type =
169         typename std::remove_reference<NextLayer>::type;
170
171     /// The type of the executor associated with the object.
172     using executor_type =
173         beast::executor_type<next_layer_type>;
174
175     /** Destructor
176
177         Destroys the stream and all associated resources.
178
179         @note A stream object must not be destroyed while there
180         are pending asynchronous operations associated with it.
181     */
182     ~stream();
183
184     /** Constructor
185
186         If `NextLayer` is move constructible, this function
187         will move-construct a new stream from the existing stream.
188
189         After the move, the only valid operation on the moved-from
190         object is destruction.
191     */
192     stream(stream&&) = default;
193
194     /// Move assignment (deleted)
195     stream& operator=(stream&&) = delete;
196
197     /** Constructor
198
199         This constructor creates a websocket stream and initializes
200         the next layer object.
201
202         @throws Any exceptions thrown by the NextLayer constructor.
203
204         @param args The arguments to be passed to initialize the
205         next layer object. The arguments are forwarded to the next
206         layer's constructor.
207     */
208     template<class... Args>
209     explicit
210     stream(Args&&... args);
211
212     //--------------------------------------------------------------------------
213
214     /** Get the executor associated with the object.
215
216         This function may be used to obtain the executor object that the
217         stream uses to dispatch handlers for asynchronous operations.
218
219         @return A copy of the executor that stream will use to dispatch handlers.
220     */
221     executor_type
222     get_executor() noexcept;
223
224     /** Get a reference to the next layer
225
226         This function returns a reference to the next layer
227         in a stack of stream layers.
228
229         @return A reference to the next layer in the stack of
230         stream layers.
231     */
232     next_layer_type&
233     next_layer() noexcept;
234
235     /** Get a reference to the next layer
236
237         This function returns a reference to the next layer in a
238         stack of stream layers.
239
240         @return A reference to the next layer in the stack of
241         stream layers.
242     */
243     next_layer_type const&
244     next_layer() const noexcept;
245
246     //--------------------------------------------------------------------------
247     //
248     // Observers
249     //
250     //--------------------------------------------------------------------------
251
252     /** Returns `true` if the stream is open.
253
254         The stream is open after a successful handshake, and when
255         no error has occurred.
256     */
257     bool
258     is_open() const noexcept;
259
260     /** Returns `true` if the latest message data indicates binary.
261
262         This function informs the caller of whether the last
263         received message frame represents a message with the
264         binary opcode.
265
266         If there is no last message frame, the return value is
267         undefined.
268     */
269     bool
270     got_binary() const noexcept;
271
272     /** Returns `true` if the latest message data indicates text.
273
274         This function informs the caller of whether the last
275         received message frame represents a message with the
276         text opcode.
277
278         If there is no last message frame, the return value is
279         undefined.
280     */
281     bool
282     got_text() const
283     {
284         return ! got_binary();
285     }
286
287     /// Returns `true` if the last completed read finished the current message.
288     bool
289     is_message_done() const noexcept;
290
291     /** Returns the close reason received from the remote peer.
292
293         This is only valid after a read completes with error::closed.
294     */
295     close_reason const&
296     reason() const noexcept;
297
298     /** Returns a suggested maximum buffer size for the next call to read.
299
300         This function returns a reasonable upper limit on the number
301         of bytes for the size of the buffer passed in the next call
302         to read. The number is determined by the state of the current
303         frame and whether or not the permessage-deflate extension is
304         enabled.
305
306         @param initial_size A non-zero size representing the caller's
307         desired buffer size for when there is no information which may
308         be used to calculate a more specific value. For example, when
309         reading the first frame header of a message.
310     */
311     std::size_t
312     read_size_hint(
313         std::size_t initial_size = +tcp_frame_size) const;
314
315     /** Returns a suggested maximum buffer size for the next call to read.
316
317         This function returns a reasonable upper limit on the number
318         of bytes for the size of the buffer passed in the next call
319         to read. The number is determined by the state of the current
320         frame and whether or not the permessage-deflate extension is
321         enabled.
322
323         @param buffer The buffer which will be used for reading. The
324         implementation will query the buffer to obtain the optimum
325         size of a subsequent call to `buffer.prepare` based on the
326         state of the current frame, if any.
327     */
328     template<class DynamicBuffer
329 #if ! BOOST_BEAST_DOXYGEN
330         , class = typename std::enable_if<
331             ! std::is_integral<DynamicBuffer>::value>::type
332 #endif
333     >
334     std::size_t
335     read_size_hint(
336         DynamicBuffer& buffer) const;
337
338     //--------------------------------------------------------------------------
339     //
340     // Settings
341     //
342     //--------------------------------------------------------------------------
343
344 #if BOOST_BEAST_DOXYGEN
345     template<class Option>
346     void
347     get_option(Option& opt);
348
349     template<class Option>
350     void
351     set_option(Option opt);
352 #else
353
354     void set_option(decorator opt);
355
356     void get_option(timeout& opt);
357     void set_option(timeout const& opt);
358 #endif
359
360     /** Set the permessage-deflate extension options
361
362         @throws invalid_argument if `deflateSupported == false`, and either
363         `client_enable` or `server_enable` is `true`.
364     */
365     void
366     set_option(permessage_deflate const& o);
367
368     /// Get the permessage-deflate extension options
369     void
370     get_option(permessage_deflate& o);
371
372     /** Set the automatic fragmentation option.
373
374         Determines if outgoing message payloads are broken up into
375         multiple pieces.
376
377         When the automatic fragmentation size is turned on, outgoing
378         message payloads are broken up into multiple frames no larger
379         than the write buffer size.
380
381         The default setting is to fragment messages.
382
383         @param value A `bool` indicating if auto fragmentation should be on.
384
385         @par Example
386         Setting the automatic fragmentation option:
387         @code
388             ws.auto_fragment(true);
389         @endcode
390     */
391     void
392     auto_fragment(bool value);
393
394     /// Returns `true` if the automatic fragmentation option is set.
395     bool
396     auto_fragment() const;
397
398     /** Set the binary message write option.
399
400         This controls whether or not outgoing message opcodes
401         are set to binary or text. The setting is only applied
402         at the start when a caller begins a new message. Changing
403         the opcode after a message is started will only take effect
404         after the current message being sent is complete.
405
406         The default setting is to send text messages.
407
408         @param value `true` if outgoing messages should indicate
409         binary, or `false` if they should indicate text.
410
411         @par Example
412         Setting the message type to binary.
413         @code
414             ws.binary(true);
415         @endcode
416         */
417     void
418     binary(bool value);
419
420     /// Returns `true` if the binary message write option is set.
421     bool
422     binary() const;
423
424     /** Set a callback to be invoked on each incoming control frame.
425
426         Sets the callback to be invoked whenever a ping, pong,
427         or close control frame is received during a call to one
428         of the following functions:
429
430         @li @ref beast::websocket::stream::read
431         @li @ref beast::websocket::stream::read_some
432         @li @ref beast::websocket::stream::async_read
433         @li @ref beast::websocket::stream::async_read_some
434
435         Unlike completion handlers, the callback will be invoked
436         for each control frame during a call to any synchronous
437         or asynchronous read function. The operation is passive,
438         with no associated error code, and triggered by reads.
439
440         For close frames, the close reason code may be obtained by
441         calling the function @ref reason.
442
443         @param cb The function object to call, which must be
444         invocable with this equivalent signature:
445         @code
446         void
447         callback(
448             frame_type kind,       // The type of frame
449             string_view payload    // The payload in the frame
450         );
451         @endcode
452         The implementation type-erases the callback which may require
453         a dynamic allocation. To prevent the possibility of a dynamic
454         allocation, use `std::ref` to wrap the callback.
455         If the read operation which receives the control frame is
456         an asynchronous operation, the callback will be invoked using
457         the same method as that used to invoke the final handler.
458
459         @note Incoming ping and close frames are automatically
460         handled. Pings are responded to with pongs, and a close frame
461         is responded to with a close frame leading to the closure of
462         the stream. It is not necessary to manually send pings, pongs,
463         or close frames from inside the control callback.
464         Attempting to manually send a close frame from inside the
465         control callback after receiving a close frame will result
466         in undefined behavior.
467     */
468     void
469     control_callback(std::function<void(frame_type, string_view)> cb);
470
471     /** Reset the control frame callback.
472
473         This function removes any previously set control frame callback.
474     */
475     void
476     control_callback();
477
478     /** Set the maximum incoming message size option.
479
480         Sets the largest permissible incoming message size. Message
481         frame fields indicating a size that would bring the total
482         message size over this limit will cause a protocol failure.
483
484         The default setting is 16 megabytes. A value of zero indicates
485         a limit of the maximum value of a `std::uint64_t`.
486
487         @par Example
488         Setting the maximum read message size.
489         @code
490             ws.read_message_max(65536);
491         @endcode
492
493         @param amount The limit on the size of incoming messages.
494     */
495     void
496     read_message_max(std::size_t amount);
497
498     /// Returns the maximum incoming message size setting.
499     std::size_t
500     read_message_max() const;
501
502     /** Set whether the PRNG is cryptographically secure
503
504         This controls whether or not the source of pseudo-random
505         numbers used to produce the masks required by the WebSocket
506         protocol are of cryptographic quality. When the setting is
507         `true`, a strong algorithm is used which cannot be guessed
508         by observing outputs. When the setting is `false`, a much
509         faster algorithm is used.
510         Masking is only performed by streams operating in the client
511         mode. For streams operating in the server mode, this setting
512         has no effect.
513         By default, newly constructed streams use a secure PRNG.
514
515         If the WebSocket stream is used with an encrypted SSL or TLS
516         next layer, if it is known to the application that intermediate
517         proxies are not vulnerable to cache poisoning, or if the
518         application is designed such that an attacker cannot send
519         arbitrary inputs to the stream interface, then the faster
520         algorithm may be used.
521
522         For more information please consult the WebSocket protocol RFC.
523
524         @param value `true` if the PRNG algorithm should be
525         cryptographically secure.
526     */
527     void
528     secure_prng(bool value);
529
530     /** Set the write buffer size option.
531
532         Sets the size of the write buffer used by the implementation to
533         send frames. The write buffer is needed when masking payload data
534         in the client role, compressing frames, or auto-fragmenting message
535         data.
536
537         Lowering the size of the buffer can decrease the memory requirements
538         for each connection, while increasing the size of the buffer can reduce
539         the number of calls made to the next layer to write data.
540
541         The default setting is 4096. The minimum value is 8.
542
543         The write buffer size can only be changed when the stream is not
544         open. Undefined behavior results if the option is modified after a
545         successful WebSocket handshake.
546
547         @par Example
548         Setting the write buffer size.
549         @code
550             ws.write_buffer_bytes(8192);
551         @endcode
552
553         @param amount The size of the write buffer in bytes.
554     */
555     void
556     write_buffer_bytes(std::size_t amount);
557
558     /// Returns the size of the write buffer.
559     std::size_t
560     write_buffer_bytes() const;
561
562     /** Set the text message write option.
563
564         This controls whether or not outgoing message opcodes
565         are set to binary or text. The setting is only applied
566         at the start when a caller begins a new message. Changing
567         the opcode after a message is started will only take effect
568         after the current message being sent is complete.
569
570         The default setting is to send text messages.
571
572         @param value `true` if outgoing messages should indicate
573         text, or `false` if they should indicate binary.
574
575         @par Example
576         Setting the message type to text.
577         @code
578             ws.text(true);
579         @endcode
580     */
581     void
582     text(bool value);
583
584     /// Returns `true` if the text message write option is set.
585     bool
586     text() const;
587
588     /*
589         timer settings
590
591         * Timer is disabled
592         * Close on timeout
593             - no complete frame received, OR
594             - no complete frame sent
595         * Ping on timeout
596             - ping on no complete frame received
597                 * if can't ping?
598     */
599
600     //--------------------------------------------------------------------------
601     //
602     // Handshaking (Client)
603     //
604     //--------------------------------------------------------------------------
605
606     /** Perform the WebSocket handshake in the client role.
607
608         This function is used to perform the
609         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
610         required before messages can be sent and received. During the handshake,
611         the client sends the Websocket Upgrade HTTP request, and the server
612         replies with an HTTP response indicating the result of the handshake.
613
614         The call blocks until one of the following conditions is true:
615
616         @li The request is sent and the response is received.
617
618         @li An error occurs.
619
620         The algorithm, known as a <em>composed operation</em>, is implemented
621         in terms of calls to the next layer's `read_some` and `write_some`
622         functions.
623
624         The handshake is successful if the received HTTP response
625         indicates the upgrade was accepted by the server, represented by a
626         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
627         of @ref beast::http::status::switching_protocols.
628
629         @param host The name of the remote host. This is required by
630         the HTTP protocol to set the "Host" header field.
631
632         @param target The request-target, in origin-form. The server may use the
633         target to distinguish different services on the same listening port.
634
635         @throws system_error Thrown on failure.
636
637         @par Example
638         @code
639         ws.handshake("localhost", "/");
640         @endcode
641
642         @see
643         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
644         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
645         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
646         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
647     */
648     void
649     handshake(
650         string_view host,
651         string_view target);
652
653     /** Perform the WebSocket handshake in the client role.
654
655         This function is used to perform the
656         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
657         required before messages can be sent and received. During the handshake,
658         the client sends the Websocket Upgrade HTTP request, and the server
659         replies with an HTTP response indicating the result of the handshake.
660
661         The call blocks until one of the following conditions is true:
662
663         @li The request is sent and the response is received.
664
665         @li An error occurs.
666
667         The algorithm, known as a <em>composed operation</em>, is implemented
668         in terms of calls to the next layer's `read_some` and `write_some`
669         functions.
670
671         The handshake is successful if the received HTTP response
672         indicates the upgrade was accepted by the server, represented by a
673         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
674         of @ref beast::http::status::switching_protocols.
675
676         @param res The HTTP Upgrade response returned by the remote
677         endpoint. The caller may use the response to access any
678         additional information sent by the server.
679
680         @param host The name of the remote host. This is required by
681         the HTTP protocol to set the "Host" header field.
682
683         @param target The request-target, in origin-form. The server may use the
684         target to distinguish different services on the same listening port.
685
686         @throws system_error Thrown on failure.
687
688         @par Example
689         @code
690         response_type res;
691         ws.handshake(res, "localhost", "/");
692         std::cout << res;
693         @endcode
694
695         @see
696         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
697         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
698         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
699         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
700     */
701     void
702     handshake(
703         response_type& res,
704         string_view host,
705         string_view target);
706
707     /** Perform the WebSocket handshake in the client role.
708
709         This function is used to perform the
710         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
711         required before messages can be sent and received. During the handshake,
712         the client sends the Websocket Upgrade HTTP request, and the server
713         replies with an HTTP response indicating the result of the handshake.
714
715         The call blocks until one of the following conditions is true:
716
717         @li The request is sent and the response is received.
718
719         @li An error occurs.
720
721         The algorithm, known as a <em>composed operation</em>, is implemented
722         in terms of calls to the next layer's `read_some` and `write_some`
723         functions.
724
725         The handshake is successful if the received HTTP response
726         indicates the upgrade was accepted by the server, represented by a
727         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
728         of @ref beast::http::status::switching_protocols.
729
730         @param host The name of the remote host. This is required by
731         the HTTP protocol to set the "Host" header field.
732
733         @param target The request-target, in origin-form. The server may use the
734         target to distinguish different services on the same listening port.
735
736         @param ec Set to indicate what error occurred, if any.
737
738         @par Example
739         @code
740         error_code ec;
741         ws.handshake("localhost", "/", ec);
742         @endcode
743
744         @see
745         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
746         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
747         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
748         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
749     */
750     void
751     handshake(
752         string_view host,
753         string_view target,
754         error_code& ec);
755
756     /** Perform the WebSocket handshake in the client role.
757
758         This function is used to perform the
759         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
760         required before messages can be sent and received. During the handshake,
761         the client sends the Websocket Upgrade HTTP request, and the server
762         replies with an HTTP response indicating the result of the handshake.
763
764         The call blocks until one of the following conditions is true:
765
766         @li The request is sent and the response is received.
767
768         @li An error occurs.
769
770         The algorithm, known as a <em>composed operation</em>, is implemented
771         in terms of calls to the next layer's `read_some` and `write_some`
772         functions.
773
774         The handshake is successful if the received HTTP response
775         indicates the upgrade was accepted by the server, represented by a
776         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
777         of @ref beast::http::status::switching_protocols.
778
779         @param res The HTTP Upgrade response returned by the remote
780         endpoint. The caller may use the response to access any
781         additional information sent by the server.
782
783         @param host The name of the remote host. This is required by
784         the HTTP protocol to set the "Host" header field.
785
786         @param target The request-target, in origin-form. The server may use the
787         target to distinguish different services on the same listening port.
788
789         @param ec Set to indicate what error occurred, if any.
790
791         @par Example
792         @code
793         error_code ec;
794         response_type res;
795         ws.handshake(res, "localhost", "/", ec);
796         if(! ec)
797             std::cout << res;
798         @endcode
799
800         @see
801         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
802         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
803         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
804         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
805     */
806     void
807     handshake(
808         response_type& res,
809         string_view host,
810         string_view target,
811         error_code& ec);
812
813     /** Perform the WebSocket handshake asynchronously in the client role.
814
815         This initiating function is used to asynchronously begin performing the
816         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
817         required before messages can be sent and received. During the handshake,
818         the client sends the Websocket Upgrade HTTP request, and the server
819         replies with an HTTP response indicating the result of the handshake.
820
821         This call always returns immediately. The asynchronous operation
822         will continue until one of the following conditions is true:
823
824         @li The request is sent and the response is received.
825
826         @li An error occurs.
827
828         The algorithm, known as a <em>composed asynchronous operation</em>,
829         is implemented in terms of calls to the next layer's `async_read_some`
830         and `async_write_some` functions. No other operation may be performed
831         on the stream until this operation completes.
832
833         The handshake is successful if the received HTTP response
834         indicates the upgrade was accepted by the server, represented by a
835         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
836         of @ref beast::http::status::switching_protocols.
837
838         @param host The name of the remote host. This is required by
839         the HTTP protocol to set the "Host" header field.
840         The implementation will not access the string data after the
841         initiating function returns.
842
843         @param target The request-target, in origin-form. The server may use the
844         target to distinguish different services on the same listening port.
845         The implementation will not access the string data after the
846         initiating function returns.
847
848         @param handler The completion handler to invoke when the operation
849         completes. The implementation takes ownership of the handler by
850         performing a decay-copy. The equivalent function signature of
851         the handler must be:
852         @code
853         void handler(
854             error_code const& ec    // Result of operation
855         );
856         @endcode
857         Regardless of whether the asynchronous operation completes
858         immediately or not, the handler will not be invoked from within
859         this function. Invocation of the handler will be performed in a
860         manner equivalent to using `net::post`.
861
862         @par Example
863         @code
864         ws.async_handshake("localhost", "/",
865             [](error_code ec)
866             {
867                 if(ec)
868                     std::cerr << "Error: " << ec.message() << "\n";
869             });
870         @endcode
871
872         @see
873         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
874         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
875         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
876         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
877     */
878     template<
879         BOOST_BEAST_ASYNC_TPARAM1 HandshakeHandler =
880             net::default_completion_token_t<executor_type>
881     >
882     BOOST_BEAST_ASYNC_RESULT1(HandshakeHandler)
883     async_handshake(
884         string_view host,
885         string_view target,
886         HandshakeHandler&& handler =
887             net::default_completion_token_t<
888                 executor_type>{});
889
890     /** Perform the WebSocket handshake asynchronously in the client role.
891
892         This initiating function is used to asynchronously begin performing the
893         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
894         required before messages can be sent and received. During the handshake,
895         the client sends the Websocket Upgrade HTTP request, and the server
896         replies with an HTTP response indicating the result of the handshake.
897
898         This call always returns immediately. The asynchronous operation
899         will continue until one of the following conditions is true:
900
901         @li The request is sent and the response is received.
902
903         @li An error occurs.
904
905         The algorithm, known as a <em>composed asynchronous operation</em>,
906         is implemented in terms of calls to the next layer's `async_read_some`
907         and `async_write_some` functions. No other operation may be performed
908         on the stream until this operation completes.
909
910         The handshake is successful if the received HTTP response
911         indicates the upgrade was accepted by the server, represented by a
912         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
913         of @ref beast::http::status::switching_protocols.
914
915         @param res The HTTP Upgrade response returned by the remote
916         endpoint. The caller may use the response to access any
917         additional information sent by the server. This object will
918         be assigned before the completion handler is invoked.
919
920         @param host The name of the remote host. This is required by
921         the HTTP protocol to set the "Host" header field.
922         The implementation will not access the string data after the
923         initiating function returns.
924
925         @param target The request-target, in origin-form. The server may use the
926         target to distinguish different services on the same listening port.
927         The implementation will not access the string data after the
928         initiating function returns.
929
930         @param handler The completion handler to invoke when the operation
931         completes. The implementation takes ownership of the handler by
932         performing a decay-copy. The equivalent function signature of
933         the handler must be:
934         @code
935         void handler(
936             error_code const& ec    // Result of operation
937         );
938         @endcode
939         Regardless of whether the asynchronous operation completes
940         immediately or not, the handler will not be invoked from within
941         this function. Invocation of the handler will be performed in a
942         manner equivalent to using `net::post`.
943
944         @par Example
945         @code
946         response_type res;
947         ws.async_handshake(res, "localhost", "/",
948             [&res](error_code ec)
949             {
950                 if(ec)
951                     std::cerr << "Error: " << ec.message() << "\n";
952                 else
953                     std::cout << res;
954
955             });
956         @endcode
957
958         @see
959         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
960         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
961         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
962         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
963     */
964     template<
965         BOOST_BEAST_ASYNC_TPARAM1 HandshakeHandler =
966             net::default_completion_token_t<executor_type>
967     >
968     BOOST_BEAST_ASYNC_RESULT1(HandshakeHandler)
969     async_handshake(
970         response_type& res,
971         string_view host,
972         string_view target,
973         HandshakeHandler&& handler =
974             net::default_completion_token_t<
975                 executor_type>{});
976
977     //--------------------------------------------------------------------------
978     //
979     // Handshaking (Server)
980     //
981     //--------------------------------------------------------------------------
982
983     /** Perform the WebSocket handshake in the server role.
984
985         This function is used to perform the
986         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
987         required before messages can be sent and received. During the handshake,
988         the client sends the Websocket Upgrade HTTP request, and the server
989         replies with an HTTP response indicating the result of the handshake.
990
991         The call blocks until one of the following conditions is true:
992
993         @li The request is received and the response is sent.
994
995         @li An error occurs.
996
997         The algorithm, known as a <em>composed operation</em>, is implemented
998         in terms of calls to the next layer's `read_some` and `write_some`
999         functions.
1000
1001         If a valid upgrade request is received, an HTTP response with a
1002         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1003         of @ref beast::http::status::switching_protocols is sent to
1004         the peer, otherwise a non-successful error is associated with
1005         the operation.
1006
1007         If the request size exceeds the capacity of the stream's
1008         internal buffer, the error @ref error::buffer_overflow will be
1009         indicated. To handle larger requests, an application should
1010         read the HTTP request directly using @ref http::read and then
1011         pass the request to the appropriate overload of @ref accept or
1012         @ref async_accept
1013
1014         @throws system_error Thrown on failure.
1015
1016         @see
1017         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1018     */
1019     void
1020     accept();
1021
1022     /** Read and respond to a WebSocket HTTP Upgrade request.
1023
1024         This function is used to perform the
1025         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1026         required before messages can be sent and received. During the handshake,
1027         the client sends the Websocket Upgrade HTTP request, and the server
1028         replies with an HTTP response indicating the result of the handshake.
1029
1030         The call blocks until one of the following conditions is true:
1031
1032         @li The request is received and the response is sent.
1033
1034         @li An error occurs.
1035
1036         The algorithm, known as a <em>composed operation</em>, is implemented
1037         in terms of calls to the next layer's `read_some` and `write_some`
1038         functions.
1039
1040         If a valid upgrade request is received, an HTTP response with a
1041         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1042         of @ref beast::http::status::switching_protocols is sent to
1043         the peer, otherwise a non-successful error is associated with
1044         the operation.
1045
1046         If the request size exceeds the capacity of the stream's
1047         internal buffer, the error @ref error::buffer_overflow will be
1048         indicated. To handle larger requests, an application should
1049         read the HTTP request directly using @ref http::read and then
1050         pass the request to the appropriate overload of @ref accept or
1051         @ref async_accept
1052
1053         @param ec Set to indicate what error occurred, if any.
1054
1055         @see
1056         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1057     */
1058     void
1059     accept(error_code& ec);
1060
1061     /** Read and respond to a WebSocket HTTP Upgrade request.
1062
1063         This function is used to perform the
1064         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1065         required before messages can be sent and received. During the handshake,
1066         the client sends the Websocket Upgrade HTTP request, and the server
1067         replies with an HTTP response indicating the result of the handshake.
1068
1069         The call blocks until one of the following conditions is true:
1070
1071         @li The request is received and the response is sent.
1072
1073         @li An error occurs.
1074
1075         The algorithm, known as a <em>composed operation</em>, is implemented
1076         in terms of calls to the next layer's `read_some` and `write_some`
1077         functions.
1078
1079         If a valid upgrade request is received, an HTTP response with a
1080         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1081         of @ref beast::http::status::switching_protocols is sent to
1082         the peer, otherwise a non-successful error is associated with
1083         the operation.
1084
1085         If the request size exceeds the capacity of the stream's
1086         internal buffer, the error @ref error::buffer_overflow will be
1087         indicated. To handle larger requests, an application should
1088         read the HTTP request directly using @ref http::read and then
1089         pass the request to the appropriate overload of @ref accept or
1090         @ref async_accept
1091
1092         @param buffers Caller provided data that has already been
1093         received on the stream. The implementation will copy the
1094         caller provided data before the function returns.
1095
1096         @throws system_error Thrown on failure.
1097
1098         @see
1099         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1100     */
1101     template<class ConstBufferSequence>
1102 #if BOOST_BEAST_DOXYGEN
1103     void
1104 #else
1105     typename std::enable_if<! http::detail::is_header<
1106         ConstBufferSequence>::value>::type
1107 #endif
1108     accept(ConstBufferSequence const& buffers);
1109
1110     /** Read and respond to a WebSocket HTTP Upgrade request.
1111
1112         This function is used to perform the
1113         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1114         required before messages can be sent and received. During the handshake,
1115         the client sends the Websocket Upgrade HTTP request, and the server
1116         replies with an HTTP response indicating the result of the handshake.
1117
1118         The call blocks until one of the following conditions is true:
1119
1120         @li The request is received and the response is sent.
1121
1122         @li An error occurs.
1123
1124         The algorithm, known as a <em>composed operation</em>, is implemented
1125         in terms of calls to the next layer's `read_some` and `write_some`
1126         functions.
1127
1128         If a valid upgrade request is received, an HTTP response with a
1129         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1130         of @ref beast::http::status::switching_protocols is sent to
1131         the peer, otherwise a non-successful error is associated with
1132         the operation.
1133
1134         If the request size exceeds the capacity of the stream's
1135         internal buffer, the error @ref error::buffer_overflow will be
1136         indicated. To handle larger requests, an application should
1137         read the HTTP request directly using @ref http::read and then
1138         pass the request to the appropriate overload of @ref accept or
1139         @ref async_accept
1140
1141         @param buffers Caller provided data that has already been
1142         received on the stream. The implementation will copy the
1143         caller provided data before the function returns.
1144
1145         @param ec Set to indicate what error occurred, if any.
1146
1147         @see
1148         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1149     */
1150     template<class ConstBufferSequence>
1151 #if BOOST_BEAST_DOXYGEN
1152     void
1153 #else
1154     typename std::enable_if<! http::detail::is_header<
1155         ConstBufferSequence>::value>::type
1156 #endif
1157     accept(
1158         ConstBufferSequence const& buffers,
1159         error_code& ec);
1160
1161     /** Respond to a WebSocket HTTP Upgrade request
1162
1163         This function is used to perform the
1164         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1165         required before messages can be sent and received. During the handshake,
1166         the client sends the Websocket Upgrade HTTP request, and the server
1167         replies with an HTTP response indicating the result of the handshake.
1168
1169         The call blocks until one of the following conditions is true:
1170
1171         @li The response is sent.
1172
1173         @li An error occurs.
1174
1175         The algorithm, known as a <em>composed operation</em>, is implemented
1176         in terms of calls to the next layer's `read_some` and `write_some`
1177         functions.
1178
1179         If a valid upgrade request is received, an HTTP response with a
1180         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1181         of @ref beast::http::status::switching_protocols is sent to
1182         the peer, otherwise a non-successful error is associated with
1183         the operation.
1184
1185         @param req An object containing the HTTP Upgrade request.
1186         Ownership is not transferred, the implementation will not
1187         access this object from other threads.
1188
1189         @throws system_error Thrown on failure.
1190
1191         @see
1192         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1193     */
1194     template<class Body, class Allocator>
1195     void
1196     accept(http::request<Body,
1197         http::basic_fields<Allocator>> const& req);
1198
1199     /** Respond to a WebSocket HTTP Upgrade request
1200
1201         This function is used to perform the
1202         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1203         required before messages can be sent and received. During the handshake,
1204         the client sends the Websocket Upgrade HTTP request, and the server
1205         replies with an HTTP response indicating the result of the handshake.
1206
1207         The call blocks until one of the following conditions is true:
1208
1209         @li The response is sent.
1210
1211         @li An error occurs.
1212
1213         The algorithm, known as a <em>composed operation</em>, is implemented
1214         in terms of calls to the next layer's `read_some` and `write_some`
1215         functions.
1216
1217         If a valid upgrade request is received, an HTTP response with a
1218         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1219         of @ref beast::http::status::switching_protocols is sent to
1220         the peer, otherwise a non-successful error is associated with
1221         the operation.
1222
1223         @param req An object containing the HTTP Upgrade request.
1224         Ownership is not transferred, the implementation will not
1225         access this object from other threads.
1226
1227         @param ec Set to indicate what error occurred, if any.
1228
1229         @see
1230         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1231     */
1232     template<class Body, class Allocator>
1233     void
1234     accept(http::request<Body,
1235         http::basic_fields<Allocator>> const& req,
1236             error_code& ec);
1237
1238     /** Perform the WebSocket handshake asynchronously in the server role.
1239
1240         This initiating function is used to asynchronously begin performing the
1241         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1242         required before messages can be sent and received. During the handshake,
1243         the client sends the Websocket Upgrade HTTP request, and the server
1244         replies with an HTTP response indicating the result of the handshake.
1245
1246         This call always returns immediately. The asynchronous operation
1247         will continue until one of the following conditions is true:
1248
1249         @li The request is received and the response is sent.
1250
1251         @li An error occurs.
1252
1253         The algorithm, known as a <em>composed asynchronous operation</em>,
1254         is implemented in terms of calls to the next layer's `async_read_some`
1255         and `async_write_some` functions. No other operation may be performed
1256         on the stream until this operation completes.
1257
1258         If a valid upgrade request is received, an HTTP response with a
1259         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1260         of @ref beast::http::status::switching_protocols is sent to
1261         the peer, otherwise a non-successful error is associated with
1262         the operation.
1263
1264         If the request size exceeds the capacity of the stream's
1265         internal buffer, the error @ref error::buffer_overflow will be
1266         indicated. To handle larger requests, an application should
1267         read the HTTP request directly using @ref http::async_read and then
1268         pass the request to the appropriate overload of @ref accept or
1269         @ref async_accept
1270
1271         @param handler The completion handler to invoke when the operation
1272         completes. The implementation takes ownership of the handler by
1273         performing a decay-copy. The equivalent function signature of
1274         the handler must be:
1275         @code
1276         void handler(
1277             error_code const& ec    // Result of operation
1278         );
1279         @endcode
1280         Regardless of whether the asynchronous operation completes
1281         immediately or not, the handler will not be invoked from within
1282         this function. Invocation of the handler will be performed in a
1283         manner equivalent to using `net::post`.
1284
1285         @see
1286         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1287     */
1288     template<
1289         BOOST_BEAST_ASYNC_TPARAM1 AcceptHandler =
1290             net::default_completion_token_t<executor_type>
1291     >
1292     BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
1293     async_accept(
1294         AcceptHandler&& handler =
1295             net::default_completion_token_t<
1296                 executor_type>{});
1297
1298     /** Perform the WebSocket handshake asynchronously in the server role.
1299
1300         This initiating function is used to asynchronously begin performing the
1301         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1302         required before messages can be sent and received. During the handshake,
1303         the client sends the Websocket Upgrade HTTP request, and the server
1304         replies with an HTTP response indicating the result of the handshake.
1305
1306         This call always returns immediately. The asynchronous operation
1307         will continue until one of the following conditions is true:
1308
1309         @li The request is received and the response is sent.
1310
1311         @li An error occurs.
1312
1313         The algorithm, known as a <em>composed asynchronous operation</em>,
1314         is implemented in terms of calls to the next layer's `async_read_some`
1315         and `async_write_some` functions. No other operation may be performed
1316         on the stream until this operation completes.
1317
1318         If a valid upgrade request is received, an HTTP response with a
1319         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1320         of @ref beast::http::status::switching_protocols is sent to
1321         the peer, otherwise a non-successful error is associated with
1322         the operation.
1323
1324         If the request size exceeds the capacity of the stream's
1325         internal buffer, the error @ref error::buffer_overflow will be
1326         indicated. To handle larger requests, an application should
1327         read the HTTP request directly using @ref http::async_read and then
1328         pass the request to the appropriate overload of @ref accept or
1329         @ref async_accept
1330
1331         @param buffers Caller provided data that has already been
1332         received on the stream. This may be used for implementations
1333         allowing multiple protocols on the same stream. The
1334         buffered data will first be applied to the handshake, and
1335         then to received WebSocket frames. The implementation will
1336         copy the caller provided data before the function returns.
1337
1338         @param handler The completion handler to invoke when the operation
1339         completes. The implementation takes ownership of the handler by
1340         performing a decay-copy. The equivalent function signature of
1341         the handler must be:
1342         @code
1343         void handler(
1344             error_code const& ec    // Result of operation
1345         );
1346         @endcode
1347         Regardless of whether the asynchronous operation completes
1348         immediately or not, the handler will not be invoked from within
1349         this function. Invocation of the handler will be performed in a
1350         manner equivalent to using `net::post`.
1351
1352         @see
1353         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1354     */
1355     template<
1356         class ConstBufferSequence,
1357         BOOST_BEAST_ASYNC_TPARAM1 AcceptHandler =
1358             net::default_completion_token_t<executor_type>
1359     >
1360     BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
1361     async_accept(
1362         ConstBufferSequence const& buffers,
1363         AcceptHandler&& handler =
1364             net::default_completion_token_t<
1365                 executor_type>{}
1366 #ifndef BOOST_BEAST_DOXYGEN
1367         , typename std::enable_if<
1368             ! http::detail::is_header<
1369             ConstBufferSequence>::value>::type* = 0
1370 #endif
1371     );
1372
1373     /** Perform the WebSocket handshake asynchronously in the server role.
1374
1375         This initiating function is used to asynchronously begin performing the
1376         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1377         required before messages can be sent and received. During the handshake,
1378         the client sends the Websocket Upgrade HTTP request, and the server
1379         replies with an HTTP response indicating the result of the handshake.
1380
1381         This call always returns immediately. The asynchronous operation
1382         will continue until one of the following conditions is true:
1383
1384         @li The request is received and the response is sent.
1385
1386         @li An error occurs.
1387
1388         The algorithm, known as a <em>composed asynchronous operation</em>,
1389         is implemented in terms of calls to the next layer's `async_read_some`
1390         and `async_write_some` functions. No other operation may be performed
1391         on the stream until this operation completes.
1392
1393         If a valid upgrade request is received, an HTTP response with a
1394         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1395         of @ref beast::http::status::switching_protocols is sent to
1396         the peer, otherwise a non-successful error is associated with
1397         the operation.
1398
1399         @param req An object containing the HTTP Upgrade request.
1400         Ownership is not transferred, the implementation will not access
1401         this object from other threads.
1402
1403         @param handler The completion handler to invoke when the operation
1404         completes. The implementation takes ownership of the handler by
1405         performing a decay-copy. The equivalent function signature of
1406         the handler must be:
1407         @code
1408         void handler(
1409             error_code const& ec    // Result of operation
1410         );
1411         @endcode
1412         Regardless of whether the asynchronous operation completes
1413         immediately or not, the handler will not be invoked from within
1414         this function. Invocation of the handler will be performed in a
1415         manner equivalent to using `net::post`.
1416
1417         @see
1418         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1419     */
1420     template<
1421         class Body, class Allocator,
1422         BOOST_BEAST_ASYNC_TPARAM1 AcceptHandler =
1423             net::default_completion_token_t<executor_type>
1424     >
1425     BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
1426     async_accept(
1427         http::request<Body,
1428             http::basic_fields<Allocator>> const& req,
1429         AcceptHandler&& handler =
1430             net::default_completion_token_t<
1431                 executor_type>{});
1432
1433     //--------------------------------------------------------------------------
1434     //
1435     // Close Frames
1436     //
1437     //--------------------------------------------------------------------------
1438
1439     /** Send a websocket close control frame.
1440
1441         This function is used to send a
1442         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close frame</a>,
1443         which begins the websocket closing handshake. The session ends when
1444         both ends of the connection have sent and received a close frame.
1445
1446         The call blocks until one of the following conditions is true:
1447
1448         @li The close frame is written.
1449
1450         @li An error occurs.
1451
1452         The algorithm, known as a <em>composed operation</em>, is implemented
1453         in terms of calls to the next layer's `write_some` function.
1454
1455         After beginning the closing handshake, the program should not write
1456         further message data, pings, or pongs. Instead, the program should
1457         continue reading message data until an error occurs. A read returning
1458         @ref error::closed indicates a successful connection closure.
1459
1460         @param cr The reason for the close.
1461         If the close reason specifies a close code other than
1462         @ref beast::websocket::close_code::none, the close frame is
1463         sent with the close code and optional reason string. Otherwise,
1464         the close frame is sent with no payload.
1465
1466         @throws system_error Thrown on failure.
1467
1468         @see
1469         @li <a href="https://tools.ietf.org/html/rfc6455#section-7.1.2">Websocket Closing Handshake (RFC6455)</a>
1470     */
1471     void
1472     close(close_reason const& cr);
1473
1474     /** Send a websocket close control frame.
1475
1476         This function is used to send a
1477         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close frame</a>,
1478         which begins the websocket closing handshake. The session ends when
1479         both ends of the connection have sent and received a close frame.
1480
1481         The call blocks until one of the following conditions is true:
1482
1483         @li The close frame is written.
1484
1485         @li An error occurs.
1486
1487         The algorithm, known as a <em>composed operation</em>, is implemented
1488         in terms of calls to the next layer's `write_some` function.
1489
1490         After beginning the closing handshake, the program should not write
1491         further message data, pings, or pongs. Instead, the program should
1492         continue reading message data until an error occurs. A read returning
1493         @ref error::closed indicates a successful connection closure.
1494
1495         @param cr The reason for the close.
1496         If the close reason specifies a close code other than
1497         @ref beast::websocket::close_code::none, the close frame is
1498         sent with the close code and optional reason string. Otherwise,
1499         the close frame is sent with no payload.
1500
1501         @param ec Set to indicate what error occurred, if any.
1502
1503         @see
1504         @li <a href="https://tools.ietf.org/html/rfc6455#section-7.1.2">Websocket Closing Handshake (RFC6455)</a>
1505     */
1506     void
1507     close(close_reason const& cr, error_code& ec);
1508
1509     /** Send a websocket close control frame asynchronously.
1510
1511         This function is used to asynchronously send a
1512         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close frame</a>,
1513         which begins the websocket closing handshake. The session ends when
1514         both ends of the connection have sent and received a close frame.
1515
1516         This call always returns immediately. The asynchronous operation
1517         will continue until one of the following conditions is true:
1518
1519         @li The close frame finishes sending.
1520
1521         @li An error occurs.
1522
1523         The algorithm, known as a <em>composed asynchronous operation</em>,
1524         is implemented in terms of calls to the next layer's `async_write_some`
1525         function. No other operations except for message reading operations
1526         should be initiated on the stream after a close operation is started.
1527
1528         After beginning the closing handshake, the program should not write
1529         further message data, pings, or pongs. Instead, the program should
1530         continue reading message data until an error occurs. A read returning
1531         @ref error::closed indicates a successful connection closure.
1532
1533         @param cr The reason for the close.
1534         If the close reason specifies a close code other than
1535         @ref beast::websocket::close_code::none, the close frame is
1536         sent with the close code and optional reason string. Otherwise,
1537         the close frame is sent with no payload.
1538
1539         @param handler The completion handler to invoke when the operation
1540         completes. The implementation takes ownership of the handler by
1541         performing a decay-copy. The equivalent function signature of
1542         the handler must be:
1543         @code
1544         void handler(
1545             error_code const& ec     // Result of operation
1546         );
1547         @endcode
1548         Regardless of whether the asynchronous operation completes
1549         immediately or not, the handler will not be invoked from within
1550         this function. Invocation of the handler will be performed in a
1551         manner equivalent to using `net::post`.
1552
1553         @see
1554         @li <a href="https://tools.ietf.org/html/rfc6455#section-7.1.2">Websocket Closing Handshake (RFC6455)</a>
1555     */
1556     template<
1557         BOOST_BEAST_ASYNC_TPARAM1 CloseHandler =
1558             net::default_completion_token_t<executor_type>
1559     >
1560     BOOST_BEAST_ASYNC_RESULT1(CloseHandler)
1561     async_close(
1562         close_reason const& cr,
1563         CloseHandler&& handler =
1564             net::default_completion_token_t<
1565                 executor_type>{});
1566
1567     //--------------------------------------------------------------------------
1568     //
1569     // Ping/Pong Frames
1570     //
1571     //--------------------------------------------------------------------------
1572
1573     /** Send a websocket ping control frame.
1574
1575         This function is used to send a
1576         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">ping frame</a>,
1577         which usually elicits an automatic pong control frame response from
1578         the peer.
1579
1580         The call blocks until one of the following conditions is true:
1581
1582         @li The ping frame is written.
1583
1584         @li An error occurs.
1585
1586         The algorithm, known as a <em>composed operation</em>, is implemented
1587         in terms of calls to the next layer's `write_some` function.
1588
1589         @param payload The payload of the ping message, which may be empty.
1590
1591         @throws system_error Thrown on failure.
1592     */
1593     void
1594     ping(ping_data const& payload);
1595
1596     /** Send a websocket ping control frame.
1597
1598         This function is used to send a
1599         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">ping frame</a>,
1600         which usually elicits an automatic pong control frame response from
1601         the peer.
1602
1603         The call blocks until one of the following conditions is true:
1604
1605         @li The ping frame is written.
1606
1607         @li An error occurs.
1608
1609         The algorithm, known as a <em>composed operation</em>, is implemented
1610         in terms of calls to the next layer's `write_some` function.
1611
1612         @param payload The payload of the ping message, which may be empty.
1613
1614         @param ec Set to indicate what error occurred, if any.
1615     */
1616     void
1617     ping(ping_data const& payload, error_code& ec);
1618
1619     /** Send a websocket ping control frame asynchronously.
1620
1621         This function is used to asynchronously send a
1622         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">ping frame</a>,
1623         which usually elicits an automatic pong control frame response from
1624         the peer.
1625
1626         @li The ping frame is written.
1627
1628         @li An error occurs.
1629
1630         The algorithm, known as a <em>composed asynchronous operation</em>,
1631         is implemented in terms of calls to the next layer's `async_write_some`
1632         function. The program must ensure that no other calls to @ref ping,
1633         @ref pong, @ref async_ping, or @ref async_pong are performed until
1634         this operation completes.
1635
1636         If a close frame is sent or received before the ping frame is
1637         sent, the error received by this completion handler will be
1638         `net::error::operation_aborted`.
1639
1640         @param payload The payload of the ping message, which may be empty.
1641         The implementation will not access the contents of this object after
1642         the initiating function returns.
1643
1644         @param handler The completion handler to invoke when the operation
1645         completes. The implementation takes ownership of the handler by
1646         performing a decay-copy. The equivalent function signature of
1647         the handler must be:
1648         @code
1649         void handler(
1650             error_code const& ec     // Result of operation
1651         );
1652         @endcode
1653         Regardless of whether the asynchronous operation completes
1654         immediately or not, the handler will not be invoked from within
1655         this function. Invocation of the handler will be performed in a
1656         manner equivalent to using `net::post`.
1657     */
1658     template<
1659         BOOST_BEAST_ASYNC_TPARAM1 WriteHandler =
1660             net::default_completion_token_t<executor_type>
1661     >
1662     BOOST_BEAST_ASYNC_RESULT1(WriteHandler)
1663     async_ping(
1664         ping_data const& payload,
1665         WriteHandler&& handler =
1666             net::default_completion_token_t<
1667                 executor_type>{});
1668
1669     /** Send a websocket pong control frame.
1670
1671         This function is used to send a
1672         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pong frame</a>,
1673         which is usually sent automatically in response to a ping frame
1674         from the remote peer.
1675
1676         The call blocks until one of the following conditions is true:
1677
1678         @li The pong frame is written.
1679
1680         @li An error occurs.
1681
1682         The algorithm, known as a <em>composed operation</em>, is implemented
1683         in terms of calls to the next layer's `write_some` function.
1684
1685         WebSocket allows pong frames to be sent at any time, without first
1686         receiving a ping. An unsolicited pong sent in this fashion may
1687         indicate to the remote peer that the connection is still active.
1688
1689         @param payload The payload of the pong message, which may be empty.
1690
1691         @throws system_error Thrown on failure.
1692     */
1693     void
1694     pong(ping_data const& payload);
1695
1696     /** Send a websocket pong control frame.
1697
1698         This function is used to send a
1699         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pong frame</a>,
1700         which is usually sent automatically in response to a ping frame
1701         from the remote peer.
1702
1703         The call blocks until one of the following conditions is true:
1704
1705         @li The pong frame is written.
1706
1707         @li An error occurs.
1708
1709         The algorithm, known as a <em>composed operation</em>, is implemented
1710         in terms of calls to the next layer's `write_some` function.
1711
1712         WebSocket allows pong frames to be sent at any time, without first
1713         receiving a ping. An unsolicited pong sent in this fashion may
1714         indicate to the remote peer that the connection is still active.
1715
1716         @param payload The payload of the pong message, which may be empty.
1717
1718         @param ec Set to indicate what error occurred, if any.
1719     */
1720     void
1721     pong(ping_data const& payload, error_code& ec);
1722
1723     /** Send a websocket pong control frame asynchronously.
1724
1725         This function is used to asynchronously send a
1726         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pong frame</a>,
1727         which is usually sent automatically in response to a ping frame
1728         from the remote peer.
1729
1730         @li The pong frame is written.
1731
1732         @li An error occurs.
1733
1734         The algorithm, known as a <em>composed asynchronous operation</em>,
1735         is implemented in terms of calls to the next layer's `async_write_some`
1736         function. The program must ensure that no other calls to @ref ping,
1737         @ref pong, @ref async_ping, or @ref async_pong are performed until
1738         this operation completes.
1739
1740         If a close frame is sent or received before the pong frame is
1741         sent, the error received by this completion handler will be
1742         `net::error::operation_aborted`.
1743
1744         WebSocket allows pong frames to be sent at any time, without first
1745         receiving a ping. An unsolicited pong sent in this fashion may
1746         indicate to the remote peer that the connection is still active.
1747
1748         @param payload The payload of the pong message, which may be empty.
1749         The implementation will not access the contents of this object after
1750         the initiating function returns.
1751
1752         @param handler The completion handler to invoke when the operation
1753         completes. The implementation takes ownership of the handler by
1754         performing a decay-copy. The equivalent function signature of
1755         the handler must be:
1756         @code
1757         void handler(
1758             error_code const& ec     // Result of operation
1759         );
1760         @endcode
1761         Regardless of whether the asynchronous operation completes
1762         immediately or not, the handler will not be invoked from within
1763         this function. Invocation of the handler will be performed in a
1764         manner equivalent to using `net::post`.
1765     */
1766     template<
1767         BOOST_BEAST_ASYNC_TPARAM1 WriteHandler =
1768             net::default_completion_token_t<executor_type>
1769     >
1770     BOOST_BEAST_ASYNC_RESULT1(WriteHandler)
1771     async_pong(
1772         ping_data const& payload,
1773         WriteHandler&& handler =
1774             net::default_completion_token_t<
1775                 executor_type>{});
1776
1777     //--------------------------------------------------------------------------
1778     //
1779     // Reading
1780     //
1781     //--------------------------------------------------------------------------
1782
1783     /** Read a complete message.
1784
1785         This function is used to read a complete message.
1786
1787         The call blocks until one of the following is true:
1788
1789         @li A complete message is received.
1790
1791         @li A close frame is received. In this case the error indicated by
1792             the function will be @ref error::closed.
1793
1794         @li An error occurs.
1795
1796         The algorithm, known as a <em>composed operation</em>, is implemented
1797         in terms of calls to the next layer's `read_some` and `write_some`
1798         functions.
1799
1800         Received message data is appended to the buffer.
1801         The functions @ref got_binary and @ref got_text may be used
1802         to query the stream and determine the type of the last received message.
1803
1804         Until the call returns, the implementation will read incoming control
1805         frames and handle them automatically as follows:
1806
1807         @li The @ref control_callback will be invoked for each control frame.
1808
1809         @li For each received ping frame, a pong frame will be
1810             automatically sent.
1811
1812         @li If a close frame is received, the WebSocket closing handshake is
1813             performed. In this case, when the function returns, the error
1814             @ref error::closed will be indicated.
1815
1816         @return The number of message payload bytes appended to the buffer.
1817
1818         @param buffer A dynamic buffer to append message data to.
1819
1820         @throws system_error Thrown on failure.
1821     */
1822     template<class DynamicBuffer>
1823     std::size_t
1824     read(DynamicBuffer& buffer);
1825
1826     /** Read a complete message.
1827
1828         This function is used to read a complete message.
1829
1830         The call blocks until one of the following is true:
1831
1832         @li A complete message is received.
1833
1834         @li A close frame is received. In this case the error indicated by
1835             the function will be @ref error::closed.
1836
1837         @li An error occurs.
1838
1839         The algorithm, known as a <em>composed operation</em>, is implemented
1840         in terms of calls to the next layer's `read_some` and `write_some`
1841         functions.
1842
1843         Received message data is appended to the buffer.
1844         The functions @ref got_binary and @ref got_text may be used
1845         to query the stream and determine the type of the last received message.
1846
1847         Until the call returns, the implementation will read incoming control
1848         frames and handle them automatically as follows:
1849
1850         @li The @ref control_callback will be invoked for each control frame.
1851
1852         @li For each received ping frame, a pong frame will be
1853             automatically sent.
1854
1855         @li If a close frame is received, the WebSocket closing handshake is
1856             performed. In this case, when the function returns, the error
1857             @ref error::closed will be indicated.
1858
1859         @return The number of message payload bytes appended to the buffer.
1860
1861         @param buffer A dynamic buffer to append message data to.
1862
1863         @param ec Set to indicate what error occurred, if any.
1864     */
1865     template<class DynamicBuffer>
1866     std::size_t
1867     read(DynamicBuffer& buffer, error_code& ec);
1868
1869     /** Read a complete message asynchronously.
1870
1871         This function is used to asynchronously read a complete message.
1872
1873         This call always returns immediately. The asynchronous operation
1874         will continue until one of the following conditions is true:
1875
1876         @li A complete message is received.
1877
1878         @li A close frame is received. In this case the error indicated by
1879             the function will be @ref error::closed.
1880
1881         @li An error occurs.
1882
1883         The algorithm, known as a <em>composed asynchronous operation</em>,
1884         is implemented in terms of calls to the next layer's `async_read_some`
1885         and `async_write_some` functions. The program must ensure that no other
1886         calls to @ref read, @ref read_some, @ref async_read, or @ref async_read_some
1887         are performed until this operation completes.
1888
1889         Received message data is appended to the buffer.
1890         The functions @ref got_binary and @ref got_text may be used
1891         to query the stream and determine the type of the last received message.
1892
1893         Until the operation completes, the implementation will read incoming
1894         control frames and handle them automatically as follows:
1895
1896         @li The @ref control_callback will be invoked for each control frame.
1897
1898         @li For each received ping frame, a pong frame will be
1899             automatically sent.
1900
1901         @li If a close frame is received, the WebSocket close procedure is
1902             performed. In this case, when the function returns, the error
1903             @ref error::closed will be indicated.
1904
1905         Pong frames and close frames sent by the implementation while the
1906         read operation is outstanding do not prevent the application from
1907         also writing message data, sending pings, sending pongs, or sending
1908         close frames.
1909
1910         @param buffer A dynamic buffer to append message data to.
1911
1912         @param handler The completion handler to invoke when the operation
1913         completes. The implementation takes ownership of the handler by
1914         performing a decay-copy. The equivalent function signature of
1915         the handler must be:
1916         @code
1917         void handler(
1918             error_code const& ec,       // Result of operation
1919             std::size_t bytes_written   // Number of bytes appended to buffer
1920         );
1921         @endcode
1922         Regardless of whether the asynchronous operation completes
1923         immediately or not, the handler will not be invoked from within
1924         this function. Invocation of the handler will be performed in a
1925         manner equivalent to using `net::post`.
1926     */
1927     template<
1928         class DynamicBuffer,
1929         BOOST_BEAST_ASYNC_TPARAM2 ReadHandler =
1930             net::default_completion_token_t<
1931                 executor_type>>
1932     BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
1933     async_read(
1934         DynamicBuffer& buffer,
1935         ReadHandler&& handler =
1936             net::default_completion_token_t<
1937                 executor_type>{});
1938
1939     //--------------------------------------------------------------------------
1940
1941     /** Read some message data.
1942
1943         This function is used to read some message data.
1944
1945         The call blocks until one of the following is true:
1946
1947         @li Some message data is received.
1948
1949         @li A close frame is received. In this case the error indicated by
1950             the function will be @ref error::closed.
1951
1952         @li An error occurs.
1953
1954         The algorithm, known as a <em>composed operation</em>, is implemented
1955         in terms of calls to the next layer's `read_some` and `write_some`
1956         functions.
1957
1958         Received message data is appended to the buffer.
1959         The functions @ref got_binary and @ref got_text may be used
1960         to query the stream and determine the type of the last received message.
1961         The function @ref is_message_done may be called to determine if the
1962         message received by the last read operation is complete.
1963
1964         Until the call returns, the implementation will read incoming control
1965         frames and handle them automatically as follows:
1966
1967         @li The @ref control_callback will be invoked for each control frame.
1968
1969         @li For each received ping frame, a pong frame will be
1970             automatically sent.
1971
1972         @li If a close frame is received, the WebSocket closing handshake is
1973             performed. In this case, when the function returns, the error
1974             @ref error::closed will be indicated.
1975
1976         @return The number of message payload bytes appended to the buffer.
1977
1978         @param buffer A dynamic buffer to append message data to.
1979
1980         @param limit An upper limit on the number of bytes this function
1981         will append into the buffer. If this value is zero, then a reasonable
1982         size will be chosen automatically.
1983
1984         @throws system_error Thrown on failure.
1985     */
1986     template<class DynamicBuffer>
1987     std::size_t
1988     read_some(
1989         DynamicBuffer& buffer,
1990         std::size_t limit);
1991
1992     /** Read some message data.
1993
1994         This function is used to read some message data.
1995
1996         The call blocks until one of the following is true:
1997
1998         @li Some message data is received.
1999
2000         @li A close frame is received. In this case the error indicated by
2001             the function will be @ref error::closed.
2002
2003         @li An error occurs.
2004
2005         The algorithm, known as a <em>composed operation</em>, is implemented
2006         in terms of calls to the next layer's `read_some` and `write_some`
2007         functions.
2008
2009         Received message data is appended to the buffer.
2010         The functions @ref got_binary and @ref got_text may be used
2011         to query the stream and determine the type of the last received message.
2012         The function @ref is_message_done may be called to determine if the
2013         message received by the last read operation is complete.
2014
2015         Until the call returns, the implementation will read incoming control
2016         frames and handle them automatically as follows:
2017
2018         @li The @ref control_callback will be invoked for each control frame.
2019
2020         @li For each received ping frame, a pong frame will be
2021             automatically sent.
2022
2023         @li If a close frame is received, the WebSocket closing handshake is
2024             performed. In this case, when the function returns, the error
2025             @ref error::closed will be indicated.
2026
2027         @return The number of message payload bytes appended to the buffer.
2028
2029         @param buffer A dynamic buffer to append message data to.
2030
2031         @param limit An upper limit on the number of bytes this function
2032         will append into the buffer. If this value is zero, then a reasonable
2033         size will be chosen automatically.
2034
2035         @param ec Set to indicate what error occurred, if any.
2036     */
2037     template<class DynamicBuffer>
2038     std::size_t
2039     read_some(
2040         DynamicBuffer& buffer,
2041         std::size_t limit,
2042         error_code& ec);
2043
2044     /** Read some message data asynchronously.
2045
2046         This function is used to asynchronously read some message data.
2047
2048         This call always returns immediately. The asynchronous operation
2049         will continue until one of the following conditions is true:
2050
2051         @li Some message data is received.
2052
2053         @li A close frame is received. In this case the error indicated by
2054             the function will be @ref error::closed.
2055
2056         @li An error occurs.
2057
2058         The algorithm, known as a <em>composed asynchronous operation</em>,
2059         is implemented in terms of calls to the next layer's `async_read_some`
2060         and `async_write_some` functions. The program must ensure that no other
2061         calls to @ref read, @ref read_some, @ref async_read, or @ref async_read_some
2062         are performed until this operation completes.
2063
2064         Received message data is appended to the buffer.
2065         The functions @ref got_binary and @ref got_text may be used
2066         to query the stream and determine the type of the last received message.
2067
2068         Until the operation completes, the implementation will read incoming
2069         control frames and handle them automatically as follows:
2070
2071         @li The @ref control_callback will be invoked for each control frame.
2072
2073         @li For each received ping frame, a pong frame will be
2074             automatically sent.
2075
2076         @li If a close frame is received, the WebSocket close procedure is
2077             performed. In this case, when the function returns, the error
2078             @ref error::closed will be indicated.
2079
2080         Pong frames and close frames sent by the implementation while the
2081         read operation is outstanding do not prevent the application from
2082         also writing message data, sending pings, sending pongs, or sending
2083         close frames.
2084
2085         @param buffer A dynamic buffer to append message data to.
2086
2087         @param limit An upper limit on the number of bytes this function
2088         will append into the buffer. If this value is zero, then a reasonable
2089         size will be chosen automatically.
2090
2091         @param handler The completion handler to invoke when the operation
2092         completes. The implementation takes ownership of the handler by
2093         performing a decay-copy. The equivalent function signature of
2094         the handler must be:
2095         @code
2096         void handler(
2097             error_code const& ec,       // Result of operation
2098             std::size_t bytes_written   // Number of bytes appended to buffer
2099         );
2100         @endcode
2101         Regardless of whether the asynchronous operation completes
2102         immediately or not, the handler will not be invoked from within
2103         this function. Invocation of the handler will be performed in a
2104         manner equivalent to using `net::post`.
2105     */
2106     template<
2107         class DynamicBuffer,
2108         BOOST_BEAST_ASYNC_TPARAM2 ReadHandler =
2109             net::default_completion_token_t<
2110                 executor_type>>
2111     BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
2112     async_read_some(
2113         DynamicBuffer& buffer,
2114         std::size_t limit,
2115         ReadHandler&& handler =
2116             net::default_completion_token_t<
2117                 executor_type>{});
2118
2119     //--------------------------------------------------------------------------
2120
2121     /** Read some message data.
2122
2123         This function is used to read some message data.
2124
2125         The call blocks until one of the following is true:
2126
2127         @li Some message data is received.
2128
2129         @li A close frame is received. In this case the error indicated by
2130             the function will be @ref error::closed.
2131
2132         @li An error occurs.
2133
2134         The algorithm, known as a <em>composed operation</em>, is implemented
2135         in terms of calls to the next layer's `read_some` and `write_some`
2136         functions.
2137
2138         The functions @ref got_binary and @ref got_text may be used
2139         to query the stream and determine the type of the last received message.
2140         The function @ref is_message_done may be called to determine if the
2141         message received by the last read operation is complete.
2142
2143         Until the call returns, the implementation will read incoming control
2144         frames and handle them automatically as follows:
2145
2146         @li The @ref control_callback will be invoked for each control frame.
2147
2148         @li For each received ping frame, a pong frame will be
2149             automatically sent.
2150
2151         @li If a close frame is received, the WebSocket closing handshake is
2152             performed. In this case, when the function returns, the error
2153             @ref error::closed will be indicated.
2154
2155         @return The number of message payload bytes appended to the buffer.
2156
2157         @param buffers A buffer sequence to write message data into.
2158         The previous contents of the buffers will be overwritten, starting
2159         from the beginning.
2160
2161         @throws system_error Thrown on failure.
2162     */
2163     template<class MutableBufferSequence>
2164     std::size_t
2165     read_some(
2166         MutableBufferSequence const& buffers);
2167
2168     /** Read some message data.
2169
2170         This function is used to read some message data.
2171
2172         The call blocks until one of the following is true:
2173
2174         @li Some message data is received.
2175
2176         @li A close frame is received. In this case the error indicated by
2177             the function will be @ref error::closed.
2178
2179         @li An error occurs.
2180
2181         The algorithm, known as a <em>composed operation</em>, is implemented
2182         in terms of calls to the next layer's `read_some` and `write_some`
2183         functions.
2184
2185         The functions @ref got_binary and @ref got_text may be used
2186         to query the stream and determine the type of the last received message.
2187         The function @ref is_message_done may be called to determine if the
2188         message received by the last read operation is complete.
2189
2190         Until the call returns, the implementation will read incoming control
2191         frames and handle them automatically as follows:
2192
2193         @li The @ref control_callback will be invoked for each control frame.
2194
2195         @li For each received ping frame, a pong frame will be
2196             automatically sent.
2197
2198         @li If a close frame is received, the WebSocket closing handshake is
2199             performed. In this case, when the function returns, the error
2200             @ref error::closed will be indicated.
2201
2202         @return The number of message payload bytes appended to the buffer.
2203
2204         @param buffers A buffer sequence to write message data into.
2205         The previous contents of the buffers will be overwritten, starting
2206         from the beginning.
2207
2208         @param ec Set to indicate what error occurred, if any.
2209     */
2210     template<class MutableBufferSequence>
2211     std::size_t
2212     read_some(
2213         MutableBufferSequence const& buffers,
2214         error_code& ec);
2215
2216     /** Read some message data asynchronously.
2217
2218         This function is used to asynchronously read some message data.
2219
2220         This call always returns immediately. The asynchronous operation
2221         will continue until one of the following conditions is true:
2222
2223         @li Some message data is received.
2224
2225         @li A close frame is received. In this case the error indicated by
2226             the function will be @ref error::closed.
2227
2228         @li An error occurs.
2229
2230         The algorithm, known as a <em>composed asynchronous operation</em>,
2231         is implemented in terms of calls to the next layer's `async_read_some`
2232         and `async_write_some` functions. The program must ensure that no other
2233         calls to @ref read, @ref read_some, @ref async_read, or @ref async_read_some
2234         are performed until this operation completes.
2235
2236         Received message data is appended to the buffer.
2237         The functions @ref got_binary and @ref got_text may be used
2238         to query the stream and determine the type of the last received message.
2239
2240         Until the operation completes, the implementation will read incoming
2241         control frames and handle them automatically as follows:
2242
2243         @li The @ref control_callback will be invoked for each control frame.
2244
2245         @li For each received ping frame, a pong frame will be
2246             automatically sent.
2247
2248         @li If a close frame is received, the WebSocket close procedure is
2249             performed. In this case, when the function returns, the error
2250             @ref error::closed will be indicated.
2251
2252         Pong frames and close frames sent by the implementation while the
2253         read operation is outstanding do not prevent the application from
2254         also writing message data, sending pings, sending pongs, or sending
2255         close frames.
2256
2257         @param buffers A buffer sequence to write message data into.
2258         The previous contents of the buffers will be overwritten, starting
2259         from the beginning.
2260         The implementation will make copies of this object as needed, but
2261         but ownership of the underlying memory is not transferred. The
2262         caller is responsible for ensuring that the memory locations
2263         pointed to by the buffer sequence remain valid until the
2264         completion handler is called.
2265
2266         @param handler The completion handler to invoke when the operation
2267         completes. The implementation takes ownership of the handler by
2268         performing a decay-copy. The equivalent function signature of
2269         the handler must be:
2270         @code
2271         void handler(
2272             error_code const& ec,       // Result of operation
2273             std::size_t bytes_written   // Number of bytes written to the buffers
2274         );
2275         @endcode
2276         Regardless of whether the asynchronous operation completes
2277         immediately or not, the handler will not be invoked from within
2278         this function. Invocation of the handler will be performed in a
2279         manner equivalent to using `net::post`.
2280     */
2281     template<
2282         class MutableBufferSequence,
2283         BOOST_BEAST_ASYNC_TPARAM2 ReadHandler =
2284             net::default_completion_token_t<
2285                 executor_type>>
2286     BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
2287     async_read_some(
2288         MutableBufferSequence const& buffers,
2289         ReadHandler&& handler =
2290             net::default_completion_token_t<
2291                 executor_type>{});
2292
2293     //--------------------------------------------------------------------------
2294     //
2295     // Writing
2296     //
2297     //--------------------------------------------------------------------------
2298
2299     /** Write a complete message.
2300
2301         This function is used to write a complete message.
2302
2303         The call blocks until one of the following is true:
2304
2305         @li The message is written.
2306
2307         @li An error occurs.
2308
2309         The algorithm, known as a <em>composed operation</em>, is implemented
2310         in terms of calls to the next layer's `write_some` function.
2311
2312         The current setting of the @ref binary option controls
2313         whether the message opcode is set to text or binary. If the
2314         @ref auto_fragment option is set, the message will be split
2315         into one or more frames as necessary. The actual payload contents
2316         sent may be transformed as per the WebSocket protocol settings.
2317
2318         @param buffers The buffers containing the message to send.
2319
2320         @return The number of bytes sent from the buffers.
2321
2322         @throws system_error Thrown on failure.
2323     */
2324     template<class ConstBufferSequence>
2325     std::size_t
2326     write(ConstBufferSequence const& buffers);
2327
2328     /** Write a complete message.
2329
2330         This function is used to write a complete message.
2331
2332         The call blocks until one of the following is true:
2333
2334         @li The complete message is written.
2335
2336         @li An error occurs.
2337
2338         The algorithm, known as a <em>composed operation</em>, is implemented
2339         in terms of calls to the next layer's `write_some` function.
2340
2341         The current setting of the @ref binary option controls
2342         whether the message opcode is set to text or binary. If the
2343         @ref auto_fragment option is set, the message will be split
2344         into one or more frames as necessary. The actual payload contents
2345         sent may be transformed as per the WebSocket protocol settings.
2346
2347         @param buffers The buffers containing the message to send.
2348
2349         @param ec Set to indicate what error occurred, if any.
2350
2351         @return The number of bytes sent from the buffers.
2352     */
2353     template<class ConstBufferSequence>
2354     std::size_t
2355     write(ConstBufferSequence const& buffers, error_code& ec);
2356
2357     /** Write a complete message asynchronously.
2358
2359         This function is used to asynchronously write a complete message.
2360
2361         This call always returns immediately. The asynchronous operation
2362         will continue until one of the following conditions is true:
2363
2364         @li The complete message is written.
2365
2366         @li An error occurs.
2367
2368         The algorithm, known as a <em>composed asynchronous operation</em>,
2369         is implemented in terms of calls to the next layer's
2370         `async_write_some` function. The program must ensure that no other
2371         calls to @ref write, @ref write_some, @ref async_write, or
2372         @ref async_write_some are performed until this operation completes.
2373
2374         The current setting of the @ref binary option controls
2375         whether the message opcode is set to text or binary. If the
2376         @ref auto_fragment option is set, the message will be split
2377         into one or more frames as necessary. The actual payload contents
2378         sent may be transformed as per the WebSocket protocol settings.
2379
2380         @param buffers A buffer sequence containing the entire message
2381         payload. The implementation will make copies of this object
2382         as needed, but ownership of the underlying memory is not
2383         transferred. The caller is responsible for ensuring that
2384         the memory locations pointed to by buffers remains valid
2385         until the completion handler is called.
2386
2387         @param handler The completion handler to invoke when the operation
2388         completes. The implementation takes ownership of the handler by
2389         performing a decay-copy. The equivalent function signature of
2390         the handler must be:
2391         @code
2392         void handler(
2393             error_code const& ec,           // Result of operation
2394             std::size_t bytes_transferred   // Number of bytes sent from the
2395                                             // buffers. If an error occurred,
2396                                             // this will be less than the buffer_size.
2397         );
2398         @endcode
2399         Regardless of whether the asynchronous operation completes
2400         immediately or not, the handler will not be invoked from within
2401         this function. Invocation of the handler will be performed in a
2402         manner equivalent to using `net::post`.
2403     */
2404     template<
2405         class ConstBufferSequence,
2406         BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
2407             net::default_completion_token_t<
2408                 executor_type>>
2409     BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
2410     async_write(
2411         ConstBufferSequence const& buffers,
2412         WriteHandler&& handler =
2413             net::default_completion_token_t<
2414                 executor_type>{});
2415
2416     /** Write some message data.
2417
2418         This function is used to send part of a message.
2419
2420         The call blocks until one of the following is true:
2421
2422         @li The message data is written.
2423
2424         @li An error occurs.
2425
2426         The algorithm, known as a <em>composed operation</em>, is implemented
2427         in terms of calls to the next layer's `write_some` function.
2428
2429         If this is the beginning of a new message, the message opcode
2430         will be set to text or binary based on the current setting of
2431         the @ref binary (or @ref text) option. The actual payload sent
2432         may be transformed as per the WebSocket protocol settings.
2433
2434         @param fin `true` if this is the last part of the message.
2435
2436         @param buffers The buffers containing the message part to send.
2437
2438         @return The number of bytes sent from the buffers.
2439
2440         @throws system_error Thrown on failure.
2441     */
2442     template<class ConstBufferSequence>
2443     std::size_t
2444     write_some(bool fin, ConstBufferSequence const& buffers);
2445
2446     /** Write some message data.
2447
2448         This function is used to send part of a message.
2449
2450         The call blocks until one of the following is true:
2451
2452         @li The message data is written.
2453
2454         @li An error occurs.
2455
2456         The algorithm, known as a <em>composed operation</em>, is implemented
2457         in terms of calls to the next layer's `write_some` function.
2458
2459         If this is the beginning of a new message, the message opcode
2460         will be set to text or binary based on the current setting of
2461         the @ref binary (or @ref text) option. The actual payload sent
2462         may be transformed as per the WebSocket protocol settings.
2463
2464         @param fin `true` if this is the last part of the message.
2465
2466         @param buffers The buffers containing the message part to send.
2467
2468         @param ec Set to indicate what error occurred, if any.
2469
2470         @return The number of bytes sent from the buffers.
2471
2472         @return The number of bytes consumed in the input buffers.
2473     */
2474     template<class ConstBufferSequence>
2475     std::size_t
2476     write_some(bool fin,
2477         ConstBufferSequence const& buffers, error_code& ec);
2478
2479     /** Write some message data asynchronously.
2480
2481         This function is used to asynchronously write part of a message.
2482
2483         This call always returns immediately. The asynchronous operation
2484         will continue until one of the following conditions is true:
2485
2486         @li The message data is written.
2487
2488         @li An error occurs.
2489
2490         The algorithm, known as a <em>composed asynchronous operation</em>,
2491         is implemented in terms of calls to the next layer's
2492         `async_write_some` function. The program must ensure that no other
2493         calls to @ref write, @ref write_some, @ref async_write, or
2494         @ref async_write_some are performed until this operation completes.
2495
2496         If this is the beginning of a new message, the message opcode
2497         will be set to text or binary based on the current setting of
2498         the @ref binary (or @ref text) option. The actual payload sent
2499         may be transformed as per the WebSocket protocol settings.
2500
2501         @param fin `true` if this is the last part of the message.
2502
2503         @param buffers The buffers containing the message part to send.
2504         The implementation will make copies of this object
2505         as needed, but ownership of the underlying memory is not
2506         transferred. The caller is responsible for ensuring that
2507         the memory locations pointed to by buffers remains valid
2508         until the completion handler is called.
2509
2510         @param handler The completion handler to invoke when the operation
2511         completes. The implementation takes ownership of the handler by
2512         performing a decay-copy. The equivalent function signature of
2513         the handler must be:
2514         @code
2515         void handler(
2516             error_code const& ec,           // Result of operation
2517             std::size_t bytes_transferred   // Number of bytes sent from the
2518                                             // buffers. If an error occurred,
2519                                             // this will be less than the buffer_size.
2520         );
2521         @endcode
2522         Regardless of whether the asynchronous operation completes
2523         immediately or not, the handler will not be invoked from within
2524         this function. Invocation of the handler will be performed in a
2525         manner equivalent to using `net::post`.
2526     */
2527     template<
2528         class ConstBufferSequence,
2529         BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
2530             net::default_completion_token_t<
2531                 executor_type>>
2532     BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
2533     async_write_some(
2534         bool fin,
2535         ConstBufferSequence const& buffers,
2536         WriteHandler&& handler =
2537             net::default_completion_token_t<
2538                 executor_type>{});
2539
2540     //
2541     // Deprecated
2542     //
2543
2544 #if ! BOOST_BEAST_DOXYGEN
2545     template<class RequestDecorator>
2546     void
2547     handshake_ex(
2548         string_view host,
2549         string_view target,
2550         RequestDecorator const& decorator);
2551
2552     template<class RequestDecorator>
2553     void
2554     handshake_ex(
2555         response_type& res,
2556         string_view host,
2557         string_view target,
2558         RequestDecorator const& decorator);
2559
2560     template<class RequestDecorator>
2561     void
2562     handshake_ex(
2563         string_view host,
2564         string_view target,
2565         RequestDecorator const& decorator,
2566         error_code& ec);
2567
2568     template<class RequestDecorator>
2569     void
2570     handshake_ex(
2571         response_type& res,
2572         string_view host,
2573         string_view target,
2574         RequestDecorator const& decorator,
2575         error_code& ec);
2576
2577     template<class RequestDecorator, class HandshakeHandler>
2578     BOOST_BEAST_ASYNC_RESULT1(HandshakeHandler)
2579     async_handshake_ex(
2580         string_view host,
2581         string_view target,
2582         RequestDecorator const& decorator,
2583         HandshakeHandler&& handler);
2584
2585     template<class RequestDecorator, class HandshakeHandler>
2586     BOOST_BEAST_ASYNC_RESULT1(HandshakeHandler)
2587     async_handshake_ex(
2588         response_type& res,
2589         string_view host,
2590         string_view target,
2591         RequestDecorator const& decorator,
2592         HandshakeHandler&& handler);
2593
2594     template<class ResponseDecorator>
2595     void
2596     accept_ex(ResponseDecorator const& decorator);
2597
2598     template<class ResponseDecorator>
2599     void
2600     accept_ex(
2601         ResponseDecorator const& decorator,
2602         error_code& ec);
2603
2604     template<class ConstBufferSequence,
2605         class ResponseDecorator>
2606     typename std::enable_if<! http::detail::is_header<
2607         ConstBufferSequence>::value>::type
2608     accept_ex(
2609         ConstBufferSequence const& buffers,
2610         ResponseDecorator const& decorator);
2611
2612     template<class ConstBufferSequence, class ResponseDecorator>
2613     typename std::enable_if<! http::detail::is_header<
2614         ConstBufferSequence>::value>::type
2615     accept_ex(
2616         ConstBufferSequence const& buffers,
2617         ResponseDecorator const& decorator,
2618         error_code& ec);
2619
2620     template<class Body, class Allocator,
2621         class ResponseDecorator>
2622     void
2623     accept_ex(http::request<Body,
2624         http::basic_fields<Allocator>> const& req,
2625             ResponseDecorator const& decorator);
2626
2627     template<class Body, class Allocator,
2628         class ResponseDecorator>
2629     void
2630     accept_ex(http::request<Body,
2631         http::basic_fields<Allocator>> const& req,
2632             ResponseDecorator const& decorator,
2633                 error_code& ec);
2634
2635     template<
2636         class ResponseDecorator,
2637         class AcceptHandler>
2638     BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
2639     async_accept_ex(
2640         ResponseDecorator const& decorator,
2641         AcceptHandler&& handler);
2642
2643     template<
2644         class ConstBufferSequence,
2645         class ResponseDecorator,
2646         class AcceptHandler>
2647     BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
2648     async_accept_ex(
2649         ConstBufferSequence const& buffers,
2650         ResponseDecorator const& decorator,
2651         AcceptHandler&& handler,
2652         typename std::enable_if<
2653             ! http::detail::is_header<
2654             ConstBufferSequence>::value>::type* = 0);
2655
2656     template<
2657         class Body, class Allocator,
2658         class ResponseDecorator,
2659         class AcceptHandler>
2660     BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
2661     async_accept_ex(
2662         http::request<Body,
2663             http::basic_fields<Allocator>> const& req,
2664         ResponseDecorator const& decorator,
2665         AcceptHandler&& handler);
2666 #endif
2667
2668 private:
2669     template<class, class>  class accept_op;
2670     template<class>         class close_op;
2671     template<class>         class handshake_op;
2672     template<class>         class ping_op;
2673     template<class>         class idle_ping_op;
2674     template<class, class>  class read_some_op;
2675     template<class, class>  class read_op;
2676     template<class>         class response_op;
2677     template<class, class>  class write_some_op;
2678     template<class, class>  class write_op;
2679
2680     struct run_accept_op;
2681     struct run_close_op;
2682     struct run_handshake_op;
2683     struct run_ping_op;
2684     struct run_idle_ping_op;
2685     struct run_read_some_op;
2686     struct run_read_op;
2687     struct run_response_op;
2688     struct run_write_some_op;
2689     struct run_write_op;
2690
2691     static void default_decorate_req(request_type&) {}
2692     static void default_decorate_res(response_type&) {}
2693
2694     //
2695     // accept / handshake
2696     //
2697
2698     template<class Buffers, class Decorator>
2699     void
2700     do_accept(
2701         Buffers const& buffers,
2702         Decorator const& decorator,
2703         error_code& ec);
2704
2705     template<
2706         class Body, class Allocator,
2707         class Decorator>
2708     void
2709     do_accept(
2710         http::request<Body,
2711             http::basic_fields<Allocator>> const& req,
2712         Decorator const& decorator,
2713         error_code& ec);
2714
2715     template<class RequestDecorator>
2716     void
2717     do_handshake(response_type* res_p,
2718         string_view host, string_view target,
2719             RequestDecorator const& decorator,
2720                 error_code& ec);
2721
2722     //
2723     // fail
2724     //
2725
2726     void
2727     do_fail(
2728         std::uint16_t code,
2729         error_code ev,
2730         error_code& ec);
2731 };
2732
2733 /** Manually provide a one-time seed to initialize the PRNG
2734
2735     This function invokes the specified seed sequence to produce a seed
2736     suitable for use with the pseudo-random number generator used to
2737     create masks and perform WebSocket protocol handshakes.
2738
2739     If a seed is not manually provided, the implementation will
2740     perform a one-time seed generation using `std::random_device`. This
2741     function may be used when the application runs in an environment
2742     where the random device is unreliable or does not provide sufficient
2743     entropy.
2744
2745     @par Preconditions
2746
2747     This function may not be called after any websocket @ref stream objects
2748     have been constructed.
2749
2750     @param ss A reference to a `std::seed_seq` which will be used to seed
2751     the pseudo-random number generator. The seed sequence should have at
2752     least 256 bits of entropy.
2753
2754     @see stream::secure_prng
2755 */
2756 inline
2757 void
2758 seed_prng(std::seed_seq& ss)
2759 {
2760     detail::prng_seed(&ss);
2761 }
2762
2763 } // websocket
2764 } // beast
2765 } // boost
2766
2767 #include <boost/beast/websocket/impl/stream_impl.hpp> // must be first
2768 #include <boost/beast/websocket/impl/accept.hpp>
2769 #include <boost/beast/websocket/impl/close.hpp>
2770 #include <boost/beast/websocket/impl/handshake.hpp>
2771 #include <boost/beast/websocket/impl/ping.hpp>
2772 #include <boost/beast/websocket/impl/read.hpp>
2773 #include <boost/beast/websocket/impl/stream.hpp>
2774 #include <boost/beast/websocket/impl/write.hpp>
2775
2776 #endif