2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BEAST_WEBSOCKET_STREAM_HPP
9 #define BEAST_WEBSOCKET_STREAM_HPP
11 #include <beast/config.hpp>
12 #include <beast/websocket/option.hpp>
13 #include <beast/websocket/detail/stream_base.hpp>
14 #include <beast/http/message.hpp>
15 #include <beast/http/string_body.hpp>
16 #include <beast/core/dynabuf_readstream.hpp>
17 #include <beast/core/async_completion.hpp>
18 #include <beast/core/detail/get_lowest_layer.hpp>
19 #include <boost/asio.hpp>
20 #include <boost/utility/string_ref.hpp>
28 /** Information about a WebSocket frame.
30 This information is provided to callers during frame
35 /// Indicates the type of message (binary or text).
38 /// `true` if this is the last frame in the current message.
42 //--------------------------------------------------------------------
44 /** Provides message-oriented functionality using WebSocket.
46 The @ref stream class template provides asynchronous and blocking
47 message-oriented functionality necessary for clients and servers
48 to utilize the WebSocket protocol.
51 @e Distinct @e objects: Safe.@n
52 @e Shared @e objects: Unsafe. The application must ensure that
53 all asynchronous operations are performed within the same
54 implicit or explicit strand.
58 To use the @ref stream template with an `ip::tcp::socket`,
62 websocket::stream<ip::tcp::socket> ws(io_service);
64 Alternatively, you can write:
66 ip::tcp::socket sock(io_service);
67 websocket::stream<ip::tcp::socket&> ws(sock);
70 @tparam NextLayer The type representing the next layer, to which
71 data will be read and written during operations. For synchronous
72 operations, the type must support the @b `SyncStream` concept.
73 For asynchronous operations, the type must support the
74 @b `AsyncStream` concept.
76 @note A stream object must not be moved or destroyed while there
77 are pending asynchronous operations associated with it.
85 template<class NextLayer>
86 class stream : public detail::stream_base
88 friend class stream_test;
90 dynabuf_readstream<NextLayer, streambuf> stream_;
93 /// The type of the next layer.
94 using next_layer_type =
95 typename std::remove_reference<NextLayer>::type;
97 /// The type of the lowest layer.
98 using lowest_layer_type =
100 implementation_defined;
102 typename beast::detail::get_lowest_layer<
103 next_layer_type>::type;
106 /** Move-construct a stream.
108 If @c NextLayer is move constructible, this function
109 will move-construct a new stream from the existing stream.
111 @note The behavior of move assignment on or from streams
112 with active or pending operations is undefined.
114 stream(stream&&) = default;
118 If `NextLayer` is move constructible, this function
119 will move-construct a new stream from the existing stream.
121 @note The behavior of move assignment on or from streams
122 with active or pending operations is undefined.
124 stream& operator=(stream&&) = default;
126 /** Construct a WebSocket stream.
128 This constructor creates a websocket stream and initializes
129 the next layer object.
131 @throws Any exceptions thrown by the NextLayer constructor.
133 @param args The arguments to be passed to initialize the
134 next layer object. The arguments are forwarded to the next
137 template<class... Args>
139 stream(Args&&... args);
143 @note A stream object must not be destroyed while there
144 are pending asynchronous operations associated with it.
148 /** Set options on the stream.
150 The application must ensure that calls to set options
151 are performed within the same implicit or explicit strand.
153 @param args One or more stream options to set.
156 template<class... Args>
158 set_option(Args&&... args)
160 template<class A1, class A2, class... An>
162 set_option(A1&& a1, A2&& a2, An&&... an)
165 set_option(std::forward<A1>(a1));
166 set_option(std::forward<A2>(a2),
167 std::forward<An>(an)...);
170 /// Set the automatic fragment size option
172 set_option(auto_fragment const& o)
174 wr_autofrag_ = o.value;
177 /** Set the decorator used for HTTP messages.
179 The value for this option is a callable type with two
185 void(response_type&);
188 If a matching signature is provided, the callable type
189 will be invoked with the HTTP request or HTTP response
190 object as appropriate. When a signature is omitted,
191 a default consisting of the string Beast followed by
192 the version number is used.
196 set_option(implementation_defined o)
198 set_option(detail::decorator_type const& o)
204 /// Set the keep-alive option
206 set_option(keep_alive const& o)
208 keep_alive_ = o.value;
211 /// Set the outgoing message type
213 set_option(message_type const& o)
215 wr_opcode_ = o.value;
218 /// Set the permessage-deflate extension options
220 set_option(permessage_deflate const& o);
222 /// Get the permessage-deflate extension options
224 get_option(permessage_deflate& o)
229 /// Set the ping callback
231 set_option(ping_callback o)
233 ping_cb_ = std::move(o.value);
236 /// Set the read buffer size
238 set_option(read_buffer_size const& o)
240 rd_buf_size_ = o.value;
241 // VFALCO What was the thinking here?
242 //stream_.capacity(o.value);
245 /// Set the maximum incoming message size allowed
247 set_option(read_message_max const& o)
249 rd_msg_max_ = o.value;
252 /// Set the size of the write buffer
254 set_option(write_buffer_size const& o)
256 wr_buf_size_ = o.value;
259 /** Get the io_service associated with the stream.
261 This function may be used to obtain the io_service object
262 that the stream uses to dispatch handlers for asynchronous
265 @return A reference to the io_service object that the stream
266 will use to dispatch handlers. Ownership is not transferred
269 boost::asio::io_service&
272 return stream_.get_io_service();
275 /** Get a reference to the next layer.
277 This function returns a reference to the next layer
278 in a stack of stream layers.
280 @return A reference to the next layer in the stack of
281 stream layers. Ownership is not transferred to the caller.
286 return stream_.next_layer();
289 /** Get a reference to the next layer.
291 This function returns a reference to the next layer in a
292 stack of stream layers.
294 @return A reference to the next layer in the stack of
295 stream layers. Ownership is not transferred to the caller.
297 next_layer_type const&
300 return stream_.next_layer();
303 /** Get a reference to the lowest layer.
305 This function returns a reference to the lowest layer
306 in a stack of stream layers.
308 @return A reference to the lowest layer in the stack of
309 stream layers. Ownership is not transferred to the caller.
314 return stream_.lowest_layer();
317 /** Get a reference to the lowest layer.
319 This function returns a reference to the lowest layer
320 in a stack of stream layers.
322 @return A reference to the lowest layer in the stack of
323 stream layers. Ownership is not transferred to the caller.
325 lowest_layer_type const&
328 return stream_.lowest_layer();
331 /** Returns the close reason received from the peer.
333 This is only valid after a read completes with error::closed.
341 /** Read and respond to a WebSocket HTTP Upgrade request.
343 This function is used to synchronously read a HTTP WebSocket
344 Upgrade request and send the HTTP response. The call blocks until
345 one of the following conditions is true:
347 @li A HTTP request finishes receiving, and a HTTP response finishes
350 @li An error occurs on the stream.
352 This function is implemented in terms of one or more calls to the
353 next layer's `read_some` and `write_some` functions.
355 If the stream receives a valid HTTP WebSocket Upgrade request, a
356 HTTP response is sent back indicating a successful upgrade. When this
357 call returns, the stream is then ready to send and receive WebSocket
358 protocol frames and messages.
360 If the HTTP Upgrade request is invalid or cannot be satisfied, a
361 HTTP response is sent indicating the reason and status code
362 (typically 400, "Bad Request"). This counts as a failure.
364 @throws system_error Thrown on failure.
369 /** Read and respond to a WebSocket HTTP Upgrade request.
371 This function is used to synchronously read a HTTP WebSocket
372 Upgrade request and send the HTTP response. The call blocks until
373 one of the following conditions is true:
375 @li A HTTP request finishes receiving, and a HTTP response finishes
378 @li An error occurs on the stream.
380 This function is implemented in terms of one or more calls to the
381 next layer's `read_some` and `write_some` functions.
383 If the stream receives a valid HTTP WebSocket Upgrade request, a
384 HTTP response is sent back indicating a successful upgrade. When this
385 call returns, the stream is then ready to send and receive WebSocket
386 protocol frames and messages.
388 If the HTTP Upgrade request is invalid or cannot be satisfied, a
389 HTTP response is sent indicating the reason and status code
390 (typically 400, "Bad Request"). This counts as a failure.
392 @param ec Set to indicate what error occurred, if any.
395 accept(error_code& ec);
397 /** Start reading and responding to a WebSocket HTTP Upgrade request.
399 This function is used to asynchronously read a HTTP WebSocket
400 Upgrade request and send the HTTP response. The function call
401 always returns immediately. The asynchronous operation will
402 continue until one of the following conditions is true:
404 @li A HTTP request finishes receiving, and a HTTP response finishes
407 @li An error occurs on the stream.
409 This operation is implemented in terms of one or more calls to the
410 next layer's `async_read_some` and `async_write_some` functions, and
411 is known as a <em>composed operation</em>. The program must ensure
412 that the stream performs no other operations until this operation
415 If the stream receives a valid HTTP WebSocket Upgrade request, a
416 HTTP response is sent back indicating a successful upgrade. When
417 this call returns, the stream is then ready to send and receive
418 WebSocket protocol frames and messages.
420 If the HTTP Upgrade request is invalid or cannot be satisfied, a
421 HTTP response is sent indicating the reason and status code
422 (typically 400, "Bad Request"). This counts as a failure.
424 @param handler The handler to be called when the request completes.
425 Copies will be made of the handler as required. The equivalent
426 function signature of the handler must be:
428 error_code const& error // result of operation
430 Regardless of whether the asynchronous operation completes
431 immediately or not, the handler will not be invoked from within
432 this function. Invocation of the handler will be performed in a
433 manner equivalent to using `boost::asio::io_service::post`.
435 template<class AcceptHandler>
439 typename async_completion<
440 AcceptHandler, void(error_code)>::result_type
442 async_accept(AcceptHandler&& handler);
444 /** Read and respond to a WebSocket HTTP Upgrade request.
446 This function is used to synchronously read a HTTP WebSocket
447 Upgrade request and send the HTTP response. The call blocks until
448 one of the following conditions is true:
450 @li A HTTP request finishes receiving, and a HTTP response finishes
453 @li An error occurs on the stream.
455 This function is implemented in terms of one or more calls to the
456 next layer's `read_some` and `write_some` functions.
458 If the stream receives a valid HTTP WebSocket Upgrade request, a
459 HTTP response is sent back indicating a successful upgrade. When
460 this call returns, the stream is then ready to send and receive
461 WebSocket protocol frames and messages.
463 If the HTTP Upgrade request is invalid or cannot be satisfied, a
464 HTTP response is sent indicating the reason and status code
465 (typically 400, "Bad Request"). This counts as a failure.
467 @param buffers Caller provided data that has already been
468 received on the stream. This may be used for implementations
469 allowing multiple protocols on the same stream. The
470 buffered data will first be applied to the handshake, and
471 then to received WebSocket frames. The implementation will
472 copy the caller provided data before the function returns.
474 @throws system_error Thrown on failure.
476 template<class ConstBufferSequence>
478 accept(ConstBufferSequence const& buffers);
480 /** Read and respond to a WebSocket HTTP Upgrade request.
482 This function is used to synchronously read a HTTP WebSocket
483 Upgrade request and send the HTTP response. The call blocks until
484 one of the following conditions is true:
486 @li A HTTP request finishes receiving, and a HTTP response finishes
489 @li An error occurs on the stream.
491 This function is implemented in terms of one or more calls to the
492 next layer's `read_some` and `write_some` functions.
494 If the stream receives a valid HTTP WebSocket Upgrade request, a
495 HTTP response is sent back indicating a successful upgrade. When
496 this call returns, the stream is then ready to send and receive
497 WebSocket protocol frames and messages.
499 If the HTTP Upgrade request is invalid or cannot be satisfied, a
500 HTTP response is sent indicating the reason and status code
501 (typically 400, "Bad Request"). This counts as a failure.
503 @param buffers Caller provided data that has already been
504 received on the stream. This may be used for implementations
505 allowing multiple protocols on the same stream. The
506 buffered data will first be applied to the handshake, and
507 then to received WebSocket frames. The implementation will
508 copy the caller provided data before the function returns.
510 @param ec Set to indicate what error occurred, if any.
512 template<class ConstBufferSequence>
514 accept(ConstBufferSequence const& buffers, error_code& ec);
516 /** Start reading and responding to a WebSocket HTTP Upgrade request.
518 This function is used to asynchronously read a HTTP WebSocket
519 Upgrade request and send the HTTP response. The function call
520 always returns immediately. The asynchronous operation will
521 continue until one of the following conditions is true:
523 @li A HTTP request finishes receiving, and a HTTP response finishes
526 @li An error occurs on the stream.
528 This operation is implemented in terms of one or more calls to the
529 next layer's `async_read_some` and `async_write_some` functions, and
530 is known as a <em>composed operation</em>. The program must ensure
531 that the stream performs no other operations until this operation
534 If the stream receives a valid HTTP WebSocket Upgrade request, a
535 HTTP response is sent back indicating a successful upgrade. When
536 this call returns, the stream is then ready to send and receive
537 WebSocket protocol frames and messages.
539 If the HTTP Upgrade request is invalid or cannot be satisfied, a
540 HTTP response is sent indicating the reason and status code
541 (typically 400, "Bad Request"). This counts as a failure.
543 @param buffers Caller provided data that has already been
544 received on the stream. This may be used for implementations
545 allowing multiple protocols on the same stream. The
546 buffered data will first be applied to the handshake, and
547 then to received WebSocket frames. The implementation will
548 copy the caller provided data before the function returns.
550 @param handler The handler to be called when the request completes.
551 Copies will be made of the handler as required. The equivalent
552 function signature of the handler must be:
554 error_code const& error // result of operation
556 Regardless of whether the asynchronous operation completes
557 immediately or not, the handler will not be invoked from within
558 this function. Invocation of the handler will be performed in a
559 manner equivalent to using `boost::asio::io_service::post`.
561 template<class ConstBufferSequence, class AcceptHandler>
565 typename async_completion<
566 AcceptHandler, void(error_code)>::result_type
568 async_accept(ConstBufferSequence const& buffers,
569 AcceptHandler&& handler);
571 /** Respond to a WebSocket HTTP Upgrade request
573 This function is used to synchronously send the HTTP response to
574 a HTTP request possibly containing a WebSocket Upgrade request.
575 The call blocks until one of the following conditions is true:
577 @li A HTTP response finishes sending.
579 @li An error occurs on the stream.
581 This function is implemented in terms of one or more calls to the
582 next layer's `write_some` functions.
584 If the passed HTTP request is a valid HTTP WebSocket Upgrade
585 request, a HTTP response is sent back indicating a successful
586 upgrade. When this call returns, the stream is then ready to send
587 and receive WebSocket protocol frames and messages.
589 If the HTTP request is invalid or cannot be satisfied, a HTTP
590 response is sent indicating the reason and status code (typically
591 400, "Bad Request"). This counts as a failure.
593 @param request An object containing the HTTP Upgrade request.
594 Ownership is not transferred, the implementation will not access
595 this object from other threads.
597 @throws system_error Thrown on failure.
599 // VFALCO TODO This should also take a DynamicBuffer with any leftover bytes.
600 template<class Fields>
602 accept(http::header<true, Fields> const& request);
604 /** Respond to a WebSocket HTTP Upgrade request
606 This function is used to synchronously send the HTTP response to
607 a HTTP request possibly containing a WebSocket Upgrade request.
608 The call blocks until one of the following conditions is true:
610 @li A HTTP response finishes sending.
612 @li An error occurs on the stream.
614 This function is implemented in terms of one or more calls to the
615 next layer's `write_some` functions.
617 If the passed HTTP request is a valid HTTP WebSocket Upgrade
618 request, a HTTP response is sent back indicating a successful
619 upgrade. When this call returns, the stream is then ready to send
620 and receive WebSocket protocol frames and messages.
622 If the HTTP request is invalid or cannot be satisfied, a HTTP
623 response is sent indicating the reason and status code (typically
624 400, "Bad Request"). This counts as a failure.
626 @param request An object containing the HTTP Upgrade request.
627 Ownership is not transferred, the implementation will not access
628 this object from other threads.
630 @param ec Set to indicate what error occurred, if any.
632 template<class Fields>
634 accept(http::header<true, Fields> const& request, error_code& ec);
636 /** Start responding to a WebSocket HTTP Upgrade request.
638 This function is used to asynchronously send the HTTP response
639 to a HTTP request possibly containing a WebSocket Upgrade request.
640 The function call always returns immediately. The asynchronous
641 operation will continue until one of the following conditions is
644 @li A HTTP response finishes sending.
646 @li An error occurs on the stream.
648 This operation is implemented in terms of one or more calls to the
649 next layer's `async_write_some` functions, and is known as a
650 <em>composed operation</em>. The program must ensure that the
651 stream performs no other operations until this operation completes.
653 If the passed HTTP request is a valid HTTP WebSocket Upgrade
654 request, a HTTP response is sent back indicating a successful
655 upgrade. When this asynchronous operation completes, the stream is
656 then ready to send and receive WebSocket protocol frames and messages.
658 If the HTTP request is invalid or cannot be satisfied, a HTTP
659 response is sent indicating the reason and status code (typically
660 400, "Bad Request"). This counts as a failure.
662 @param request An object containing the HTTP Upgrade request.
663 Ownership is not transferred, the implementation will not access
664 this object from other threads.
666 @param handler The handler to be called when the request completes.
667 Copies will be made of the handler as required. The equivalent
668 function signature of the handler must be:
670 error_code const& error // result of operation
672 Regardless of whether the asynchronous operation completes
673 immediately or not, the handler will not be invoked from within
674 this function. Invocation of the handler will be performed in a
675 manner equivalent to using `boost::asio::io_service::post`.
677 template<class Fields, class AcceptHandler>
681 typename async_completion<
682 AcceptHandler, void(error_code)>::result_type
684 async_accept(http::header<true,
685 Fields> const& request, AcceptHandler&& handler);
687 /** Send a HTTP WebSocket Upgrade request and receive the response.
689 This function is used to synchronously send the WebSocket
690 upgrade HTTP request. The call blocks until one of the
691 following conditions is true:
693 @li A HTTP request finishes sending and a HTTP response finishes
696 @li An error occurs on the stream
698 This function is implemented in terms of one or more calls to the
699 next layer's `read_some` and `write_some` functions.
701 The operation is successful if the received HTTP response indicates
702 a successful HTTP Upgrade (represented by a Status-Code of 101,
703 "switching protocols").
705 @param host The name of the remote host,
706 required by the HTTP protocol.
708 @param resource The requesting URI, which may not be empty,
709 required by the HTTP protocol.
711 @throws system_error Thrown on failure.
715 websocket::stream<ip::tcp::socket> ws(io_service);
719 ws.upgrade("localhost", "/");
723 // An error occurred.
728 handshake(boost::string_ref const& host,
729 boost::string_ref const& resource);
731 /** Send a HTTP WebSocket Upgrade request and receive the response.
733 This function is used to synchronously send the WebSocket
734 upgrade HTTP request. The call blocks until one of the
735 following conditions is true:
737 @li A HTTP request finishes sending and a HTTP response finishes
740 @li An error occurs on the stream
742 This function is implemented in terms of one or more calls to the
743 next layer's `read_some` and `write_some` functions.
745 The operation is successful if the received HTTP response indicates
746 a successful HTTP Upgrade (represented by a Status-Code of 101,
747 "switching protocols").
749 @param host The name of the remote host,
750 required by the HTTP protocol.
752 @param resource The requesting URI, which may not be empty,
753 required by the HTTP protocol.
755 @param ec Set to indicate what error occurred, if any.
759 websocket::stream<ip::tcp::socket> ws(io_service);
762 ws.upgrade(host, resource, ec);
765 // An error occurred.
770 handshake(boost::string_ref const& host,
771 boost::string_ref const& resource, error_code& ec);
773 /** Start an asynchronous operation to send an upgrade request and receive the response.
775 This function is used to asynchronously send the HTTP WebSocket
776 upgrade request and receive the HTTP WebSocket Upgrade response.
777 This function call always returns immediately. The asynchronous
778 operation will continue until one of the following conditions is
781 @li A HTTP request finishes sending and a HTTP response finishes
784 @li An error occurs on the stream.
786 This operation is implemented in terms of one or more calls to the
787 next layer's `async_read_some` and `async_write_some` functions, and
788 is known as a <em>composed operation</em>. The program must ensure
789 that the stream performs no other operations until this operation
792 The operation is successful if the received HTTP response indicates
793 a successful HTTP Upgrade (represented by a Status-Code of 101,
794 "switching protocols").
796 @param host The name of the remote host, required by
797 the HTTP protocol. Copies may be made as needed.
799 @param resource The requesting URI, which may not be empty,
800 required by the HTTP protocol. Copies may be made as
803 @param h The handler to be called when the request completes.
804 Copies will be made of the handler as required. The equivalent
805 function signature of the handler must be:
807 error_code const& error // result of operation
809 Regardless of whether the asynchronous operation completes
810 immediately or not, the handler will not be invoked from within
811 this function. Invocation of the handler will be performed in a
812 manner equivalent to using `boost::asio::io_service::post`.
814 template<class HandshakeHandler>
818 typename async_completion<
819 HandshakeHandler, void(error_code)>::result_type
821 async_handshake(boost::string_ref const& host,
822 boost::string_ref const& resource, HandshakeHandler&& h);
824 /** Send a WebSocket close frame.
826 This function is used to synchronously send a close frame on
827 the stream. The call blocks until one of the following is true:
829 @li The close frame finishes sending.
831 @li An error occurs on the stream.
833 This function is implemented in terms of one or more calls
834 to the next layer's `write_some` functions.
836 If the close reason specifies a close code other than
837 @ref beast::websocket::close_code::none, the close frame is
838 sent with the close code and optional reason string. Otherwise,
839 the close frame is sent with no payload.
841 Callers should not attempt to write WebSocket data after
842 initiating the close. Instead, callers should continue
843 reading until an error occurs. A read returning @ref error::closed
844 indicates a successful connection closure.
846 @param cr The reason for the close.
848 @throws system_error Thrown on failure.
851 close(close_reason const& cr);
853 /** Send a WebSocket close frame.
855 This function is used to synchronously send a close frame on
856 the stream. The call blocks until one of the following is true:
858 @li The close frame finishes sending.
860 @li An error occurs on the stream.
862 This function is implemented in terms of one or more calls
863 to the next layer's `write_some` functions.
865 If the close reason specifies a close code other than
866 @ref beast::websocket::close_code::none, the close frame is
867 sent with the close code and optional reason string. Otherwise,
868 the close frame is sent with no payload.
870 Callers should not attempt to write WebSocket data after
871 initiating the close. Instead, callers should continue
872 reading until an error occurs. A read returning @ref error::closed
873 indicates a successful connection closure.
875 @param cr The reason for the close.
877 @param ec Set to indicate what error occurred, if any.
880 close(close_reason const& cr, error_code& ec);
882 /** Start an asynchronous operation to send a WebSocket close frame.
884 This function is used to asynchronously send a close frame on
885 the stream. This function call always returns immediately. The
886 asynchronous operation will continue until one of the following
889 @li The close frame finishes sending.
891 @li An error occurs on the stream.
893 This operation is implemented in terms of one or more calls to the
894 next layer's `async_write_some` functions, and is known as a
895 <em>composed operation</em>. The program must ensure that the
896 stream performs no other write operations (such as @ref async_ping,
897 @ref stream::async_write, @ref stream::async_write_frame, or
898 @ref stream::async_close) until this operation completes.
900 If the close reason specifies a close code other than
901 @ref beast::websocket::close_code::none, the close frame is
902 sent with the close code and optional reason string. Otherwise,
903 the close frame is sent with no payload.
905 Callers should not attempt to write WebSocket data after
906 initiating the close. Instead, callers should continue
907 reading until an error occurs. A read returning @ref error::closed
908 indicates a successful connection closure.
910 @param cr The reason for the close.
912 @param handler The handler to be called when the close operation
913 completes. Copies will be made of the handler as required. The
914 function signature of the handler must be:
917 error_code const& error // Result of operation
920 Regardless of whether the asynchronous operation completes
921 immediately or not, the handler will not be invoked from within
922 this function. Invocation of the handler will be performed in a
923 manner equivalent to using `boost::asio::io_service::post`.
925 template<class CloseHandler>
929 typename async_completion<
930 CloseHandler, void(error_code)>::result_type
932 async_close(close_reason const& cr, CloseHandler&& handler);
934 /** Send a WebSocket ping frame.
936 This function is used to synchronously send a ping frame on
937 the stream. The call blocks until one of the following is true:
939 @li The ping frame finishes sending.
941 @li An error occurs on the stream.
943 This function is implemented in terms of one or more calls to the
944 next layer's `write_some` functions.
946 @param payload The payload of the ping message, which may be empty.
948 @throws system_error Thrown on failure.
951 ping(ping_data const& payload);
953 /** Send a WebSocket ping frame.
955 This function is used to synchronously send a ping frame on
956 the stream. The call blocks until one of the following is true:
958 @li The ping frame finishes sending.
960 @li An error occurs on the stream.
962 This function is implemented in terms of one or more calls to the
963 next layer's `write_some` functions.
965 @param payload The payload of the ping message, which may be empty.
967 @param ec Set to indicate what error occurred, if any.
970 ping(ping_data const& payload, error_code& ec);
972 /** Start an asynchronous operation to send a WebSocket ping frame.
974 This function is used to asynchronously send a ping frame to
975 the stream. The function call always returns immediately. The
976 asynchronous operation will continue until one of the following
979 @li The entire ping frame is sent.
981 @li An error occurs on the stream.
983 This operation is implemented in terms of one or more calls to the
984 next layer's `async_write_some` functions, and is known as a
985 <em>composed operation</em>. The program must ensure that the
986 stream performs no other writes until this operation completes.
988 If a close frame is sent or received before the ping frame is
989 sent, the completion handler will be called with the error
990 set to `boost::asio::error::operation_aborted`.
992 @param payload The payload of the ping message, which may be empty.
994 @param handler The handler to be called when the read operation
995 completes. Copies will be made of the handler as required. The
996 function signature of the handler must be:
999 error_code const& error // Result of operation
1002 Regardless of whether the asynchronous operation completes
1003 immediately or not, the handler will not be invoked from within
1004 this function. Invocation of the handler will be performed in a
1005 manner equivalent to using `boost::asio::io_service::post`.
1007 template<class WriteHandler>
1011 typename async_completion<
1012 WriteHandler, void(error_code)>::result_type
1014 async_ping(ping_data const& payload, WriteHandler&& handler);
1016 /** Send a WebSocket pong frame.
1018 This function is used to synchronously send a pong frame on
1019 the stream. The call blocks until one of the following is true:
1021 @li The pong frame finishes sending.
1023 @li An error occurs on the stream.
1025 This function is implemented in terms of one or more calls to the
1026 next layer's `write_some` functions.
1028 The WebSocket protocol allows pong frames to be sent from either
1029 end at any time. It is not necessary to first receive a ping in
1030 order to send a pong. The remote peer may use the receipt of a
1031 pong frame as an indication that the connection is not dead.
1033 @param payload The payload of the pong message, which may be empty.
1035 @throws system_error Thrown on failure.
1038 pong(ping_data const& payload);
1040 /** Send a WebSocket pong frame.
1042 This function is used to synchronously send a pong frame on
1043 the stream. The call blocks until one of the following is true:
1045 @li The pong frame finishes sending.
1047 @li An error occurs on the stream.
1049 This function is implemented in terms of one or more calls to the
1050 next layer's `write_some` functions.
1052 The WebSocket protocol allows pong frames to be sent from either
1053 end at any time. It is not necessary to first receive a ping in
1054 order to send a pong. The remote peer may use the receipt of a
1055 pong frame as an indication that the connection is not dead.
1057 @param payload The payload of the pong message, which may be empty.
1059 @param ec Set to indicate what error occurred, if any.
1062 pong(ping_data const& payload, error_code& ec);
1064 /** Start an asynchronous operation to send a WebSocket pong frame.
1066 This function is used to asynchronously send a pong frame to
1067 the stream. The function call always returns immediately. The
1068 asynchronous operation will continue until one of the following
1071 @li The entire pong frame is sent.
1073 @li An error occurs on the stream.
1075 This operation is implemented in terms of one or more calls to the
1076 next layer's `async_write_some` functions, and is known as a
1077 <em>composed operation</em>. The program must ensure that the
1078 stream performs no other writes until this operation completes.
1080 The WebSocket protocol allows pong frames to be sent from either
1081 end at any time. It is not necessary to first receive a ping in
1082 order to send a pong. The remote peer may use the receipt of a
1083 pong frame as an indication that the connection is not dead.
1085 If a close frame is sent or received before the pong frame is
1086 sent, the completion handler will be called with the error
1087 set to `boost::asio::error::operation_aborted`.
1089 @param payload The payload of the pong message, which may be empty.
1091 @param handler The handler to be called when the read operation
1092 completes. Copies will be made of the handler as required. The
1093 function signature of the handler must be:
1096 error_code const& error // Result of operation
1099 Regardless of whether the asynchronous operation completes
1100 immediately or not, the handler will not be invoked from within
1101 this function. Invocation of the handler will be performed in a
1102 manner equivalent to using `boost::asio::io_service::post`.
1104 template<class WriteHandler>
1108 typename async_completion<
1109 WriteHandler, void(error_code)>::result_type
1111 async_pong(ping_data const& payload, WriteHandler&& handler);
1113 /** Read a message from the stream.
1115 This function is used to synchronously read a message from
1116 the stream. The call blocks until one of the following is true:
1118 @li A complete message is received.
1120 @li An error occurs on the stream.
1122 This call is implemented in terms of one or more calls to the
1123 stream's `read_some` and `write_some` operations.
1125 Upon a success, op is set to either binary or text depending on
1126 the message type, and the input area of the stream buffer will
1127 hold all the message payload bytes (which may be zero in length).
1129 During reads, the implementation handles control frames as
1132 @li A pong frame is sent when a ping frame is received.
1134 @li The @ref ping_callback is invoked when a ping frame
1135 or pong frame is received.
1137 @li The WebSocket close procedure is started if a close frame
1138 is received. In this case, the operation will eventually
1139 complete with the error set to @ref error::closed.
1141 @param op A value to receive the message type.
1142 This object must remain valid until the handler is called.
1144 @param dynabuf A dynamic buffer to hold the message data after
1145 any masking or decompression has been applied.
1147 @throws system_error Thrown on failure.
1149 template<class DynamicBuffer>
1151 read(opcode& op, DynamicBuffer& dynabuf);
1153 /** Read a message from the stream.
1155 This function is used to synchronously read a message from
1156 the stream. The call blocks until one of the following is true:
1158 @li A complete message is received.
1160 @li An error occurs on the stream.
1162 This call is implemented in terms of one or more calls to the
1163 stream's `read_some` and `write_some` operations.
1165 Upon a success, op is set to either binary or text depending on
1166 the message type, and the input area of the stream buffer will
1167 hold all the message payload bytes (which may be zero in length).
1169 During reads, the implementation handles control frames as
1172 @li The @ref ping_callback is invoked when a ping frame
1173 or pong frame is received.
1175 @li A pong frame is sent when a ping frame is received.
1177 @li The WebSocket close procedure is started if a close frame
1178 is received. In this case, the operation will eventually
1179 complete with the error set to @ref error::closed.
1181 @param op A value to receive the message type.
1182 This object must remain valid until the handler is called.
1184 @param dynabuf A dynamic buffer to hold the message data after
1185 any masking or decompression has been applied.
1187 @param ec Set to indicate what error occurred, if any.
1189 template<class DynamicBuffer>
1191 read(opcode& op, DynamicBuffer& dynabuf, error_code& ec);
1193 /** Start an asynchronous operation to read a message from the stream.
1195 This function is used to asynchronously read a message from
1196 the stream. The function call always returns immediately. The
1197 asynchronous operation will continue until one of the following
1200 @li A complete message is received.
1202 @li An error occurs on the stream.
1204 This operation is implemented in terms of one or more calls to the
1205 next layer's `async_read_some` and `async_write_some` functions,
1206 and is known as a <em>composed operation</em>. The program must
1207 ensure that the stream performs no other reads until this operation
1210 Upon a success, op is set to either binary or text depending on
1211 the message type, and the input area of the stream buffer will
1212 hold all the message payload bytes (which may be zero in length).
1214 During reads, the implementation handles control frames as
1217 @li The @ref ping_callback is invoked when a ping frame
1218 or pong frame is received.
1220 @li A pong frame is sent when a ping frame is received.
1222 @li The WebSocket close procedure is started if a close frame
1223 is received. In this case, the operation will eventually
1224 complete with the error set to @ref error::closed.
1226 Because of the need to handle control frames, read operations
1227 can cause writes to take place. These writes are managed
1228 transparently; callers can still have one active asynchronous
1229 read and asynchronous write operation pending simultaneously
1230 (a user initiated call to @ref async_close counts as a write).
1232 @param op A value to receive the message type.
1233 This object must remain valid until the handler is called.
1235 @param dynabuf A dynamic buffer to hold the message data after
1236 any masking or decompression has been applied. This object must
1237 remain valid until the handler is called.
1239 @param handler The handler to be called when the read operation
1240 completes. Copies will be made of the handler as required. The
1241 function signature of the handler must be:
1244 error_code const& error // Result of operation
1247 Regardless of whether the asynchronous operation completes
1248 immediately or not, the handler will not be invoked from within
1249 this function. Invocation of the handler will be performed in a
1250 manner equivalent to using `boost::asio::io_service::post`.
1252 template<class DynamicBuffer, class ReadHandler>
1256 typename async_completion<
1257 ReadHandler, void(error_code)>::result_type
1259 async_read(opcode& op, DynamicBuffer& dynabuf, ReadHandler&& handler);
1261 /** Read a message frame from the stream.
1263 This function is used to synchronously read a single message
1264 frame from the stream. The call blocks until one of the following
1267 @li A complete frame is received.
1269 @li An error occurs on the stream.
1271 This call is implemented in terms of one or more calls to the
1272 stream's `read_some` and `write_some` operations.
1274 Upon success, `fi` is filled out to reflect the message payload
1275 contents. `op` is set to binary or text, and the `fin` flag
1276 indicates if all the message data has been read in. To read the
1277 entire message, callers should keep calling @ref read_frame
1278 until `fi.fin == true`. A message with no payload will have
1279 `fi.fin == true`, and zero bytes placed into the stream buffer.
1281 During reads, the implementation handles control frames as
1284 @li The @ref ping_callback is invoked when a ping frame
1285 or pong frame is received.
1287 @li A pong frame is sent when a ping frame is received.
1289 @li The WebSocket close procedure is started if a close frame
1290 is received. In this case, the operation will eventually
1291 complete with the error set to @ref error::closed.
1293 @param fi An object to store metadata about the message.
1295 @param dynabuf A dynamic buffer to hold the message data after
1296 any masking or decompression has been applied.
1298 @throws system_error Thrown on failure.
1300 template<class DynamicBuffer>
1302 read_frame(frame_info& fi, DynamicBuffer& dynabuf);
1304 /** Read a message frame from the stream.
1306 This function is used to synchronously read a single message
1307 frame from the stream. The call blocks until one of the following
1310 @li A complete frame is received.
1312 @li An error occurs on the stream.
1314 This call is implemented in terms of one or more calls to the
1315 stream's `read_some` and `write_some` operations.
1317 Upon success, `fi` is filled out to reflect the message payload
1318 contents. `op` is set to binary or text, and the `fin` flag
1319 indicates if all the message data has been read in. To read the
1320 entire message, callers should keep calling @ref read_frame
1321 until `fi.fin == true`. A message with no payload will have
1322 `fi.fin == true`, and zero bytes placed into the stream buffer.
1324 During reads, the implementation handles control frames as
1327 @li The @ref ping_callback is invoked when a ping frame
1328 or pong frame is received.
1330 @li A pong frame is sent when a ping frame is received.
1332 @li The WebSocket close procedure is started if a close frame
1333 is received. In this case, the operation will eventually
1334 complete with the error set to @ref error::closed.
1336 @param fi An object to store metadata about the message.
1338 @param dynabuf A dynamic buffer to hold the message data after
1339 any masking or decompression has been applied.
1341 @param ec Set to indicate what error occurred, if any.
1343 template<class DynamicBuffer>
1345 read_frame(frame_info& fi, DynamicBuffer& dynabuf, error_code& ec);
1347 /** Start an asynchronous operation to read a message frame from the stream.
1349 This function is used to asynchronously read a single message
1350 frame from the websocket. The function call always returns
1351 immediately. The asynchronous operation will continue until
1352 one of the following conditions is true:
1354 @li A complete frame is received.
1356 @li An error occurs on the stream.
1358 This operation is implemented in terms of one or more calls to the
1359 next layer's `async_read_some` and `async_write_some` functions,
1360 and is known as a <em>composed operation</em>. The program must
1361 ensure that the stream performs no other reads until this operation
1364 Upon a successful completion, `fi` is filled out to reflect the
1365 message payload contents. `op` is set to binary or text, and the
1366 `fin` flag indicates if all the message data has been read in.
1367 To read the entire message, callers should keep calling
1368 @ref read_frame until `fi.fin == true`. A message with no payload
1369 will have `fi.fin == true`, and zero bytes placed into the stream
1372 During reads, the implementation handles control frames as
1375 @li The @ref ping_callback is invoked when a ping frame
1376 or pong frame is received.
1378 @li A pong frame is sent when a ping frame is received.
1380 @li The WebSocket close procedure is started if a close frame
1381 is received. In this case, the operation will eventually
1382 complete with the error set to @ref error::closed.
1384 Because of the need to handle control frames, read operations
1385 can cause writes to take place. These writes are managed
1386 transparently; callers can still have one active asynchronous
1387 read and asynchronous write operation pending simultaneously
1388 (a user initiated call to @ref async_close counts as a write).
1390 @param fi An object to store metadata about the message.
1391 This object must remain valid until the handler is called.
1393 @param dynabuf A dynamic buffer to hold the message data after
1394 any masking or decompression has been applied. This object must
1395 remain valid until the handler is called.
1397 @param handler The handler to be called when the read operation
1398 completes. Copies will be made of the handler as required. The
1399 function signature of the handler must be:
1402 error_code const& error // Result of operation
1405 Regardless of whether the asynchronous operation completes
1406 immediately or not, the handler will not be invoked from within
1407 this function. Invocation of the handler will be performed in a
1408 manner equivalent to using boost::asio::io_service::post().
1410 template<class DynamicBuffer, class ReadHandler>
1414 typename async_completion<
1415 ReadHandler, void(error_code)>::result_type
1417 async_read_frame(frame_info& fi,
1418 DynamicBuffer& dynabuf, ReadHandler&& handler);
1420 /** Write a message to the stream.
1422 This function is used to synchronously write a message to
1423 the stream. The call blocks until one of the following conditions
1426 @li The entire message is sent.
1428 @li An error occurs.
1430 This operation is implemented in terms of one or more calls to the
1431 next layer's `write_some` function.
1433 The current setting of the @ref message_type option controls
1434 whether the message opcode is set to text or binary. If the
1435 @ref auto_fragment option is set, the message will be split
1436 into one or more frames as necessary. The actual payload contents
1437 sent may be transformed as per the WebSocket protocol settings.
1439 @param buffers The buffers containing the entire message
1440 payload. The implementation will make copies of this object
1441 as needed, but ownership of the underlying memory is not
1442 transferred. The caller is responsible for ensuring that
1443 the memory locations pointed to by buffers remains valid
1444 until the completion handler is called.
1446 @throws system_error Thrown on failure.
1448 @note This function always sends an entire message. To
1449 send a message in fragments, use @ref write_frame.
1451 template<class ConstBufferSequence>
1453 write(ConstBufferSequence const& buffers);
1455 /** Write a message to the stream.
1457 This function is used to synchronously write a message to
1458 the stream. The call blocks until one of the following conditions
1461 @li The entire message is sent.
1463 @li An error occurs.
1465 This operation is implemented in terms of one or more calls to the
1466 next layer's `write_some` function.
1468 The current setting of the @ref message_type option controls
1469 whether the message opcode is set to text or binary. If the
1470 @ref auto_fragment option is set, the message will be split
1471 into one or more frames as necessary. The actual payload contents
1472 sent may be transformed as per the WebSocket protocol settings.
1474 @param buffers The buffers containing the entire message
1475 payload. The implementation will make copies of this object
1476 as needed, but ownership of the underlying memory is not
1477 transferred. The caller is responsible for ensuring that
1478 the memory locations pointed to by buffers remains valid
1479 until the completion handler is called.
1481 @param ec Set to indicate what error occurred, if any.
1483 @throws system_error Thrown on failure.
1485 @note This function always sends an entire message. To
1486 send a message in fragments, use @ref write_frame.
1488 template<class ConstBufferSequence>
1490 write(ConstBufferSequence const& buffers, error_code& ec);
1492 /** Start an asynchronous operation to write a message to the stream.
1494 This function is used to asynchronously write a message to
1495 the stream. The function call always returns immediately.
1496 The asynchronous operation will continue until one of the
1497 following conditions is true:
1499 @li The entire message is sent.
1501 @li An error occurs.
1503 This operation is implemented in terms of one or more calls
1504 to the next layer's `async_write_some` functions, and is known
1505 as a <em>composed operation</em>. The program must ensure that
1506 the stream performs no other write operations (such as
1507 stream::async_write, stream::async_write_frame, or
1508 stream::async_close).
1510 The current setting of the @ref message_type option controls
1511 whether the message opcode is set to text or binary. If the
1512 @ref auto_fragment option is set, the message will be split
1513 into one or more frames as necessary. The actual payload contents
1514 sent may be transformed as per the WebSocket protocol settings.
1516 @param buffers The buffers containing the entire message
1517 payload. The implementation will make copies of this object
1518 as needed, but ownership of the underlying memory is not
1519 transferred. The caller is responsible for ensuring that
1520 the memory locations pointed to by buffers remains valid
1521 until the completion handler is called.
1523 @param handler The handler to be called when the write operation
1524 completes. Copies will be made of the handler as required. The
1525 function signature of the handler must be:
1528 error_code const& error // Result of operation
1531 Regardless of whether the asynchronous operation completes
1532 immediately or not, the handler will not be invoked from within
1533 this function. Invocation of the handler will be performed in a
1534 manner equivalent to using `boost::asio::io_service::post`.
1536 template<class ConstBufferSequence, class WriteHandler>
1540 typename async_completion<
1541 WriteHandler, void(error_code)>::result_type
1543 async_write(ConstBufferSequence const& buffers,
1544 WriteHandler&& handler);
1546 /** Write partial message data on the stream.
1548 This function is used to write some or all of a message's
1549 payload to the stream. The call will block until one of the
1550 following conditions is true:
1552 @li A frame is sent.
1554 @li Message data is transferred to the write buffer.
1556 @li An error occurs.
1558 This operation is implemented in terms of one or more calls
1559 to the stream's `write_some` function.
1561 If this is the beginning of a new message, the message opcode
1562 will be set to text or binary as per the current setting of
1563 the @ref message_type option. The actual payload sent
1564 may be transformed as per the WebSocket protocol settings.
1566 @param fin `true` if this is the last frame in the message.
1568 @param buffers The input buffer sequence holding the data to write.
1570 @return The number of bytes consumed in the input buffers.
1572 @throws system_error Thrown on failure.
1574 template<class ConstBufferSequence>
1576 write_frame(bool fin, ConstBufferSequence const& buffers);
1578 /** Write partial message data on the stream.
1580 This function is used to write some or all of a message's
1581 payload to the stream. The call will block until one of the
1582 following conditions is true:
1584 @li A frame is sent.
1586 @li Message data is transferred to the write buffer.
1588 @li An error occurs.
1590 This operation is implemented in terms of one or more calls
1591 to the stream's `write_some` function.
1593 If this is the beginning of a new message, the message opcode
1594 will be set to text or binary as per the current setting of
1595 the @ref message_type option. The actual payload sent
1596 may be transformed as per the WebSocket protocol settings.
1598 @param fin `true` if this is the last frame in the message.
1600 @param buffers The input buffer sequence holding the data to write.
1602 @param ec Set to indicate what error occurred, if any.
1604 @return The number of bytes consumed in the input buffers.
1606 template<class ConstBufferSequence>
1608 write_frame(bool fin,
1609 ConstBufferSequence const& buffers, error_code& ec);
1611 /** Start an asynchronous operation to send a message frame on the stream.
1613 This function is used to asynchronously write a message frame
1614 on the stream. This function call always returns immediately.
1615 The asynchronous operation will continue until one of the following
1618 @li The entire frame is sent.
1620 @li An error occurs.
1622 This operation is implemented in terms of one or more calls
1623 to the next layer's `async_write_some` functions, and is known
1624 as a <em>composed operation</em>. The actual payload sent
1625 may be transformed as per the WebSocket protocol settings. The
1626 program must ensure that the stream performs no other write
1627 operations (such as stream::async_write, stream::async_write_frame,
1628 or stream::async_close).
1630 If this is the beginning of a new message, the message opcode
1631 will be set to text or binary as per the current setting of
1632 the @ref message_type option. The actual payload sent
1633 may be transformed as per the WebSocket protocol settings.
1635 @param fin A bool indicating whether or not the frame is the
1636 last frame in the corresponding WebSockets message.
1638 @param buffers A object meeting the requirements of
1639 ConstBufferSequence which holds the payload data before any
1640 masking or compression. Although the buffers object may be copied
1641 as necessary, ownership of the underlying buffers is retained by
1642 the caller, which must guarantee that they remain valid until
1643 the handler is called.
1645 @param handler The handler to be called when the write completes.
1646 Copies will be made of the handler as required. The equivalent
1647 function signature of the handler must be:
1649 error_code const& error // result of operation
1652 template<class ConstBufferSequence, class WriteHandler>
1656 typename async_completion<
1657 WriteHandler, void(error_code)>::result_type
1659 async_write_frame(bool fin,
1660 ConstBufferSequence const& buffers, WriteHandler&& handler);
1663 template<class Handler> class accept_op;
1664 template<class Handler> class close_op;
1665 template<class Handler> class handshake_op;
1666 template<class Handler> class ping_op;
1667 template<class Handler> class response_op;
1668 template<class Buffers, class Handler> class write_op;
1669 template<class Buffers, class Handler> class write_frame_op;
1670 template<class DynamicBuffer, class Handler> class read_op;
1671 template<class DynamicBuffer, class Handler> class read_frame_op;
1676 http::request_header
1677 build_request(boost::string_ref const& host,
1678 boost::string_ref const& resource,
1681 http::response_header
1682 build_response(http::request_header const& req);
1685 do_response(http::response_header const& resp,
1686 boost::string_ref const& key, error_code& ec);
1692 #include <beast/websocket/impl/accept.ipp>
1693 #include <beast/websocket/impl/close.ipp>
1694 #include <beast/websocket/impl/handshake.ipp>
1695 #include <beast/websocket/impl/ping.ipp>
1696 #include <beast/websocket/impl/read.ipp>
1697 #include <beast/websocket/impl/stream.ipp>
1698 #include <beast/websocket/impl/write.ipp>