Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:35

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_WEBSOCKET_STREAM_HPP
0011 #define BOOST_BEAST_WEBSOCKET_STREAM_HPP
0012 
0013 #include <boost/beast/core/detail/config.hpp>
0014 #include <boost/beast/websocket/error.hpp>
0015 #include <boost/beast/websocket/option.hpp>
0016 #include <boost/beast/websocket/rfc6455.hpp>
0017 #include <boost/beast/websocket/stream_base.hpp>
0018 #include <boost/beast/websocket/stream_fwd.hpp>
0019 #include <boost/beast/websocket/detail/hybi13.hpp>
0020 #include <boost/beast/websocket/detail/impl_base.hpp>
0021 #include <boost/beast/websocket/detail/pmd_extension.hpp>
0022 #include <boost/beast/websocket/detail/prng.hpp>
0023 #include <boost/beast/core/role.hpp>
0024 #include <boost/beast/core/stream_traits.hpp>
0025 #include <boost/beast/core/string.hpp>
0026 #include <boost/beast/http/detail/type_traits.hpp>
0027 #include <boost/asio/async_result.hpp>
0028 #include <boost/asio/error.hpp>
0029 #include <boost/shared_ptr.hpp>
0030 #include <algorithm>
0031 #include <cstdint>
0032 #include <functional>
0033 #include <limits>
0034 #include <memory>
0035 #include <type_traits>
0036 #include <random>
0037 
0038 namespace boost {
0039 namespace beast {
0040 namespace websocket {
0041 
0042 /** The type of received control frame.
0043 
0044     Values of this type are passed to the control frame
0045     callback set using @ref stream::control_callback.
0046 */
0047 enum class frame_type
0048 {
0049     /// A close frame was received
0050     close,
0051 
0052     /// A ping frame was received
0053     ping,
0054 
0055     /// A pong frame was received
0056     pong
0057 };
0058 
0059 namespace detail {
0060 class frame_test;
0061 } // detail
0062 
0063 //--------------------------------------------------------------------
0064 
0065 /** Provides message-oriented functionality using WebSocket.
0066 
0067     The @ref stream class template provides asynchronous and blocking
0068     message-oriented functionality necessary for clients and servers
0069     to utilize the WebSocket protocol.
0070 
0071     For asynchronous operations, the application must ensure
0072     that they are are all performed within the same implicit
0073     or explicit strand.
0074 
0075     @par Thread Safety
0076     @e Distinct @e objects: Safe.@n
0077     @e Shared @e objects: Unsafe.
0078     The application must also ensure that all asynchronous
0079     operations are performed within the same implicit or explicit strand.
0080 
0081     @par Example
0082     To declare the @ref stream object with a @ref tcp_stream in a
0083     multi-threaded asynchronous program using a strand, you may write:
0084     @code
0085     websocket::stream<tcp_stream> ws{net::make_strand(ioc)};
0086     @endcode
0087     Alternatively, for a single-threaded or synchronous application
0088     you may write:
0089     @code
0090     websocket::stream<tcp_stream> ws(ioc);
0091     @endcode
0092 
0093     @tparam NextLayer The type representing the next layer, to which
0094     data will be read and written during operations. For synchronous
0095     operations, the type must support the <em>SyncStream</em> concept.
0096     For asynchronous operations, the type must support the
0097     <em>AsyncStream</em> concept.
0098 
0099     @tparam deflateSupported A `bool` indicating whether or not the
0100     stream will be capable of negotiating the permessage-deflate websocket
0101     extension. Note that even if this is set to `true`, the permessage
0102     deflate options (set by the caller at runtime) must still have the
0103     feature enabled for a successful negotiation to occur.
0104 
0105     @note A stream object must not be moved or destroyed while there
0106     are pending asynchronous operations associated with it.
0107 
0108     @par Concepts
0109         @li <em>AsyncStream</em>
0110         @li <em>DynamicBuffer</em>
0111         @li <em>SyncStream</em>
0112 
0113     @see
0114         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
0115         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
0116         @li <a href="https://tools.ietf.org/html/rfc6455#section-7.1.2">Websocket Closing Handshake (RFC6455)</a>
0117         @li <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">Websocket Close (RFC6455)</a>
0118         @li <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">WebSocket Ping (RFC6455)</a>
0119         @li <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">WebSocket Pong (RFC6455)</a>
0120         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
0121         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
0122         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
0123 */
0124 template<
0125     class NextLayer,
0126     bool deflateSupported>
0127 class stream
0128 #if ! BOOST_BEAST_DOXYGEN
0129     : private stream_base
0130 #endif
0131 {
0132     struct impl_type;
0133 
0134     boost::shared_ptr<impl_type> impl_;
0135 
0136     using time_point = typename
0137         std::chrono::steady_clock::time_point;
0138 
0139     using control_cb_type =
0140         std::function<void(frame_type, string_view)>;
0141 
0142 #ifndef BOOST_BEAST_DOXYGEN
0143     friend class close_test;
0144     friend class frame_test;
0145     friend class ping_test;
0146     friend class read2_test;
0147     friend class read3_test;
0148     friend class stream_test;
0149     friend class write_test;
0150 
0151     /*  The read buffer has to be at least as large
0152         as the largest possible control frame including
0153         the frame header.
0154     */
0155     static std::size_t constexpr max_control_frame_size = 2 + 8 + 4 + 125;
0156     static std::size_t constexpr tcp_frame_size = 1536;
0157 #endif
0158 
0159     static time_point never() noexcept
0160     {
0161         return (time_point::max)();
0162     }
0163 
0164 public:
0165 
0166     /// Indicates if the permessage-deflate extension is supported
0167     using is_deflate_supported =
0168         std::integral_constant<bool, deflateSupported>;
0169 
0170     /// The type of the next layer.
0171     using next_layer_type =
0172         typename std::remove_reference<NextLayer>::type;
0173 
0174     /// The type of the executor associated with the object.
0175     using executor_type =
0176         beast::executor_type<next_layer_type>;
0177 
0178     /// Rebinds the stream type to another executor.
0179     template<class Executor1>
0180     struct rebind_executor
0181     {
0182         /// The stream type when rebound to the specified executor.
0183         using other = stream<
0184                 typename next_layer_type::template rebind_executor<Executor1>::other,
0185                 deflateSupported>;
0186     };
0187 
0188     /** Destructor
0189 
0190         Destroys the stream and all associated resources.
0191 
0192         @note A stream object must not be destroyed while there
0193         are pending asynchronous operations associated with it.
0194     */
0195     ~stream();
0196 
0197     /** Constructor
0198 
0199         If `NextLayer` is move constructible, this function
0200         will move-construct a new stream from the existing stream.
0201 
0202         After the move, the only valid operation on the moved-from
0203         object is destruction.
0204     */
0205     stream(stream&&) = default;
0206 
0207     /// Move assignment (deleted)
0208     stream& operator=(stream&&) = delete;
0209 
0210     /** Constructor
0211 
0212         This constructor creates a websocket stream and initializes
0213         the next layer object.
0214 
0215         @throws Any exceptions thrown by the NextLayer constructor.
0216 
0217         @param args The arguments to be passed to initialize the
0218         next layer object. The arguments are forwarded to the next
0219         layer's constructor.
0220     */
0221     template<class... Args>
0222     explicit
0223     stream(Args&&... args);
0224 
0225     /** Rebinding constructor
0226      *
0227      *  This constructor creates a the websocket stream from a
0228      *  websocket stream with a different executor.
0229      *
0230      *  @throw Any exception thrown by the NextLayer rebind constructor.
0231      *
0232      *  @param other The other websocket stream to construct from.
0233      */
0234     template<class Other>
0235     explicit
0236     stream(stream<Other> && other);
0237 
0238 
0239     //--------------------------------------------------------------------------
0240 
0241     /** Get the executor associated with the object.
0242 
0243         This function may be used to obtain the executor object that the
0244         stream uses to dispatch handlers for asynchronous operations.
0245 
0246         @return A copy of the executor that stream will use to dispatch handlers.
0247     */
0248     executor_type
0249     get_executor() noexcept;
0250 
0251     /** Get a reference to the next layer
0252 
0253         This function returns a reference to the next layer
0254         in a stack of stream layers.
0255 
0256         @return A reference to the next layer in the stack of
0257         stream layers.
0258     */
0259     next_layer_type&
0260     next_layer() noexcept;
0261 
0262     /** Get a reference to the next layer
0263 
0264         This function returns a reference to the next layer in a
0265         stack of stream layers.
0266 
0267         @return A reference to the next layer in the stack of
0268         stream layers.
0269     */
0270     next_layer_type const&
0271     next_layer() const noexcept;
0272 
0273     //--------------------------------------------------------------------------
0274     //
0275     // Observers
0276     //
0277     //--------------------------------------------------------------------------
0278 
0279     /** Returns `true` if the stream is open.
0280 
0281         The stream is open after a successful handshake, and when
0282         no error has occurred.
0283     */
0284     bool
0285     is_open() const noexcept;
0286 
0287     /** Returns `true` if the latest message data indicates binary.
0288 
0289         This function informs the caller of whether the last
0290         received message frame represents a message with the
0291         binary opcode.
0292 
0293         If there is no last message frame, the return value is
0294         undefined.
0295     */
0296     bool
0297     got_binary() const noexcept;
0298 
0299     /** Returns `true` if the latest message data indicates text.
0300 
0301         This function informs the caller of whether the last
0302         received message frame represents a message with the
0303         text opcode.
0304 
0305         If there is no last message frame, the return value is
0306         undefined.
0307     */
0308     bool
0309     got_text() const
0310     {
0311         return ! got_binary();
0312     }
0313 
0314     /// Returns `true` if the last completed read finished the current message.
0315     bool
0316     is_message_done() const noexcept;
0317 
0318     /** Returns the close reason received from the remote peer.
0319 
0320         This is only valid after a read completes with error::closed.
0321     */
0322     close_reason const&
0323     reason() const noexcept;
0324 
0325     /** Returns a suggested maximum buffer size for the next call to read.
0326 
0327         This function returns a reasonable upper limit on the number
0328         of bytes for the size of the buffer passed in the next call
0329         to read. The number is determined by the state of the current
0330         frame and whether or not the permessage-deflate extension is
0331         enabled.
0332 
0333         @param initial_size A non-zero size representing the caller's
0334         desired buffer size for when there is no information which may
0335         be used to calculate a more specific value. For example, when
0336         reading the first frame header of a message.
0337     */
0338     std::size_t
0339     read_size_hint(
0340         std::size_t initial_size = +tcp_frame_size) const;
0341 
0342     /** Returns a suggested maximum buffer size for the next call to read.
0343 
0344         This function returns a reasonable upper limit on the number
0345         of bytes for the size of the buffer passed in the next call
0346         to read. The number is determined by the state of the current
0347         frame and whether or not the permessage-deflate extension is
0348         enabled.
0349 
0350         @param buffer The buffer which will be used for reading. The
0351         implementation will query the buffer to obtain the optimum
0352         size of a subsequent call to `buffer.prepare` based on the
0353         state of the current frame, if any.
0354     */
0355     template<class DynamicBuffer
0356 #if ! BOOST_BEAST_DOXYGEN
0357         , class = typename std::enable_if<
0358             ! std::is_integral<DynamicBuffer>::value>::type
0359 #endif
0360     >
0361     std::size_t
0362     read_size_hint(
0363         DynamicBuffer& buffer) const;
0364 
0365     //--------------------------------------------------------------------------
0366     //
0367     // Settings
0368     //
0369     //--------------------------------------------------------------------------
0370 
0371 #if BOOST_BEAST_DOXYGEN
0372     /// Get the option value
0373     template<class Option>
0374     void
0375     get_option(Option& opt);
0376 
0377     /// Set the option value
0378     template<class Option>
0379     void
0380     set_option(Option opt);
0381 #else
0382     void set_option(decorator opt);
0383 #endif
0384 
0385     /** Set the timeout option
0386 
0387         @throws system_error on failure to reset the
0388         timer.
0389     */
0390     void
0391     set_option(timeout const& opt);
0392 
0393     /// Get the timeout option
0394     void
0395     get_option(timeout& opt);
0396 
0397     /** Set the permessage-deflate extension options
0398 
0399         @throws invalid_argument if `deflateSupported == false`, and either
0400         `client_enable` or `server_enable` is `true`.
0401     */
0402     void
0403     set_option(permessage_deflate const& o);
0404 
0405     /// Get the permessage-deflate extension options
0406     void
0407     get_option(permessage_deflate& o);
0408 
0409     /** Set the automatic fragmentation option.
0410 
0411         Determines if outgoing message payloads are broken up into
0412         multiple pieces.
0413 
0414         When the automatic fragmentation size is turned on, outgoing
0415         message payloads are broken up into multiple frames no larger
0416         than the write buffer size.
0417 
0418         The default setting is to fragment messages.
0419 
0420         @param value A `bool` indicating if auto fragmentation should be on.
0421 
0422         @par Example
0423         Setting the automatic fragmentation option:
0424         @code
0425             ws.auto_fragment(true);
0426         @endcode
0427     */
0428     void
0429     auto_fragment(bool value);
0430 
0431     /// Returns `true` if the automatic fragmentation option is set.
0432     bool
0433     auto_fragment() const;
0434 
0435     /** Set the binary message write option.
0436 
0437         This controls whether or not outgoing message opcodes
0438         are set to binary or text. The setting is only applied
0439         at the start when a caller begins a new message. Changing
0440         the opcode after a message is started will only take effect
0441         after the current message being sent is complete.
0442 
0443         The default setting is to send text messages.
0444 
0445         @param value `true` if outgoing messages should indicate
0446         binary, or `false` if they should indicate text.
0447 
0448         @par Example
0449         Setting the message type to binary.
0450         @code
0451             ws.binary(true);
0452         @endcode
0453         */
0454     void
0455     binary(bool value);
0456 
0457     /// Returns `true` if the binary message write option is set.
0458     bool
0459     binary() const;
0460 
0461     /** Set a callback to be invoked on each incoming control frame.
0462 
0463         Sets the callback to be invoked whenever a ping, pong,
0464         or close control frame is received during a call to one
0465         of the following functions:
0466 
0467         @li @ref beast::websocket::stream::read
0468         @li @ref beast::websocket::stream::read_some
0469         @li @ref beast::websocket::stream::async_read
0470         @li @ref beast::websocket::stream::async_read_some
0471 
0472         Unlike completion handlers, the callback will be invoked
0473         for each control frame during a call to any synchronous
0474         or asynchronous read function. The operation is passive,
0475         with no associated error code, and triggered by reads.
0476 
0477         For close frames, the close reason code may be obtained by
0478         calling the function @ref reason.
0479 
0480         @param cb The function object to call, which must be
0481         invocable with this equivalent signature:
0482         @code
0483         void
0484         callback(
0485             frame_type kind,       // The type of frame
0486             string_view payload    // The payload in the frame
0487         );
0488         @endcode
0489         The implementation type-erases the callback which may require
0490         a dynamic allocation. To prevent the possibility of a dynamic
0491         allocation, use `std::ref` to wrap the callback.
0492         If the read operation which receives the control frame is
0493         an asynchronous operation, the callback will be invoked using
0494         the same method as that used to invoke the final handler.
0495 
0496         @note Incoming ping and close frames are automatically
0497         handled. Pings are responded to with pongs, and a close frame
0498         is responded to with a close frame leading to the closure of
0499         the stream. It is not necessary to manually send pings, pongs,
0500         or close frames from inside the control callback.
0501         Attempting to manually send a close frame from inside the
0502         control callback after receiving a close frame will result
0503         in undefined behavior.
0504     */
0505     void
0506     control_callback(std::function<void(frame_type, string_view)> cb);
0507 
0508     /** Reset the control frame callback.
0509 
0510         This function removes any previously set control frame callback.
0511     */
0512     void
0513     control_callback();
0514 
0515     /** Set the maximum incoming message size option.
0516 
0517         Sets the largest permissible incoming message size. Message
0518         frame fields indicating a size that would bring the total
0519         message size over this limit will cause a protocol failure.
0520 
0521         The default setting is 16 megabytes. A value of zero indicates
0522         a limit of the maximum value of a `std::uint64_t`.
0523 
0524         @par Example
0525         Setting the maximum read message size.
0526         @code
0527             ws.read_message_max(65536);
0528         @endcode
0529 
0530         @param amount The limit on the size of incoming messages.
0531     */
0532     void
0533     read_message_max(std::size_t amount);
0534 
0535     /// Returns the maximum incoming message size setting.
0536     std::size_t
0537     read_message_max() const;
0538 
0539     /** Set whether the PRNG is cryptographically secure
0540 
0541         This controls whether or not the source of pseudo-random
0542         numbers used to produce the masks required by the WebSocket
0543         protocol are of cryptographic quality. When the setting is
0544         `true`, a strong algorithm is used which cannot be guessed
0545         by observing outputs. When the setting is `false`, a much
0546         faster algorithm is used.
0547         Masking is only performed by streams operating in the client
0548         mode. For streams operating in the server mode, this setting
0549         has no effect.
0550         By default, newly constructed streams use a secure PRNG.
0551 
0552         If the WebSocket stream is used with an encrypted SSL or TLS
0553         next layer, if it is known to the application that intermediate
0554         proxies are not vulnerable to cache poisoning, or if the
0555         application is designed such that an attacker cannot send
0556         arbitrary inputs to the stream interface, then the faster
0557         algorithm may be used.
0558 
0559         For more information please consult the WebSocket protocol RFC.
0560 
0561         @param value `true` if the PRNG algorithm should be
0562         cryptographically secure.
0563     */
0564     void
0565     secure_prng(bool value);
0566 
0567     /** Set the write buffer size option.
0568 
0569         Sets the size of the write buffer used by the implementation to
0570         send frames. The write buffer is needed when masking payload data
0571         in the client role, compressing frames, or auto-fragmenting message
0572         data.
0573 
0574         Lowering the size of the buffer can decrease the memory requirements
0575         for each connection, while increasing the size of the buffer can reduce
0576         the number of calls made to the next layer to write data.
0577 
0578         The default setting is 4096. The minimum value is 8.
0579 
0580         The write buffer size can only be changed when the stream is not
0581         open. Undefined behavior results if the option is modified after a
0582         successful WebSocket handshake.
0583 
0584         @par Example
0585         Setting the write buffer size.
0586         @code
0587             ws.write_buffer_bytes(8192);
0588         @endcode
0589 
0590         @param amount The size of the write buffer in bytes.
0591     */
0592     void
0593     write_buffer_bytes(std::size_t amount);
0594 
0595     /// Returns the size of the write buffer.
0596     std::size_t
0597     write_buffer_bytes() const;
0598 
0599     /** Set the text message write option.
0600 
0601         This controls whether or not outgoing message opcodes
0602         are set to binary or text. The setting is only applied
0603         at the start when a caller begins a new message. Changing
0604         the opcode after a message is started will only take effect
0605         after the current message being sent is complete.
0606 
0607         The default setting is to send text messages.
0608 
0609         @param value `true` if outgoing messages should indicate
0610         text, or `false` if they should indicate binary.
0611 
0612         @par Example
0613         Setting the message type to text.
0614         @code
0615             ws.text(true);
0616         @endcode
0617     */
0618     void
0619     text(bool value);
0620 
0621     /// Returns `true` if the text message write option is set.
0622     bool
0623     text() const;
0624 
0625     /** Set the compress message write option.
0626 
0627         This controls whether or not outgoing messages should be
0628         compressed. The setting is only applied when
0629 
0630         @li The template parameter `deflateSupported` is true
0631         @li Compression is enable. This is controlled with `stream::set_option`
0632         @li Client and server have negotiated permessage-deflate settings
0633         @li The message is larger than `permessage_deflate::msg_size_threshold`
0634 
0635         This function permits adjusting per-message compression.
0636         Changing the opcode after a message is started will only take effect
0637         after the current message being sent is complete.
0638 
0639         The default setting is to compress messages whenever the conditions
0640         above are true.
0641 
0642         @param value `true` if outgoing messages should be compressed
0643 
0644         @par Example
0645         Disabling compression for a single message.
0646         @code
0647             ws.compress(false);
0648             ws.write(net::buffer(s), ec);
0649             ws.compress(true);
0650         @endcode
0651     */
0652     void
0653     compress(bool value);
0654 
0655     /// Returns `true` if the compress message write option is set.
0656     bool
0657     compress() const;
0658 
0659 
0660 
0661     /*
0662         timer settings
0663 
0664         * Timer is disabled
0665         * Close on timeout
0666             - no complete frame received, OR
0667             - no complete frame sent
0668         * Ping on timeout
0669             - ping on no complete frame received
0670                 * if can't ping?
0671     */
0672 
0673     //--------------------------------------------------------------------------
0674     //
0675     // Handshaking (Client)
0676     //
0677     //--------------------------------------------------------------------------
0678 
0679     /** Perform the WebSocket handshake in the client role.
0680 
0681         This function is used to perform the
0682         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
0683         required before messages can be sent and received. During the handshake,
0684         the client sends the Websocket Upgrade HTTP request, and the server
0685         replies with an HTTP response indicating the result of the handshake.
0686 
0687         The call blocks until one of the following conditions is true:
0688 
0689         @li The request is sent and the response is received.
0690 
0691         @li An error occurs.
0692 
0693         The algorithm, known as a <em>composed operation</em>, is implemented
0694         in terms of calls to the next layer's `read_some` and `write_some`
0695         functions.
0696 
0697         The handshake is successful if the received HTTP response
0698         indicates the upgrade was accepted by the server, represented by a
0699         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
0700         of @ref beast::http::status::switching_protocols.
0701 
0702         @param host The name of the remote host. This is required by
0703         the HTTP protocol to set the "Host" header field.
0704 
0705         @param target The request-target, in origin-form. The server may use the
0706         target to distinguish different services on the same listening port.
0707 
0708         @throws system_error Thrown on failure.
0709 
0710         @par Example
0711         @code
0712         ws.handshake("localhost", "/");
0713         @endcode
0714 
0715         @see
0716         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
0717         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
0718         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
0719         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
0720     */
0721     void
0722     handshake(
0723         string_view host,
0724         string_view target);
0725 
0726     /** Perform the WebSocket handshake in the client role.
0727 
0728         This function is used to perform the
0729         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
0730         required before messages can be sent and received. During the handshake,
0731         the client sends the Websocket Upgrade HTTP request, and the server
0732         replies with an HTTP response indicating the result of the handshake.
0733 
0734         The call blocks until one of the following conditions is true:
0735 
0736         @li The request is sent and the response is received.
0737 
0738         @li An error occurs.
0739 
0740         The algorithm, known as a <em>composed operation</em>, is implemented
0741         in terms of calls to the next layer's `read_some` and `write_some`
0742         functions.
0743 
0744         The handshake is successful if the received HTTP response
0745         indicates the upgrade was accepted by the server, represented by a
0746         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
0747         of @ref beast::http::status::switching_protocols.
0748 
0749         @param res The HTTP Upgrade response returned by the remote
0750         endpoint. The caller may use the response to access any
0751         additional information sent by the server. Note that the response object
0752         referenced by this parameter will be updated as long as the stream has
0753         received a valid HTTP response. If not (for example because of a communications
0754         error), the response contents will be undefined except for the result() which
0755         will bet set to 500, Internal Server Error.
0756 
0757         @param host The name of the remote host. This is required by
0758         the HTTP protocol to set the "Host" header field.
0759 
0760         @param target The request-target, in origin-form. The server may use the
0761         target to distinguish different services on the same listening port.
0762 
0763         @throws system_error Thrown on failure.
0764 
0765         @par Example
0766         @code
0767         response_type res;
0768         ws.handshake(res, "localhost", "/");
0769         std::cout << res;
0770         @endcode
0771 
0772         @see
0773         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
0774         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
0775         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
0776         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
0777     */
0778     void
0779     handshake(
0780         response_type& res,
0781         string_view host,
0782         string_view target);
0783 
0784     /** Perform the WebSocket handshake in the client role.
0785 
0786         This function is used to perform the
0787         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
0788         required before messages can be sent and received. During the handshake,
0789         the client sends the Websocket Upgrade HTTP request, and the server
0790         replies with an HTTP response indicating the result of the handshake.
0791 
0792         The call blocks until one of the following conditions is true:
0793 
0794         @li The request is sent and the response is received.
0795 
0796         @li An error occurs.
0797 
0798         The algorithm, known as a <em>composed operation</em>, is implemented
0799         in terms of calls to the next layer's `read_some` and `write_some`
0800         functions.
0801 
0802         The handshake is successful if the received HTTP response
0803         indicates the upgrade was accepted by the server, represented by a
0804         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
0805         of @ref beast::http::status::switching_protocols.
0806 
0807         @param host The name of the remote host. This is required by
0808         the HTTP protocol to set the "Host" header field.
0809 
0810         @param target The request-target, in origin-form. The server may use the
0811         target to distinguish different services on the same listening port.
0812 
0813         @param ec Set to indicate what error occurred, if any.
0814 
0815         @par Example
0816         @code
0817         error_code ec;
0818         ws.handshake("localhost", "/", ec);
0819         @endcode
0820 
0821         @see
0822         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
0823         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
0824         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
0825         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
0826     */
0827     void
0828     handshake(
0829         string_view host,
0830         string_view target,
0831         error_code& ec);
0832 
0833     /** Perform the WebSocket handshake in the client role.
0834 
0835         This function is used to perform the
0836         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
0837         required before messages can be sent and received. During the handshake,
0838         the client sends the Websocket Upgrade HTTP request, and the server
0839         replies with an HTTP response indicating the result of the handshake.
0840 
0841         The call blocks until one of the following conditions is true:
0842 
0843         @li The request is sent and the response is received.
0844 
0845         @li An error occurs.
0846 
0847         The algorithm, known as a <em>composed operation</em>, is implemented
0848         in terms of calls to the next layer's `read_some` and `write_some`
0849         functions.
0850 
0851         The handshake is successful if the received HTTP response
0852         indicates the upgrade was accepted by the server, represented by a
0853         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
0854         of @ref beast::http::status::switching_protocols.
0855 
0856         @param res The HTTP Upgrade response returned by the remote
0857         endpoint. The caller may use the response to access any
0858         additional information sent by the server.
0859 
0860         @param host The name of the remote host. This is required by
0861         the HTTP protocol to set the "Host" header field.
0862 
0863         @param target The request-target, in origin-form. The server may use the
0864         target to distinguish different services on the same listening port.
0865 
0866         @param ec Set to indicate what error occurred, if any.
0867 
0868         @par Example
0869         @code
0870         error_code ec;
0871         response_type res;
0872         ws.handshake(res, "localhost", "/", ec);
0873         if(! ec)
0874             std::cout << res;
0875         @endcode
0876 
0877         @see
0878         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
0879         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
0880         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
0881         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
0882     */
0883     void
0884     handshake(
0885         response_type& res,
0886         string_view host,
0887         string_view target,
0888         error_code& ec);
0889 
0890     /** Perform the WebSocket handshake asynchronously in the client role.
0891 
0892         This initiating function is used to asynchronously begin performing the
0893         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
0894         required before messages can be sent and received. During the handshake,
0895         the client sends the Websocket Upgrade HTTP request, and the server
0896         replies with an HTTP response indicating the result of the handshake.
0897 
0898         This call always returns immediately. The asynchronous operation
0899         will continue until one of the following conditions is true:
0900 
0901         @li The request is sent and the response is received.
0902 
0903         @li An error occurs.
0904 
0905         The algorithm, known as a <em>composed asynchronous operation</em>,
0906         is implemented in terms of calls to the next layer's `async_read_some`
0907         and `async_write_some` functions. No other operation may be performed
0908         on the stream until this operation completes.
0909 
0910         The handshake is successful if the received HTTP response
0911         indicates the upgrade was accepted by the server, represented by a
0912         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
0913         of @ref beast::http::status::switching_protocols.
0914 
0915         @param host The name of the remote host. This is required by
0916         the HTTP protocol to set the "Host" header field.
0917         The implementation will not access the string data after the
0918         initiating function returns.
0919 
0920         @param target The request-target, in origin-form. The server may use the
0921         target to distinguish different services on the same listening port.
0922         The implementation will not access the string data after the
0923         initiating function returns.
0924 
0925         @param handler The completion handler to invoke when the operation
0926         completes. The implementation takes ownership of the handler by
0927         performing a decay-copy. The equivalent function signature of
0928         the handler must be:
0929         @code
0930         void handler(
0931             error_code const& ec    // Result of operation
0932         );
0933         @endcode
0934         If the handler has an associated immediate executor,
0935         an immediate completion will be dispatched to it.
0936         Otherwise, the handler will not be invoked from within
0937         this function. Invocation of the handler will be performed
0938         by dispatching to the immediate executor. If no
0939         immediate executor is specified, this is equivalent
0940         to using `net::post`.
0941         @par Example
0942         @code
0943         ws.async_handshake("localhost", "/",
0944             [](error_code ec)
0945             {
0946                 if(ec)
0947                     std::cerr << "Error: " << ec.message() << "\n";
0948             });
0949         @endcode
0950 
0951         @see
0952         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
0953         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
0954         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
0955         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
0956     */
0957     template<
0958         BOOST_BEAST_ASYNC_TPARAM1 HandshakeHandler =
0959             net::default_completion_token_t<executor_type>
0960     >
0961     BOOST_BEAST_ASYNC_RESULT1(HandshakeHandler)
0962     async_handshake(
0963         string_view host,
0964         string_view target,
0965         HandshakeHandler&& handler =
0966             net::default_completion_token_t<
0967                 executor_type>{});
0968 
0969     /** Perform the WebSocket handshake asynchronously in the client role.
0970 
0971         This initiating function is used to asynchronously begin performing the
0972         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
0973         required before messages can be sent and received. During the handshake,
0974         the client sends the Websocket Upgrade HTTP request, and the server
0975         replies with an HTTP response indicating the result of the handshake.
0976 
0977         This call always returns immediately. The asynchronous operation
0978         will continue until one of the following conditions is true:
0979 
0980         @li The request is sent and the response is received.
0981 
0982         @li An error occurs.
0983 
0984         The algorithm, known as a <em>composed asynchronous operation</em>,
0985         is implemented in terms of calls to the next layer's `async_read_some`
0986         and `async_write_some` functions. No other operation may be performed
0987         on the stream until this operation completes.
0988 
0989         The handshake is successful if the received HTTP response
0990         indicates the upgrade was accepted by the server, represented by a
0991         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
0992         of @ref beast::http::status::switching_protocols.
0993 
0994         @param res The HTTP Upgrade response returned by the remote
0995         endpoint. The caller may use the response to access any
0996         additional information sent by the server. This object will
0997         be assigned before the completion handler is invoked.
0998 
0999         @param host The name of the remote host. This is required by
1000         the HTTP protocol to set the "Host" header field.
1001         The implementation will not access the string data after the
1002         initiating function returns.
1003 
1004         @param target The request-target, in origin-form. The server may use the
1005         target to distinguish different services on the same listening port.
1006         The implementation will not access the string data after the
1007         initiating function returns.
1008 
1009         @param handler The completion handler to invoke when the operation
1010         completes. The implementation takes ownership of the handler by
1011         performing a decay-copy. The equivalent function signature of
1012         the handler must be:
1013         @code
1014         void handler(
1015             error_code const& ec    // Result of operation
1016         );
1017         @endcode
1018         If the handler has an associated immediate executor,
1019         an immediate completion will be dispatched to it.
1020         Otherwise, the handler will not be invoked from within
1021         this function. Invocation of the handler will be performed
1022         by dispatching to the immediate executor. If no
1023         immediate executor is specified, this is equivalent
1024         to using `net::post`.
1025         @par Example
1026         @code
1027         response_type res;
1028         ws.async_handshake(res, "localhost", "/",
1029             [&res](error_code ec)
1030             {
1031                 if(ec)
1032                     std::cerr << "Error: " << ec.message() << "\n";
1033                 else
1034                     std::cout << res;
1035 
1036             });
1037         @endcode
1038 
1039         @see
1040         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.1">Websocket Opening Handshake Client Requirements (RFC6455)</a>
1041         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.4">Host field (RFC7230)</a>
1042         @li <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">request-target (RFC7230)</a>
1043         @li <a href="https://tools.ietf.org/html/rfc7230#section-5.3.1">origin-form (RFC7230)</a>
1044     */
1045     template<
1046         BOOST_BEAST_ASYNC_TPARAM1 HandshakeHandler =
1047             net::default_completion_token_t<executor_type>
1048     >
1049     BOOST_BEAST_ASYNC_RESULT1(HandshakeHandler)
1050     async_handshake(
1051         response_type& res,
1052         string_view host,
1053         string_view target,
1054         HandshakeHandler&& handler =
1055             net::default_completion_token_t<
1056                 executor_type>{});
1057 
1058     //--------------------------------------------------------------------------
1059     //
1060     // Handshaking (Server)
1061     //
1062     //--------------------------------------------------------------------------
1063 
1064     /** Perform the WebSocket handshake in the server role.
1065 
1066         This function is used to perform the
1067         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1068         required before messages can be sent and received. During the handshake,
1069         the client sends the Websocket Upgrade HTTP request, and the server
1070         replies with an HTTP response indicating the result of the handshake.
1071 
1072         The call blocks until one of the following conditions is true:
1073 
1074         @li The request is received and the response is sent.
1075 
1076         @li An error occurs.
1077 
1078         The algorithm, known as a <em>composed operation</em>, is implemented
1079         in terms of calls to the next layer's `read_some` and `write_some`
1080         functions.
1081 
1082         If a valid upgrade request is received, an HTTP response with a
1083         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1084         of @ref beast::http::status::switching_protocols is sent to
1085         the peer, otherwise a non-successful error is associated with
1086         the operation.
1087 
1088         If the request size exceeds the capacity of the stream's
1089         internal buffer, the error @ref error::buffer_overflow will be
1090         indicated. To handle larger requests, an application should
1091         read the HTTP request directly using @ref http::read and then
1092         pass the request to the appropriate overload of @ref accept or
1093         @ref async_accept
1094 
1095         @throws system_error Thrown on failure.
1096 
1097         @see
1098         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1099     */
1100     void
1101     accept();
1102 
1103     /** Read and respond to a WebSocket HTTP Upgrade request.
1104 
1105         This function is used to perform the
1106         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1107         required before messages can be sent and received. During the handshake,
1108         the client sends the Websocket Upgrade HTTP request, and the server
1109         replies with an HTTP response indicating the result of the handshake.
1110 
1111         The call blocks until one of the following conditions is true:
1112 
1113         @li The request is received and the response is sent.
1114 
1115         @li An error occurs.
1116 
1117         The algorithm, known as a <em>composed operation</em>, is implemented
1118         in terms of calls to the next layer's `read_some` and `write_some`
1119         functions.
1120 
1121         If a valid upgrade request is received, an HTTP response with a
1122         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1123         of @ref beast::http::status::switching_protocols is sent to
1124         the peer, otherwise a non-successful error is associated with
1125         the operation.
1126 
1127         If the request size exceeds the capacity of the stream's
1128         internal buffer, the error @ref error::buffer_overflow will be
1129         indicated. To handle larger requests, an application should
1130         read the HTTP request directly using @ref http::read and then
1131         pass the request to the appropriate overload of @ref accept or
1132         @ref async_accept
1133 
1134         @param ec Set to indicate what error occurred, if any.
1135 
1136         @see
1137         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1138     */
1139     void
1140     accept(error_code& ec);
1141 
1142     /** Read and respond to a WebSocket HTTP Upgrade request.
1143 
1144         This function is used to perform the
1145         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1146         required before messages can be sent and received. During the handshake,
1147         the client sends the Websocket Upgrade HTTP request, and the server
1148         replies with an HTTP response indicating the result of the handshake.
1149 
1150         The call blocks until one of the following conditions is true:
1151 
1152         @li The request is received and the response is sent.
1153 
1154         @li An error occurs.
1155 
1156         The algorithm, known as a <em>composed operation</em>, is implemented
1157         in terms of calls to the next layer's `read_some` and `write_some`
1158         functions.
1159 
1160         If a valid upgrade request is received, an HTTP response with a
1161         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1162         of @ref beast::http::status::switching_protocols is sent to
1163         the peer, otherwise a non-successful error is associated with
1164         the operation.
1165 
1166         If the request size exceeds the capacity of the stream's
1167         internal buffer, the error @ref error::buffer_overflow will be
1168         indicated. To handle larger requests, an application should
1169         read the HTTP request directly using @ref http::read and then
1170         pass the request to the appropriate overload of @ref accept or
1171         @ref async_accept
1172 
1173         @param buffers Caller provided data that has already been
1174         received on the stream. The implementation will copy the
1175         caller provided data before the function returns.
1176 
1177         @throws system_error Thrown on failure.
1178 
1179         @see
1180         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1181     */
1182     template<class ConstBufferSequence>
1183 #if BOOST_BEAST_DOXYGEN
1184     void
1185 #else
1186     typename std::enable_if<! http::detail::is_header<
1187         ConstBufferSequence>::value>::type
1188 #endif
1189     accept(ConstBufferSequence const& buffers);
1190 
1191     /** Read and respond to a WebSocket HTTP Upgrade request.
1192 
1193         This function is used to perform the
1194         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1195         required before messages can be sent and received. During the handshake,
1196         the client sends the Websocket Upgrade HTTP request, and the server
1197         replies with an HTTP response indicating the result of the handshake.
1198 
1199         The call blocks until one of the following conditions is true:
1200 
1201         @li The request is received and the response is sent.
1202 
1203         @li An error occurs.
1204 
1205         The algorithm, known as a <em>composed operation</em>, is implemented
1206         in terms of calls to the next layer's `read_some` and `write_some`
1207         functions.
1208 
1209         If a valid upgrade request is received, an HTTP response with a
1210         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1211         of @ref beast::http::status::switching_protocols is sent to
1212         the peer, otherwise a non-successful error is associated with
1213         the operation.
1214 
1215         If the request size exceeds the capacity of the stream's
1216         internal buffer, the error @ref error::buffer_overflow will be
1217         indicated. To handle larger requests, an application should
1218         read the HTTP request directly using @ref http::read and then
1219         pass the request to the appropriate overload of @ref accept or
1220         @ref async_accept
1221 
1222         @param buffers Caller provided data that has already been
1223         received on the stream. The implementation will copy the
1224         caller provided data before the function returns.
1225 
1226         @param ec Set to indicate what error occurred, if any.
1227 
1228         @see
1229         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1230     */
1231     template<class ConstBufferSequence>
1232 #if BOOST_BEAST_DOXYGEN
1233     void
1234 #else
1235     typename std::enable_if<! http::detail::is_header<
1236         ConstBufferSequence>::value>::type
1237 #endif
1238     accept(
1239         ConstBufferSequence const& buffers,
1240         error_code& ec);
1241 
1242     /** Respond to a WebSocket HTTP Upgrade request
1243 
1244         This function is used to perform the
1245         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1246         required before messages can be sent and received. During the handshake,
1247         the client sends the Websocket Upgrade HTTP request, and the server
1248         replies with an HTTP response indicating the result of the handshake.
1249 
1250         The call blocks until one of the following conditions is true:
1251 
1252         @li The response is sent.
1253 
1254         @li An error occurs.
1255 
1256         The algorithm, known as a <em>composed operation</em>, is implemented
1257         in terms of calls to the next layer's `read_some` and `write_some`
1258         functions.
1259 
1260         If a valid upgrade request is received, an HTTP response with a
1261         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1262         of @ref beast::http::status::switching_protocols is sent to
1263         the peer, otherwise a non-successful error is associated with
1264         the operation.
1265 
1266         @param req An object containing the HTTP Upgrade request.
1267         Ownership is not transferred, the implementation will not
1268         access this object from other threads.
1269 
1270         @throws system_error Thrown on failure.
1271 
1272         @see
1273         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1274     */
1275     template<class Body, class Allocator>
1276     void
1277     accept(http::request<Body,
1278         http::basic_fields<Allocator>> const& req);
1279 
1280     /** Respond to a WebSocket HTTP Upgrade request
1281 
1282         This function is used to perform the
1283         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1284         required before messages can be sent and received. During the handshake,
1285         the client sends the Websocket Upgrade HTTP request, and the server
1286         replies with an HTTP response indicating the result of the handshake.
1287 
1288         The call blocks until one of the following conditions is true:
1289 
1290         @li The response is sent.
1291 
1292         @li An error occurs.
1293 
1294         The algorithm, known as a <em>composed operation</em>, is implemented
1295         in terms of calls to the next layer's `read_some` and `write_some`
1296         functions.
1297 
1298         If a valid upgrade request is received, an HTTP response with a
1299         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1300         of @ref beast::http::status::switching_protocols is sent to
1301         the peer, otherwise a non-successful error is associated with
1302         the operation.
1303 
1304         @param req An object containing the HTTP Upgrade request.
1305         Ownership is not transferred, the implementation will not
1306         access this object from other threads.
1307 
1308         @param ec Set to indicate what error occurred, if any.
1309 
1310         @see
1311         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1312     */
1313     template<class Body, class Allocator>
1314     void
1315     accept(http::request<Body,
1316         http::basic_fields<Allocator>> const& req,
1317             error_code& ec);
1318 
1319     /** Perform the WebSocket handshake asynchronously in the server role.
1320 
1321         This initiating function is used to asynchronously begin performing the
1322         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1323         required before messages can be sent and received. During the handshake,
1324         the client sends the Websocket Upgrade HTTP request, and the server
1325         replies with an HTTP response indicating the result of the handshake.
1326 
1327         This call always returns immediately. The asynchronous operation
1328         will continue until one of the following conditions is true:
1329 
1330         @li The request is received and the response is sent.
1331 
1332         @li An error occurs.
1333 
1334         The algorithm, known as a <em>composed asynchronous operation</em>,
1335         is implemented in terms of calls to the next layer's `async_read_some`
1336         and `async_write_some` functions. No other operation may be performed
1337         on the stream until this operation completes.
1338 
1339         If a valid upgrade request is received, an HTTP response with a
1340         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1341         of @ref beast::http::status::switching_protocols is sent to
1342         the peer, otherwise a non-successful error is associated with
1343         the operation.
1344 
1345         If the request size exceeds the capacity of the stream's
1346         internal buffer, the error @ref error::buffer_overflow will be
1347         indicated. To handle larger requests, an application should
1348         read the HTTP request directly using @ref http::async_read and then
1349         pass the request to the appropriate overload of @ref accept or
1350         @ref async_accept
1351 
1352         @param handler The completion handler to invoke when the operation
1353         completes. The implementation takes ownership of the handler by
1354         performing a decay-copy. The equivalent function signature of
1355         the handler must be:
1356         @code
1357         void handler(
1358             error_code const& ec    // Result of operation
1359         );
1360         @endcode
1361         If the handler has an associated immediate executor,
1362         an immediate completion will be dispatched to it.
1363         Otherwise, the handler will not be invoked from within
1364         this function. Invocation of the handler will be performed
1365         by dispatching to the immediate executor. If no
1366         immediate executor is specified, this is equivalent
1367         to using `net::post`.
1368         @see
1369         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1370     */
1371     template<
1372         BOOST_BEAST_ASYNC_TPARAM1 AcceptHandler =
1373             net::default_completion_token_t<executor_type>
1374     >
1375     BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
1376     async_accept(
1377         AcceptHandler&& handler =
1378             net::default_completion_token_t<
1379                 executor_type>{});
1380 
1381     /** Perform the WebSocket handshake asynchronously in the server role.
1382 
1383         This initiating function is used to asynchronously begin performing the
1384         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1385         required before messages can be sent and received. During the handshake,
1386         the client sends the Websocket Upgrade HTTP request, and the server
1387         replies with an HTTP response indicating the result of the handshake.
1388 
1389         This call always returns immediately. The asynchronous operation
1390         will continue until one of the following conditions is true:
1391 
1392         @li The request is received and the response is sent.
1393 
1394         @li An error occurs.
1395 
1396         The algorithm, known as a <em>composed asynchronous operation</em>,
1397         is implemented in terms of calls to the next layer's `async_read_some`
1398         and `async_write_some` functions. No other operation may be performed
1399         on the stream until this operation completes.
1400 
1401         If a valid upgrade request is received, an HTTP response with a
1402         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1403         of @ref beast::http::status::switching_protocols is sent to
1404         the peer, otherwise a non-successful error is associated with
1405         the operation.
1406 
1407         If the request size exceeds the capacity of the stream's
1408         internal buffer, the error @ref error::buffer_overflow will be
1409         indicated. To handle larger requests, an application should
1410         read the HTTP request directly using @ref http::async_read and then
1411         pass the request to the appropriate overload of @ref accept or
1412         @ref async_accept
1413 
1414         @param buffers Caller provided data that has already been
1415         received on the stream. This may be used for implementations
1416         allowing multiple protocols on the same stream. The
1417         buffered data will first be applied to the handshake, and
1418         then to received WebSocket frames. The implementation will
1419         copy the caller provided data before the function returns.
1420 
1421         @param handler The completion handler to invoke when the operation
1422         completes. The implementation takes ownership of the handler by
1423         performing a decay-copy. The equivalent function signature of
1424         the handler must be:
1425         @code
1426         void handler(
1427             error_code const& ec    // Result of operation
1428         );
1429         @endcode
1430         If the handler has an associated immediate executor,
1431         an immediate completion will be dispatched to it.
1432         Otherwise, the handler will not be invoked from within
1433         this function. Invocation of the handler will be performed
1434         by dispatching to the immediate executor. If no
1435         immediate executor is specified, this is equivalent
1436         to using `net::post`.
1437         @see
1438         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1439     */
1440     template<
1441         class ConstBufferSequence,
1442         BOOST_BEAST_ASYNC_TPARAM1 AcceptHandler =
1443             net::default_completion_token_t<executor_type>
1444     >
1445     BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
1446     async_accept(
1447         ConstBufferSequence const& buffers,
1448         AcceptHandler&& handler =
1449             net::default_completion_token_t<
1450                 executor_type>{}
1451 #ifndef BOOST_BEAST_DOXYGEN
1452         , typename std::enable_if<
1453             ! http::detail::is_header<
1454             ConstBufferSequence>::value>::type* = 0
1455 #endif
1456     );
1457 
1458     /** Perform the WebSocket handshake asynchronously in the server role.
1459 
1460         This initiating function is used to asynchronously begin performing the
1461         <a href="https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake">WebSocket handshake</a>,
1462         required before messages can be sent and received. During the handshake,
1463         the client sends the Websocket Upgrade HTTP request, and the server
1464         replies with an HTTP response indicating the result of the handshake.
1465 
1466         This call always returns immediately. The asynchronous operation
1467         will continue until one of the following conditions is true:
1468 
1469         @li The request is received and the response is sent.
1470 
1471         @li An error occurs.
1472 
1473         The algorithm, known as a <em>composed asynchronous operation</em>,
1474         is implemented in terms of calls to the next layer's `async_read_some`
1475         and `async_write_some` functions. No other operation may be performed
1476         on the stream until this operation completes.
1477 
1478         If a valid upgrade request is received, an HTTP response with a
1479         <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">status-code</a>
1480         of @ref beast::http::status::switching_protocols is sent to
1481         the peer, otherwise a non-successful error is associated with
1482         the operation.
1483 
1484         @param req An object containing the HTTP Upgrade request.
1485         Ownership is not transferred, the implementation will not access
1486         this object from other threads.
1487 
1488         @param handler The completion handler to invoke when the operation
1489         completes. The implementation takes ownership of the handler by
1490         performing a decay-copy. The equivalent function signature of
1491         the handler must be:
1492         @code
1493         void handler(
1494             error_code const& ec    // Result of operation
1495         );
1496         @endcode
1497         If the handler has an associated immediate executor,
1498         an immediate completion will be dispatched to it.
1499         Otherwise, the handler will not be invoked from within
1500         this function. Invocation of the handler will be performed
1501         by dispatching to the immediate executor. If no
1502         immediate executor is specified, this is equivalent
1503         to using `net::post`.
1504         @see
1505         @li <a href="https://tools.ietf.org/html/rfc6455#section-4.2">Websocket Opening Handshake Server Requirements (RFC6455)</a>
1506     */
1507     template<
1508         class Body, class Allocator,
1509         BOOST_BEAST_ASYNC_TPARAM1 AcceptHandler =
1510             net::default_completion_token_t<executor_type>
1511     >
1512     BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
1513     async_accept(
1514         http::request<Body,
1515             http::basic_fields<Allocator>> const& req,
1516         AcceptHandler&& handler =
1517             net::default_completion_token_t<
1518                 executor_type>{});
1519 
1520     //--------------------------------------------------------------------------
1521     //
1522     // Close Frames
1523     //
1524     //--------------------------------------------------------------------------
1525 
1526     /** Send a websocket close control frame.
1527 
1528         This function is used to send a
1529         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close frame</a>,
1530         which begins the websocket closing handshake. The session ends when
1531         both ends of the connection have sent and received a close frame.
1532 
1533         The call blocks until one of the following conditions is true:
1534 
1535         @li The close frame is written.
1536 
1537         @li An error occurs.
1538 
1539         The algorithm, known as a <em>composed operation</em>, is implemented
1540         in terms of calls to the next layer's `write_some` function.
1541 
1542         After beginning the closing handshake, the program should not write
1543         further message data, pings, or pongs. Instead, the program should
1544         continue reading message data until an error occurs. A read returning
1545         @ref error::closed indicates a successful connection closure.
1546 
1547         @param cr The reason for the close.
1548         If the close reason specifies a close code other than
1549         @ref beast::websocket::close_code::none, the close frame is
1550         sent with the close code and optional reason string. Otherwise,
1551         the close frame is sent with no payload.
1552 
1553         @throws system_error Thrown on failure.
1554 
1555         @see
1556         @li <a href="https://tools.ietf.org/html/rfc6455#section-7.1.2">Websocket Closing Handshake (RFC6455)</a>
1557     */
1558     void
1559     close(close_reason const& cr);
1560 
1561     /** Send a websocket close control frame.
1562 
1563         This function is used to send a
1564         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close frame</a>,
1565         which begins the websocket closing handshake. The session ends when
1566         both ends of the connection have sent and received a close frame.
1567 
1568         The call blocks until one of the following conditions is true:
1569 
1570         @li The close frame is written.
1571 
1572         @li An error occurs.
1573 
1574         The algorithm, known as a <em>composed operation</em>, is implemented
1575         in terms of calls to the next layer's `write_some` function.
1576 
1577         After beginning the closing handshake, the program should not write
1578         further message data, pings, or pongs. Instead, the program should
1579         continue reading message data until an error occurs. A read returning
1580         @ref error::closed indicates a successful connection closure.
1581 
1582         @param cr The reason for the close.
1583         If the close reason specifies a close code other than
1584         @ref beast::websocket::close_code::none, the close frame is
1585         sent with the close code and optional reason string. Otherwise,
1586         the close frame is sent with no payload.
1587 
1588         @param ec Set to indicate what error occurred, if any.
1589 
1590         @see
1591         @li <a href="https://tools.ietf.org/html/rfc6455#section-7.1.2">Websocket Closing Handshake (RFC6455)</a>
1592     */
1593     void
1594     close(close_reason const& cr, error_code& ec);
1595 
1596     /** Send a websocket close control frame asynchronously.
1597 
1598         This function is used to asynchronously send a
1599         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close frame</a>,
1600         which begins the websocket closing handshake. The session ends when
1601         both ends of the connection have sent and received a close frame.
1602 
1603         This call always returns immediately. The asynchronous operation
1604         will continue until one of the following conditions is true:
1605 
1606         @li The close frame finishes sending.
1607 
1608         @li An error occurs.
1609 
1610         The algorithm, known as a <em>composed asynchronous operation</em>,
1611         is implemented in terms of calls to the next layer's `async_write_some`
1612         function. No other operations except for message reading operations
1613         should be initiated on the stream after a close operation is started.
1614 
1615         After beginning the closing handshake, the program should not write
1616         further message data, pings, or pongs. Instead, the program should
1617         continue reading message data until an error occurs. A read returning
1618         @ref error::closed indicates a successful connection closure.
1619 
1620         @param cr The reason for the close.
1621         If the close reason specifies a close code other than
1622         @ref beast::websocket::close_code::none, the close frame is
1623         sent with the close code and optional reason string. Otherwise,
1624         the close frame is sent with no payload.
1625 
1626         @param handler The completion handler to invoke when the operation
1627         completes. The implementation takes ownership of the handler by
1628         performing a decay-copy. The equivalent function signature of
1629         the handler must be:
1630         @code
1631         void handler(
1632             error_code const& ec     // Result of operation
1633         );
1634         @endcode
1635         If the handler has an associated immediate executor,
1636         an immediate completion will be dispatched to it.
1637         Otherwise, the handler will not be invoked from within
1638         this function. Invocation of the handler will be performed
1639         by dispatching to the immediate executor. If no
1640         immediate executor is specified, this is equivalent
1641         to using `net::post`.
1642          @par Per-Operation Cancellation
1643 
1644         This asynchronous operation supports cancellation for the following
1645         net::cancellation_type values:
1646 
1647         @li @c net::cancellation_type::terminal
1648         @li @c net::cancellation_type::total
1649 
1650         `total` cancellation succeeds if the operation is suspended due to ongoing
1651         control operations such as a ping/pong.
1652         `terminal` cancellation succeeds when supported by the underlying stream.
1653 
1654         @note `terminal` cancellation will may close the underlying socket.
1655 
1656         @see
1657         @li <a href="https://tools.ietf.org/html/rfc6455#section-7.1.2">Websocket Closing Handshake (RFC6455)</a>
1658     */
1659     template<
1660         BOOST_BEAST_ASYNC_TPARAM1 CloseHandler =
1661             net::default_completion_token_t<executor_type>
1662     >
1663     BOOST_BEAST_ASYNC_RESULT1(CloseHandler)
1664     async_close(
1665         close_reason const& cr,
1666         CloseHandler&& handler =
1667             net::default_completion_token_t<
1668                 executor_type>{});
1669 
1670     //--------------------------------------------------------------------------
1671     //
1672     // Ping/Pong Frames
1673     //
1674     //--------------------------------------------------------------------------
1675 
1676     /** Send a websocket ping control frame.
1677 
1678         This function is used to send a
1679         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">ping frame</a>,
1680         which usually elicits an automatic pong control frame response from
1681         the peer.
1682 
1683         The call blocks until one of the following conditions is true:
1684 
1685         @li The ping frame is written.
1686 
1687         @li An error occurs.
1688 
1689         The algorithm, known as a <em>composed operation</em>, is implemented
1690         in terms of calls to the next layer's `write_some` function.
1691 
1692         @param payload The payload of the ping message, which may be empty.
1693 
1694         @throws system_error Thrown on failure.
1695     */
1696     void
1697     ping(ping_data const& payload);
1698 
1699     /** Send a websocket ping control frame.
1700 
1701         This function is used to send a
1702         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">ping frame</a>,
1703         which usually elicits an automatic pong control frame response from
1704         the peer.
1705 
1706         The call blocks until one of the following conditions is true:
1707 
1708         @li The ping frame is written.
1709 
1710         @li An error occurs.
1711 
1712         The algorithm, known as a <em>composed operation</em>, is implemented
1713         in terms of calls to the next layer's `write_some` function.
1714 
1715         @param payload The payload of the ping message, which may be empty.
1716 
1717         @param ec Set to indicate what error occurred, if any.
1718     */
1719     void
1720     ping(ping_data const& payload, error_code& ec);
1721 
1722     /** Send a websocket ping control frame asynchronously.
1723 
1724         This function is used to asynchronously send a
1725         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">ping frame</a>,
1726         which usually elicits an automatic pong control frame response from
1727         the peer.
1728 
1729         @li The ping frame is written.
1730 
1731         @li An error occurs.
1732 
1733         The algorithm, known as a <em>composed asynchronous operation</em>,
1734         is implemented in terms of calls to the next layer's `async_write_some`
1735         function. The program must ensure that no other calls to @ref ping,
1736         @ref pong, @ref async_ping, or @ref async_pong are performed until
1737         this operation completes.
1738 
1739         If a close frame is sent or received before the ping frame is
1740         sent, the error received by this completion handler will be
1741         `net::error::operation_aborted`.
1742 
1743         @param payload The payload of the ping message, which may be empty.
1744         The implementation will not access the contents of this object after
1745         the initiating function returns.
1746 
1747         @param handler The completion handler to invoke when the operation
1748         completes. The implementation takes ownership of the handler by
1749         performing a decay-copy. The equivalent function signature of
1750         the handler must be:
1751         @code
1752         void handler(
1753             error_code const& ec     // Result of operation
1754         );
1755         @endcode
1756         If the handler has an associated immediate executor,
1757         an immediate completion will be dispatched to it.
1758         Otherwise, the handler will not be invoked from within
1759         this function. Invocation of the handler will be performed
1760         by dispatching to the immediate executor. If no
1761         immediate executor is specified, this is equivalent
1762         to using `net::post`.
1763         @par Per-Operation Cancellation
1764 
1765         This asynchronous operation supports cancellation for the following
1766         net::cancellation_type values:
1767 
1768         @li @c net::cancellation_type::terminal
1769         @li @c net::cancellation_type::total
1770 
1771         `total` cancellation succeeds if the operation is suspended due to ongoing
1772         control operations such as a ping/pong.
1773         `terminal` cancellation succeeds when supported by the underlying stream.
1774 
1775         `terminal` cancellation leaves the stream in an undefined state,
1776         so that only closing it is guaranteed to succeed.
1777     */
1778     template<
1779         BOOST_BEAST_ASYNC_TPARAM1 PingHandler =
1780             net::default_completion_token_t<executor_type>
1781     >
1782     BOOST_BEAST_ASYNC_RESULT1(PingHandler)
1783     async_ping(
1784         ping_data const& payload,
1785         PingHandler&& handler =
1786             net::default_completion_token_t<
1787                 executor_type>{});
1788 
1789     /** Send a websocket pong control frame.
1790 
1791         This function is used to send a
1792         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pong frame</a>,
1793         which is usually sent automatically in response to a ping frame
1794         from the remote peer.
1795 
1796         The call blocks until one of the following conditions is true:
1797 
1798         @li The pong frame is written.
1799 
1800         @li An error occurs.
1801 
1802         The algorithm, known as a <em>composed operation</em>, is implemented
1803         in terms of calls to the next layer's `write_some` function.
1804 
1805         WebSocket allows pong frames to be sent at any time, without first
1806         receiving a ping. An unsolicited pong sent in this fashion may
1807         indicate to the remote peer that the connection is still active.
1808 
1809         @param payload The payload of the pong message, which may be empty.
1810 
1811         @throws system_error Thrown on failure.
1812     */
1813     void
1814     pong(ping_data const& payload);
1815 
1816     /** Send a websocket pong control frame.
1817 
1818         This function is used to send a
1819         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pong frame</a>,
1820         which is usually sent automatically in response to a ping frame
1821         from the remote peer.
1822 
1823         The call blocks until one of the following conditions is true:
1824 
1825         @li The pong frame is written.
1826 
1827         @li An error occurs.
1828 
1829         The algorithm, known as a <em>composed operation</em>, is implemented
1830         in terms of calls to the next layer's `write_some` function.
1831 
1832         WebSocket allows pong frames to be sent at any time, without first
1833         receiving a ping. An unsolicited pong sent in this fashion may
1834         indicate to the remote peer that the connection is still active.
1835 
1836         @param payload The payload of the pong message, which may be empty.
1837 
1838         @param ec Set to indicate what error occurred, if any.
1839     */
1840     void
1841     pong(ping_data const& payload, error_code& ec);
1842 
1843     /** Send a websocket pong control frame asynchronously.
1844 
1845         This function is used to asynchronously send a
1846         <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pong frame</a>,
1847         which is usually sent automatically in response to a ping frame
1848         from the remote peer.
1849 
1850         @li The pong frame is written.
1851 
1852         @li An error occurs.
1853 
1854         The algorithm, known as a <em>composed asynchronous operation</em>,
1855         is implemented in terms of calls to the next layer's `async_write_some`
1856         function. The program must ensure that no other calls to @ref ping,
1857         @ref pong, @ref async_ping, or @ref async_pong are performed until
1858         this operation completes.
1859 
1860         If a close frame is sent or received before the pong frame is
1861         sent, the error received by this completion handler will be
1862         `net::error::operation_aborted`.
1863 
1864         WebSocket allows pong frames to be sent at any time, without first
1865         receiving a ping. An unsolicited pong sent in this fashion may
1866         indicate to the remote peer that the connection is still active.
1867 
1868         @param payload The payload of the pong message, which may be empty.
1869         The implementation will not access the contents of this object after
1870         the initiating function returns.
1871 
1872         @param handler The completion handler to invoke when the operation
1873         completes. The implementation takes ownership of the handler by
1874         performing a decay-copy. The equivalent function signature of
1875         the handler must be:
1876         @code
1877         void handler(
1878             error_code const& ec     // Result of operation
1879         );
1880         @endcode
1881         If the handler has an associated immediate executor,
1882         an immediate completion will be dispatched to it.
1883         Otherwise, the handler will not be invoked from within
1884         this function. Invocation of the handler will be performed
1885         by dispatching to the immediate executor. If no
1886         immediate executor is specified, this is equivalent
1887         to using `net::post`.
1888         @par Per-Operation Cancellation
1889 
1890         This asynchronous operation supports cancellation for the following
1891         net::cancellation_type values:
1892 
1893         @li @c net::cancellation_type::terminal
1894         @li @c net::cancellation_type::total
1895 
1896         `total` cancellation succeeds if the operation is suspended due to ongoing
1897         control operations such as a ping/pong.
1898         `terminal` cancellation succeeds when supported by the underlying stream.
1899 
1900         `terminal` cancellation leaves the stream in an undefined state,
1901         so that only closing it is guaranteed to succeed.
1902     */
1903     template<
1904         BOOST_BEAST_ASYNC_TPARAM1 PongHandler =
1905             net::default_completion_token_t<executor_type>
1906     >
1907     BOOST_BEAST_ASYNC_RESULT1(PongHandler)
1908     async_pong(
1909         ping_data const& payload,
1910         PongHandler&& handler =
1911             net::default_completion_token_t<
1912                 executor_type>{});
1913 
1914     //--------------------------------------------------------------------------
1915     //
1916     // Reading
1917     //
1918     //--------------------------------------------------------------------------
1919 
1920     /** Read a complete message.
1921 
1922         This function is used to read a complete message.
1923 
1924         The call blocks until one of the following is true:
1925 
1926         @li A complete message is received.
1927 
1928         @li A close frame is received. In this case the error indicated by
1929             the function will be @ref error::closed.
1930 
1931         @li An error occurs.
1932 
1933         The algorithm, known as a <em>composed operation</em>, is implemented
1934         in terms of calls to the next layer's `read_some` and `write_some`
1935         functions.
1936 
1937         Received message data is appended to the buffer.
1938         The functions @ref got_binary and @ref got_text may be used
1939         to query the stream and determine the type of the last received message.
1940 
1941         Until the call returns, the implementation will read incoming control
1942         frames and handle them automatically as follows:
1943 
1944         @li The @ref control_callback will be invoked for each control frame.
1945 
1946         @li For each received ping frame, a pong frame will be
1947             automatically sent.
1948 
1949         @li If a close frame is received, the WebSocket closing handshake is
1950             performed. In this case, when the function returns, the error
1951             @ref error::closed will be indicated.
1952 
1953         @return The number of message payload bytes appended to the buffer.
1954 
1955         @param buffer A dynamic buffer to append message data to.
1956 
1957         @throws system_error Thrown on failure.
1958     */
1959     template<class DynamicBuffer>
1960     std::size_t
1961     read(DynamicBuffer& buffer);
1962 
1963     /** Read a complete message.
1964 
1965         This function is used to read a complete message.
1966 
1967         The call blocks until one of the following is true:
1968 
1969         @li A complete message is received.
1970 
1971         @li A close frame is received. In this case the error indicated by
1972             the function will be @ref error::closed.
1973 
1974         @li An error occurs.
1975 
1976         The algorithm, known as a <em>composed operation</em>, is implemented
1977         in terms of calls to the next layer's `read_some` and `write_some`
1978         functions.
1979 
1980         Received message data is appended to the buffer.
1981         The functions @ref got_binary and @ref got_text may be used
1982         to query the stream and determine the type of the last received message.
1983 
1984         Until the call returns, the implementation will read incoming control
1985         frames and handle them automatically as follows:
1986 
1987         @li The @ref control_callback will be invoked for each control frame.
1988 
1989         @li For each received ping frame, a pong frame will be
1990             automatically sent.
1991 
1992         @li If a close frame is received, the WebSocket closing handshake is
1993             performed. In this case, when the function returns, the error
1994             @ref error::closed will be indicated.
1995 
1996         @return The number of message payload bytes appended to the buffer.
1997 
1998         @param buffer A dynamic buffer to append message data to.
1999 
2000         @param ec Set to indicate what error occurred, if any.
2001     */
2002     template<class DynamicBuffer>
2003     std::size_t
2004     read(DynamicBuffer& buffer, error_code& ec);
2005 
2006     /** Read a complete message asynchronously.
2007 
2008         This function is used to asynchronously read a complete message.
2009 
2010         This call always returns immediately. The asynchronous operation
2011         will continue until one of the following conditions is true:
2012 
2013         @li A complete message is received.
2014 
2015         @li A close frame is received. In this case the error indicated by
2016             the function will be @ref error::closed.
2017 
2018         @li An error occurs.
2019 
2020         The algorithm, known as a <em>composed asynchronous operation</em>,
2021         is implemented in terms of calls to the next layer's `async_read_some`
2022         and `async_write_some` functions. The program must ensure that no other
2023         calls to @ref read, @ref read_some, @ref async_read, or @ref async_read_some
2024         are performed until this operation completes.
2025 
2026         Received message data is appended to the buffer.
2027         The functions @ref got_binary and @ref got_text may be used
2028         to query the stream and determine the type of the last received message.
2029 
2030         Until the operation completes, the implementation will read incoming
2031         control frames and handle them automatically as follows:
2032 
2033         @li The @ref control_callback will be invoked for each control frame.
2034 
2035         @li For each received ping frame, a pong frame will be
2036             automatically sent.
2037 
2038         @li If a close frame is received, the WebSocket close procedure is
2039             performed. In this case, when the function returns, the error
2040             @ref error::closed will be indicated.
2041 
2042         Pong frames and close frames sent by the implementation while the
2043         read operation is outstanding do not prevent the application from
2044         also writing message data, sending pings, sending pongs, or sending
2045         close frames.
2046 
2047         @param buffer A dynamic buffer to append message data to.
2048 
2049         @param handler The completion handler to invoke when the operation
2050         completes. The implementation takes ownership of the handler by
2051         performing a decay-copy. The equivalent function signature of
2052         the handler must be:
2053         @code
2054         void handler(
2055             error_code const& ec,       // Result of operation
2056             std::size_t bytes_written   // Number of bytes appended to buffer
2057         );
2058         @endcode
2059         If the handler has an associated immediate executor,
2060         an immediate completion will be dispatched to it.
2061         Otherwise, the handler will not be invoked from within
2062         this function. Invocation of the handler will be performed
2063         by dispatching to the immediate executor. If no
2064         immediate executor is specified, this is equivalent
2065         to using `net::post`.
2066         @par Per-Operation Cancellation
2067 
2068         This asynchronous operation supports cancellation for the following
2069         net::cancellation_type values:
2070 
2071         @li @c net::cancellation_type::terminal
2072         @li @c net::cancellation_type::total
2073 
2074         `total` cancellation succeeds if the operation is suspended due to ongoing
2075         control operations such as a ping/pong.
2076         `terminal` cancellation succeeds when supported by the underlying stream.
2077 
2078         `terminal` cancellation leaves the stream in an undefined state,
2079         so that only closing it is guaranteed to succeed.
2080     */
2081     template<
2082         class DynamicBuffer,
2083         BOOST_BEAST_ASYNC_TPARAM2 ReadHandler =
2084             net::default_completion_token_t<
2085                 executor_type>>
2086     BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
2087     async_read(
2088         DynamicBuffer& buffer,
2089         ReadHandler&& handler =
2090             net::default_completion_token_t<
2091                 executor_type>{});
2092 
2093     //--------------------------------------------------------------------------
2094 
2095     /** Read some message data.
2096 
2097         This function is used to read some message data.
2098 
2099         The call blocks until one of the following is true:
2100 
2101         @li Some message data is received.
2102 
2103         @li A close frame is received. In this case the error indicated by
2104             the function will be @ref error::closed.
2105 
2106         @li An error occurs.
2107 
2108         The algorithm, known as a <em>composed operation</em>, is implemented
2109         in terms of calls to the next layer's `read_some` and `write_some`
2110         functions.
2111 
2112         Received message data is appended to the buffer.
2113         The functions @ref got_binary and @ref got_text may be used
2114         to query the stream and determine the type of the last received message.
2115         The function @ref is_message_done may be called to determine if the
2116         message received by the last read operation is complete.
2117 
2118         Until the call returns, the implementation will read incoming control
2119         frames and handle them automatically as follows:
2120 
2121         @li The @ref control_callback will be invoked for each control frame.
2122 
2123         @li For each received ping frame, a pong frame will be
2124             automatically sent.
2125 
2126         @li If a close frame is received, the WebSocket closing handshake is
2127             performed. In this case, when the function returns, the error
2128             @ref error::closed will be indicated.
2129 
2130         @return The number of message payload bytes appended to the buffer.
2131 
2132         @param buffer A dynamic buffer to append message data to.
2133 
2134         @param limit An upper limit on the number of bytes this function
2135         will append into the buffer. If this value is zero, then a reasonable
2136         size will be chosen automatically.
2137 
2138         @throws system_error Thrown on failure.
2139     */
2140     template<class DynamicBuffer>
2141     std::size_t
2142     read_some(
2143         DynamicBuffer& buffer,
2144         std::size_t limit);
2145 
2146     /** Read some message data.
2147 
2148         This function is used to read some message data.
2149 
2150         The call blocks until one of the following is true:
2151 
2152         @li Some message data is received.
2153 
2154         @li A close frame is received. In this case the error indicated by
2155             the function will be @ref error::closed.
2156 
2157         @li An error occurs.
2158 
2159         The algorithm, known as a <em>composed operation</em>, is implemented
2160         in terms of calls to the next layer's `read_some` and `write_some`
2161         functions.
2162 
2163         Received message data is appended to the buffer.
2164         The functions @ref got_binary and @ref got_text may be used
2165         to query the stream and determine the type of the last received message.
2166         The function @ref is_message_done may be called to determine if the
2167         message received by the last read operation is complete.
2168 
2169         Until the call returns, the implementation will read incoming control
2170         frames and handle them automatically as follows:
2171 
2172         @li The @ref control_callback will be invoked for each control frame.
2173 
2174         @li For each received ping frame, a pong frame will be
2175             automatically sent.
2176 
2177         @li If a close frame is received, the WebSocket closing handshake is
2178             performed. In this case, when the function returns, the error
2179             @ref error::closed will be indicated.
2180 
2181         @return The number of message payload bytes appended to the buffer.
2182 
2183         @param buffer A dynamic buffer to append message data to.
2184 
2185         @param limit An upper limit on the number of bytes this function
2186         will append into the buffer. If this value is zero, then a reasonable
2187         size will be chosen automatically.
2188 
2189         @param ec Set to indicate what error occurred, if any.
2190     */
2191     template<class DynamicBuffer>
2192     std::size_t
2193     read_some(
2194         DynamicBuffer& buffer,
2195         std::size_t limit,
2196         error_code& ec);
2197 
2198     /** Read some message data asynchronously.
2199 
2200         This function is used to asynchronously read some message data.
2201 
2202         This call always returns immediately. The asynchronous operation
2203         will continue until one of the following conditions is true:
2204 
2205         @li Some message data is received.
2206 
2207         @li A close frame is received. In this case the error indicated by
2208             the function will be @ref error::closed.
2209 
2210         @li An error occurs.
2211 
2212         The algorithm, known as a <em>composed asynchronous operation</em>,
2213         is implemented in terms of calls to the next layer's `async_read_some`
2214         and `async_write_some` functions. The program must ensure that no other
2215         calls to @ref read, @ref read_some, @ref async_read, or @ref async_read_some
2216         are performed until this operation completes.
2217 
2218         Received message data is appended to the buffer.
2219         The functions @ref got_binary and @ref got_text may be used
2220         to query the stream and determine the type of the last received message.
2221 
2222         Until the operation completes, the implementation will read incoming
2223         control frames and handle them automatically as follows:
2224 
2225         @li The @ref control_callback will be invoked for each control frame.
2226 
2227         @li For each received ping frame, a pong frame will be
2228             automatically sent.
2229 
2230         @li If a close frame is received, the WebSocket close procedure is
2231             performed. In this case, when the function returns, the error
2232             @ref error::closed will be indicated.
2233 
2234         Pong frames and close frames sent by the implementation while the
2235         read operation is outstanding do not prevent the application from
2236         also writing message data, sending pings, sending pongs, or sending
2237         close frames.
2238 
2239         @param buffer A dynamic buffer to append message data to.
2240 
2241         @param limit An upper limit on the number of bytes this function
2242         will append into the buffer. If this value is zero, then a reasonable
2243         size will be chosen automatically.
2244 
2245         @param handler The completion handler to invoke when the operation
2246         completes. The implementation takes ownership of the handler by
2247         performing a decay-copy. The equivalent function signature of
2248         the handler must be:
2249         @code
2250         void handler(
2251             error_code const& ec,       // Result of operation
2252             std::size_t bytes_written   // Number of bytes appended to buffer
2253         );
2254         @endcode
2255         If the handler has an associated immediate executor,
2256         an immediate completion will be dispatched to it.
2257         Otherwise, the handler will not be invoked from within
2258         this function. Invocation of the handler will be performed
2259         by dispatching to the immediate executor. If no
2260         immediate executor is specified, this is equivalent
2261         to using `net::post`.
2262         @par Per-Operation Cancellation
2263 
2264         This asynchronous operation supports cancellation for the following
2265         net::cancellation_type values:
2266 
2267         @li @c net::cancellation_type::terminal
2268         @li @c net::cancellation_type::total
2269 
2270         `total` cancellation succeeds if the operation is suspended due to ongoing
2271         control operations such as a ping/pong.
2272         `terminal` cancellation succeeds when supported by the underlying stream.
2273 
2274         `terminal` cancellation leaves the stream in an undefined state,
2275         so that only closing it is guaranteed to succeed.
2276     */
2277     template<
2278         class DynamicBuffer,
2279         BOOST_BEAST_ASYNC_TPARAM2 ReadHandler =
2280             net::default_completion_token_t<
2281                 executor_type>>
2282     BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
2283     async_read_some(
2284         DynamicBuffer& buffer,
2285         std::size_t limit,
2286         ReadHandler&& handler =
2287             net::default_completion_token_t<
2288                 executor_type>{});
2289 
2290     //--------------------------------------------------------------------------
2291 
2292     /** Read some message data.
2293 
2294         This function is used to read some message data.
2295 
2296         The call blocks until one of the following is true:
2297 
2298         @li Some message data is received.
2299 
2300         @li A close frame is received. In this case the error indicated by
2301             the function will be @ref error::closed.
2302 
2303         @li An error occurs.
2304 
2305         The algorithm, known as a <em>composed operation</em>, is implemented
2306         in terms of calls to the next layer's `read_some` and `write_some`
2307         functions.
2308 
2309         The functions @ref got_binary and @ref got_text may be used
2310         to query the stream and determine the type of the last received message.
2311         The function @ref is_message_done may be called to determine if the
2312         message received by the last read operation is complete.
2313 
2314         Until the call returns, the implementation will read incoming control
2315         frames and handle them automatically as follows:
2316 
2317         @li The @ref control_callback will be invoked for each control frame.
2318 
2319         @li For each received ping frame, a pong frame will be
2320             automatically sent.
2321 
2322         @li If a close frame is received, the WebSocket closing handshake is
2323             performed. In this case, when the function returns, the error
2324             @ref error::closed will be indicated.
2325 
2326         @return The number of message payload bytes appended to the buffer.
2327 
2328         @param buffers A buffer sequence to write message data into.
2329         The previous contents of the buffers will be overwritten, starting
2330         from the beginning.
2331 
2332         @throws system_error Thrown on failure.
2333     */
2334     template<class MutableBufferSequence>
2335     std::size_t
2336     read_some(
2337         MutableBufferSequence const& buffers);
2338 
2339     /** Read some message data.
2340 
2341         This function is used to read some message data.
2342 
2343         The call blocks until one of the following is true:
2344 
2345         @li Some message data is received.
2346 
2347         @li A close frame is received. In this case the error indicated by
2348             the function will be @ref error::closed.
2349 
2350         @li An error occurs.
2351 
2352         The algorithm, known as a <em>composed operation</em>, is implemented
2353         in terms of calls to the next layer's `read_some` and `write_some`
2354         functions.
2355 
2356         The functions @ref got_binary and @ref got_text may be used
2357         to query the stream and determine the type of the last received message.
2358         The function @ref is_message_done may be called to determine if the
2359         message received by the last read operation is complete.
2360 
2361         Until the call returns, the implementation will read incoming control
2362         frames and handle them automatically as follows:
2363 
2364         @li The @ref control_callback will be invoked for each control frame.
2365 
2366         @li For each received ping frame, a pong frame will be
2367             automatically sent.
2368 
2369         @li If a close frame is received, the WebSocket closing handshake is
2370             performed. In this case, when the function returns, the error
2371             @ref error::closed will be indicated.
2372 
2373         @return The number of message payload bytes appended to the buffer.
2374 
2375         @param buffers A buffer sequence to write message data into.
2376         The previous contents of the buffers will be overwritten, starting
2377         from the beginning.
2378 
2379         @param ec Set to indicate what error occurred, if any.
2380 
2381         @par Per-Operation Cancellation
2382 
2383         This asynchronous operation supports cancellation for the following
2384         net::cancellation_type values:
2385 
2386         @li @c net::cancellation_type::terminal
2387         @li @c net::cancellation_type::total
2388 
2389         `total` cancellation succeeds if the operation is suspended due to ongoing
2390         control operations such as a ping/pong.
2391         `terminal` cancellation succeeds when supported by the underlying stream.
2392 
2393         `terminal` cancellation leaves the stream in an undefined state,
2394         so that only closing it is guaranteed to succeed.
2395     */
2396     template<class MutableBufferSequence>
2397     std::size_t
2398     read_some(
2399         MutableBufferSequence const& buffers,
2400         error_code& ec);
2401 
2402     /** Read some message data asynchronously.
2403 
2404         This function is used to asynchronously read some message data.
2405 
2406         This call always returns immediately. The asynchronous operation
2407         will continue until one of the following conditions is true:
2408 
2409         @li Some message data is received.
2410 
2411         @li A close frame is received. In this case the error indicated by
2412             the function will be @ref error::closed.
2413 
2414         @li An error occurs.
2415 
2416         The algorithm, known as a <em>composed asynchronous operation</em>,
2417         is implemented in terms of calls to the next layer's `async_read_some`
2418         and `async_write_some` functions. The program must ensure that no other
2419         calls to @ref read, @ref read_some, @ref async_read, or @ref async_read_some
2420         are performed until this operation completes.
2421 
2422         Received message data is appended to the buffer.
2423         The functions @ref got_binary and @ref got_text may be used
2424         to query the stream and determine the type of the last received message.
2425 
2426         Until the operation completes, the implementation will read incoming
2427         control frames and handle them automatically as follows:
2428 
2429         @li The @ref control_callback will be invoked for each control frame.
2430 
2431         @li For each received ping frame, a pong frame will be
2432             automatically sent.
2433 
2434         @li If a close frame is received, the WebSocket close procedure is
2435             performed. In this case, when the function returns, the error
2436             @ref error::closed will be indicated.
2437 
2438         Pong frames and close frames sent by the implementation while the
2439         read operation is outstanding do not prevent the application from
2440         also writing message data, sending pings, sending pongs, or sending
2441         close frames.
2442 
2443         @param buffers A buffer sequence to write message data into.
2444         The previous contents of the buffers will be overwritten, starting
2445         from the beginning.
2446         The implementation will make copies of this object as needed, but
2447         but ownership of the underlying memory is not transferred. The
2448         caller is responsible for ensuring that the memory locations
2449         pointed to by the buffer sequence remain valid until the
2450         completion handler is called.
2451 
2452         @param handler The completion handler to invoke when the operation
2453         completes. The implementation takes ownership of the handler by
2454         performing a decay-copy. The equivalent function signature of
2455         the handler must be:
2456         @code
2457         void handler(
2458             error_code const& ec,       // Result of operation
2459             std::size_t bytes_written   // Number of bytes written to the buffers
2460         );
2461         @endcode
2462         If the handler has an associated immediate executor,
2463         an immediate completion will be dispatched to it.
2464         Otherwise, the handler will not be invoked from within
2465         this function. Invocation of the handler will be performed
2466         by dispatching to the immediate executor. If no
2467         immediate executor is specified, this is equivalent
2468         to using `net::post`.
2469 
2470         @par Per-Operation Cancellation
2471 
2472         This asynchronous operation supports cancellation for the following
2473         net::cancellation_type values:
2474 
2475         @li @c net::cancellation_type::terminal
2476         @li @c net::cancellation_type::total
2477 
2478         `total` cancellation succeeds if the operation is suspended due to ongoing
2479         control operations such as a ping/pong.
2480         `terminal` cancellation succeeds when supported by the underlying stream.
2481 
2482         `terminal` cancellation leaves the stream in an undefined state,
2483         so that only closing it is guaranteed to succeed.
2484     */
2485     template<
2486         class MutableBufferSequence,
2487         BOOST_BEAST_ASYNC_TPARAM2 ReadHandler =
2488             net::default_completion_token_t<
2489                 executor_type>>
2490     BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
2491     async_read_some(
2492         MutableBufferSequence const& buffers,
2493         ReadHandler&& handler =
2494             net::default_completion_token_t<
2495                 executor_type>{});
2496 
2497     //--------------------------------------------------------------------------
2498     //
2499     // Writing
2500     //
2501     //--------------------------------------------------------------------------
2502 
2503     /** Write a complete message.
2504 
2505         This function is used to write a complete message.
2506 
2507         The call blocks until one of the following is true:
2508 
2509         @li The message is written.
2510 
2511         @li An error occurs.
2512 
2513         The algorithm, known as a <em>composed operation</em>, is implemented
2514         in terms of calls to the next layer's `write_some` function.
2515 
2516         The current setting of the @ref binary option controls
2517         whether the message opcode is set to text or binary. If the
2518         @ref auto_fragment option is set, the message will be split
2519         into one or more frames as necessary. The actual payload contents
2520         sent may be transformed as per the WebSocket protocol settings.
2521 
2522         @param buffers The buffers containing the message to send.
2523 
2524         @return The number of bytes sent from the buffers.
2525 
2526         @throws system_error Thrown on failure.
2527     */
2528     template<class ConstBufferSequence>
2529     std::size_t
2530     write(ConstBufferSequence const& buffers);
2531 
2532     /** Write a complete message.
2533 
2534         This function is used to write a complete message.
2535 
2536         The call blocks until one of the following is true:
2537 
2538         @li The complete message is written.
2539 
2540         @li An error occurs.
2541 
2542         The algorithm, known as a <em>composed operation</em>, is implemented
2543         in terms of calls to the next layer's `write_some` function.
2544 
2545         The current setting of the @ref binary option controls
2546         whether the message opcode is set to text or binary. If the
2547         @ref auto_fragment option is set, the message will be split
2548         into one or more frames as necessary. The actual payload contents
2549         sent may be transformed as per the WebSocket protocol settings.
2550 
2551         @param buffers The buffers containing the message to send.
2552 
2553         @param ec Set to indicate what error occurred, if any.
2554 
2555         @return The number of bytes sent from the buffers.
2556     */
2557     template<class ConstBufferSequence>
2558     std::size_t
2559     write(ConstBufferSequence const& buffers, error_code& ec);
2560 
2561     /** Write a complete message asynchronously.
2562 
2563         This function is used to asynchronously write a complete message.
2564 
2565         This call always returns immediately. The asynchronous operation
2566         will continue until one of the following conditions is true:
2567 
2568         @li The complete message is written.
2569 
2570         @li An error occurs.
2571 
2572         The algorithm, known as a <em>composed asynchronous operation</em>,
2573         is implemented in terms of calls to the next layer's
2574         `async_write_some` function. The program must ensure that no other
2575         calls to @ref write, @ref write_some, @ref async_write, or
2576         @ref async_write_some are performed until this operation completes.
2577 
2578         The current setting of the @ref binary option controls
2579         whether the message opcode is set to text or binary. If the
2580         @ref auto_fragment option is set, the message will be split
2581         into one or more frames as necessary. The actual payload contents
2582         sent may be transformed as per the WebSocket protocol settings.
2583 
2584         @param buffers A buffer sequence containing the entire message
2585         payload. The implementation will make copies of this object
2586         as needed, but ownership of the underlying memory is not
2587         transferred. The caller is responsible for ensuring that
2588         the memory locations pointed to by buffers remains valid
2589         until the completion handler is called.
2590 
2591         @param handler The completion handler to invoke when the operation
2592         completes. The implementation takes ownership of the handler by
2593         performing a decay-copy. The equivalent function signature of
2594         the handler must be:
2595         @code
2596         void handler(
2597             error_code const& ec,           // Result of operation
2598             std::size_t bytes_transferred   // Number of bytes sent from the
2599                                             // buffers. If an error occurred,
2600                                             // this will be less than the buffer_size.
2601         );
2602         @endcode
2603         If the handler has an associated immediate executor,
2604         an immediate completion will be dispatched to it.
2605         Otherwise, the handler will not be invoked from within
2606         this function. Invocation of the handler will be performed
2607         by dispatching to the immediate executor. If no
2608         immediate executor is specified, this is equivalent
2609         to using `net::post`.
2610         @par Per-Operation Cancellation
2611 
2612         This asynchronous operation supports cancellation for the following
2613         net::cancellation_type values:
2614 
2615         @li @c net::cancellation_type::terminal
2616         @li @c net::cancellation_type::total
2617 
2618         `total` cancellation succeeds if the operation is suspended due to ongoing
2619         control operations such as a ping/pong.
2620         `terminal` cancellation succeeds when supported by the underlying stream.
2621 
2622         `terminal` cancellation leaves the stream in an undefined state,
2623         so that only closing it is guaranteed to succeed.
2624     */
2625     template<
2626         class ConstBufferSequence,
2627         BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
2628             net::default_completion_token_t<
2629                 executor_type>>
2630     BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
2631     async_write(
2632         ConstBufferSequence const& buffers,
2633         WriteHandler&& handler =
2634             net::default_completion_token_t<
2635                 executor_type>{});
2636 
2637     /** Write some message data.
2638 
2639         This function is used to send part of a message.
2640 
2641         The call blocks until one of the following is true:
2642 
2643         @li The message data is written.
2644 
2645         @li An error occurs.
2646 
2647         The algorithm, known as a <em>composed operation</em>, is implemented
2648         in terms of calls to the next layer's `write_some` function.
2649 
2650         If this is the beginning of a new message, the message opcode
2651         will be set to text or binary based on the current setting of
2652         the @ref binary (or @ref text) option. The actual payload sent
2653         may be transformed as per the WebSocket protocol settings.
2654 
2655         @param fin `true` if this is the last part of the message.
2656 
2657         @param buffers The buffers containing the message part to send.
2658 
2659         @return The number of bytes sent from the buffers.
2660 
2661         @throws system_error Thrown on failure.
2662 
2663     */
2664     template<class ConstBufferSequence>
2665     std::size_t
2666     write_some(bool fin, ConstBufferSequence const& buffers);
2667 
2668     /** Write some message data.
2669 
2670         This function is used to send part of a message.
2671 
2672         The call blocks until one of the following is true:
2673 
2674         @li The message data is written.
2675 
2676         @li An error occurs.
2677 
2678         The algorithm, known as a <em>composed operation</em>, is implemented
2679         in terms of calls to the next layer's `write_some` function.
2680 
2681         If this is the beginning of a new message, the message opcode
2682         will be set to text or binary based on the current setting of
2683         the @ref binary (or @ref text) option. The actual payload sent
2684         may be transformed as per the WebSocket protocol settings.
2685 
2686         This function always writes a complete WebSocket frame (not WebSocket
2687         message) upon successful completion, so it is well defined to perform
2688         ping, pong, and close operations after this operation completes.
2689 
2690         @param fin `true` if this is the last part of the message.
2691 
2692         @param buffers The buffers containing the message part to send.
2693 
2694         @param ec Set to indicate what error occurred, if any.
2695 
2696         @return The number of bytes sent from the buffers.
2697 
2698         @return The number of bytes consumed in the input buffers.
2699     */
2700     template<class ConstBufferSequence>
2701     std::size_t
2702     write_some(bool fin,
2703         ConstBufferSequence const& buffers, error_code& ec);
2704 
2705     /** Write some message data asynchronously.
2706 
2707         This function is used to asynchronously write part of a message.
2708 
2709         This call always returns immediately. The asynchronous operation
2710         will continue until one of the following conditions is true:
2711 
2712         @li The message data is written.
2713 
2714         @li An error occurs.
2715 
2716         The algorithm, known as a <em>composed asynchronous operation</em>,
2717         is implemented in terms of calls to the next layer's
2718         `async_write_some` function. The program must ensure that no other
2719         calls to @ref write, @ref write_some, @ref async_write, or
2720         @ref async_write_some are performed until this operation completes.
2721 
2722         If this is the beginning of a new message, the message opcode
2723         will be set to text or binary based on the current setting of
2724         the @ref binary (or @ref text) option. The actual payload sent
2725         may be transformed as per the WebSocket protocol settings.
2726 
2727         This function always writes a complete WebSocket frame (not WebSocket
2728         message) upon successful completion, so it is well defined to perform
2729         ping, pong, and close operations in parallel to this operation.
2730 
2731         @param fin `true` if this is the last part of the message.
2732 
2733         @param buffers The buffers containing the message part to send.
2734         The implementation will make copies of this object
2735         as needed, but ownership of the underlying memory is not
2736         transferred. The caller is responsible for ensuring that
2737         the memory locations pointed to by buffers remains valid
2738         until the completion handler is called.
2739 
2740         @param handler The completion handler to invoke when the operation
2741         completes. The implementation takes ownership of the handler by
2742         performing a decay-copy. The equivalent function signature of
2743         the handler must be:
2744         @code
2745         void handler(
2746             error_code const& ec,           // Result of operation
2747             std::size_t bytes_transferred   // Number of bytes sent from the
2748                                             // buffers. If an error occurred,
2749                                             // this will be less than the buffer_size.
2750         );
2751         @endcode
2752         If the handler has an associated immediate executor,
2753         an immediate completion will be dispatched to it.
2754         Otherwise, the handler will not be invoked from within
2755         this function. Invocation of the handler will be performed
2756         by dispatching to the immediate executor. If no
2757         immediate executor is specified, this is equivalent
2758         to using `net::post`.
2759         @par Per-Operation Cancellation
2760 
2761         This asynchronous operation supports cancellation for the following
2762         net::cancellation_type values:
2763 
2764         @li @c net::cancellation_type::terminal
2765         @li @c net::cancellation_type::total
2766 
2767         `total` cancellation succeeds if the operation is suspended due to ongoing
2768         control operations such as a ping/pong.
2769         `terminal` cancellation succeeds when supported by the underlying stream.
2770 
2771         `terminal` cancellation leaves the stream in an undefined state,
2772         so that only closing it is guaranteed to succeed.
2773     */
2774     template<
2775         class ConstBufferSequence,
2776         BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
2777             net::default_completion_token_t<
2778                 executor_type>>
2779     BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
2780     async_write_some(
2781         bool fin,
2782         ConstBufferSequence const& buffers,
2783         WriteHandler&& handler =
2784             net::default_completion_token_t<
2785                 executor_type>{});
2786 
2787 private:
2788     template<class, class>  class accept_op;
2789     template<class>         class close_op;
2790     template<class>         class handshake_op;
2791     template<class>         class ping_op;
2792     template<class>         class idle_ping_op;
2793     template<class, class>  class read_some_op;
2794     template<class, class>  class read_op;
2795     template<class>         class response_op;
2796     template<class, class>  class write_some_op;
2797     template<class, class>  class write_op;
2798 
2799     struct run_accept_op;
2800     struct run_close_op;
2801     struct run_handshake_op;
2802     struct run_ping_op;
2803     struct run_idle_ping_op;
2804     struct run_read_some_op;
2805     struct run_read_op;
2806     struct run_response_op;
2807     struct run_write_some_op;
2808     struct run_write_op;
2809 
2810     static void default_decorate_req(request_type&) {}
2811     static void default_decorate_res(response_type&) {}
2812 
2813     //
2814     // accept / handshake
2815     //
2816 
2817     template<class Buffers, class Decorator>
2818     void
2819     do_accept(
2820         Buffers const& buffers,
2821         Decorator const& decorator,
2822         error_code& ec);
2823 
2824     template<
2825         class Body, class Allocator,
2826         class Decorator>
2827     void
2828     do_accept(
2829         http::request<Body,
2830             http::basic_fields<Allocator>> const& req,
2831         Decorator const& decorator,
2832         error_code& ec);
2833 
2834     template<class RequestDecorator>
2835     void
2836     do_handshake(response_type* res_p,
2837         string_view host, string_view target,
2838             RequestDecorator const& decorator,
2839                 error_code& ec);
2840 
2841     //
2842     // fail
2843     //
2844 
2845     void
2846     do_fail(
2847         std::uint16_t code,
2848         error_code ev,
2849         error_code& ec);
2850 };
2851 
2852 /** Manually provide a one-time seed to initialize the PRNG
2853 
2854     This function invokes the specified seed sequence to produce a seed
2855     suitable for use with the pseudo-random number generator used to
2856     create masks and perform WebSocket protocol handshakes.
2857 
2858     If a seed is not manually provided, the implementation will
2859     perform a one-time seed generation using `std::random_device`. This
2860     function may be used when the application runs in an environment
2861     where the random device is unreliable or does not provide sufficient
2862     entropy.
2863 
2864     @par Preconditions
2865 
2866     This function may not be called after any websocket @ref stream objects
2867     have been constructed.
2868 
2869     @param ss A reference to a `std::seed_seq` which will be used to seed
2870     the pseudo-random number generator. The seed sequence should have at
2871     least 256 bits of entropy.
2872 
2873     @see stream::secure_prng
2874 */
2875 inline
2876 void
2877 seed_prng(std::seed_seq& ss)
2878 {
2879     detail::prng_seed(&ss);
2880 }
2881 
2882 } // websocket
2883 } // beast
2884 } // boost
2885 
2886 #include <boost/beast/websocket/impl/stream_impl.hpp> // must be first
2887 #include <boost/beast/websocket/impl/accept.hpp>
2888 #include <boost/beast/websocket/impl/close.hpp>
2889 #include <boost/beast/websocket/impl/handshake.hpp>
2890 #include <boost/beast/websocket/impl/ping.hpp>
2891 #include <boost/beast/websocket/impl/read.hpp>
2892 #include <boost/beast/websocket/impl/stream.hpp>
2893 #include <boost/beast/websocket/impl/write.hpp>
2894 
2895 #endif