Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:36:10

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