Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 08:05:57

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