]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) | |
3 | // | |
4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | // | |
7 | ||
8 | #ifndef BEAST_WEBSOCKET_STREAM_HPP | |
9 | #define BEAST_WEBSOCKET_STREAM_HPP | |
10 | ||
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> | |
21 | #include <algorithm> | |
22 | #include <cstdint> | |
23 | #include <limits> | |
24 | ||
25 | namespace beast { | |
26 | namespace websocket { | |
27 | ||
28 | /** Information about a WebSocket frame. | |
29 | ||
30 | This information is provided to callers during frame | |
31 | read operations. | |
32 | */ | |
33 | struct frame_info | |
34 | { | |
35 | /// Indicates the type of message (binary or text). | |
36 | opcode op; | |
37 | ||
38 | /// `true` if this is the last frame in the current message. | |
39 | bool fin; | |
40 | }; | |
41 | ||
42 | //-------------------------------------------------------------------- | |
43 | ||
44 | /** Provides message-oriented functionality using WebSocket. | |
45 | ||
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. | |
49 | ||
50 | @par Thread Safety | |
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. | |
55 | ||
56 | @par Example | |
57 | ||
58 | To use the @ref stream template with an `ip::tcp::socket`, | |
59 | you would write: | |
60 | ||
61 | @code | |
62 | websocket::stream<ip::tcp::socket> ws(io_service); | |
63 | @endcode | |
64 | Alternatively, you can write: | |
65 | @code | |
66 | ip::tcp::socket sock(io_service); | |
67 | websocket::stream<ip::tcp::socket&> ws(sock); | |
68 | @endcode | |
69 | ||
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. | |
75 | ||
76 | @note A stream object must not be moved or destroyed while there | |
77 | are pending asynchronous operations associated with it. | |
78 | ||
79 | @par Concepts | |
80 | @b `AsyncStream`, | |
81 | @b `Decorator`, | |
82 | @b `DynamicBuffer`, | |
83 | @b `SyncStream` | |
84 | */ | |
85 | template<class NextLayer> | |
86 | class stream : public detail::stream_base | |
87 | { | |
88 | friend class stream_test; | |
89 | ||
90 | dynabuf_readstream<NextLayer, streambuf> stream_; | |
91 | ||
92 | public: | |
93 | /// The type of the next layer. | |
94 | using next_layer_type = | |
95 | typename std::remove_reference<NextLayer>::type; | |
96 | ||
97 | /// The type of the lowest layer. | |
98 | using lowest_layer_type = | |
99 | #if BEAST_DOXYGEN | |
100 | implementation_defined; | |
101 | #else | |
102 | typename beast::detail::get_lowest_layer< | |
103 | next_layer_type>::type; | |
104 | #endif | |
105 | ||
106 | /** Move-construct a stream. | |
107 | ||
108 | If @c NextLayer is move constructible, this function | |
109 | will move-construct a new stream from the existing stream. | |
110 | ||
111 | @note The behavior of move assignment on or from streams | |
112 | with active or pending operations is undefined. | |
113 | */ | |
114 | stream(stream&&) = default; | |
115 | ||
116 | /** Move assignment. | |
117 | ||
118 | If `NextLayer` is move constructible, this function | |
119 | will move-construct a new stream from the existing stream. | |
120 | ||
121 | @note The behavior of move assignment on or from streams | |
122 | with active or pending operations is undefined. | |
123 | */ | |
124 | stream& operator=(stream&&) = default; | |
125 | ||
126 | /** Construct a WebSocket stream. | |
127 | ||
128 | This constructor creates a websocket stream and initializes | |
129 | the next layer object. | |
130 | ||
131 | @throws Any exceptions thrown by the NextLayer constructor. | |
132 | ||
133 | @param args The arguments to be passed to initialize the | |
134 | next layer object. The arguments are forwarded to the next | |
135 | layer's constructor. | |
136 | */ | |
137 | template<class... Args> | |
138 | explicit | |
139 | stream(Args&&... args); | |
140 | ||
141 | /** Destructor. | |
142 | ||
143 | @note A stream object must not be destroyed while there | |
144 | are pending asynchronous operations associated with it. | |
145 | */ | |
146 | ~stream() = default; | |
147 | ||
148 | /** Set options on the stream. | |
149 | ||
150 | The application must ensure that calls to set options | |
151 | are performed within the same implicit or explicit strand. | |
152 | ||
153 | @param args One or more stream options to set. | |
154 | */ | |
155 | #if BEAST_DOXYGEN | |
156 | template<class... Args> | |
157 | void | |
158 | set_option(Args&&... args) | |
159 | #else | |
160 | template<class A1, class A2, class... An> | |
161 | void | |
162 | set_option(A1&& a1, A2&& a2, An&&... an) | |
163 | #endif | |
164 | { | |
165 | set_option(std::forward<A1>(a1)); | |
166 | set_option(std::forward<A2>(a2), | |
167 | std::forward<An>(an)...); | |
168 | } | |
169 | ||
170 | /// Set the automatic fragment size option | |
171 | void | |
172 | set_option(auto_fragment const& o) | |
173 | { | |
174 | wr_autofrag_ = o.value; | |
175 | } | |
176 | ||
177 | /** Set the decorator used for HTTP messages. | |
178 | ||
179 | The value for this option is a callable type with two | |
180 | optional signatures: | |
181 | ||
182 | @code | |
183 | void(request_type&); | |
184 | ||
185 | void(response_type&); | |
186 | @endcode | |
187 | ||
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. | |
193 | */ | |
194 | void | |
195 | #if BEAST_DOXYGEN | |
196 | set_option(implementation_defined o) | |
197 | #else | |
198 | set_option(detail::decorator_type const& o) | |
199 | #endif | |
200 | { | |
201 | d_ = o; | |
202 | } | |
203 | ||
204 | /// Set the keep-alive option | |
205 | void | |
206 | set_option(keep_alive const& o) | |
207 | { | |
208 | keep_alive_ = o.value; | |
209 | } | |
210 | ||
211 | /// Set the outgoing message type | |
212 | void | |
213 | set_option(message_type const& o) | |
214 | { | |
215 | wr_opcode_ = o.value; | |
216 | } | |
217 | ||
218 | /// Set the permessage-deflate extension options | |
219 | void | |
220 | set_option(permessage_deflate const& o); | |
221 | ||
222 | /// Get the permessage-deflate extension options | |
223 | void | |
224 | get_option(permessage_deflate& o) | |
225 | { | |
226 | o = pmd_opts_; | |
227 | } | |
228 | ||
229 | /// Set the ping callback | |
230 | void | |
231 | set_option(ping_callback o) | |
232 | { | |
233 | ping_cb_ = std::move(o.value); | |
234 | } | |
235 | ||
236 | /// Set the read buffer size | |
237 | void | |
238 | set_option(read_buffer_size const& o) | |
239 | { | |
240 | rd_buf_size_ = o.value; | |
241 | // VFALCO What was the thinking here? | |
242 | //stream_.capacity(o.value); | |
243 | } | |
244 | ||
245 | /// Set the maximum incoming message size allowed | |
246 | void | |
247 | set_option(read_message_max const& o) | |
248 | { | |
249 | rd_msg_max_ = o.value; | |
250 | } | |
251 | ||
252 | /// Set the size of the write buffer | |
253 | void | |
254 | set_option(write_buffer_size const& o) | |
255 | { | |
256 | wr_buf_size_ = o.value; | |
257 | } | |
258 | ||
259 | /** Get the io_service associated with the stream. | |
260 | ||
261 | This function may be used to obtain the io_service object | |
262 | that the stream uses to dispatch handlers for asynchronous | |
263 | operations. | |
264 | ||
265 | @return A reference to the io_service object that the stream | |
266 | will use to dispatch handlers. Ownership is not transferred | |
267 | to the caller. | |
268 | */ | |
269 | boost::asio::io_service& | |
270 | get_io_service() | |
271 | { | |
272 | return stream_.get_io_service(); | |
273 | } | |
274 | ||
275 | /** Get a reference to the next layer. | |
276 | ||
277 | This function returns a reference to the next layer | |
278 | in a stack of stream layers. | |
279 | ||
280 | @return A reference to the next layer in the stack of | |
281 | stream layers. Ownership is not transferred to the caller. | |
282 | */ | |
283 | next_layer_type& | |
284 | next_layer() | |
285 | { | |
286 | return stream_.next_layer(); | |
287 | } | |
288 | ||
289 | /** Get a reference to the next layer. | |
290 | ||
291 | This function returns a reference to the next layer in a | |
292 | stack of stream layers. | |
293 | ||
294 | @return A reference to the next layer in the stack of | |
295 | stream layers. Ownership is not transferred to the caller. | |
296 | */ | |
297 | next_layer_type const& | |
298 | next_layer() const | |
299 | { | |
300 | return stream_.next_layer(); | |
301 | } | |
302 | ||
303 | /** Get a reference to the lowest layer. | |
304 | ||
305 | This function returns a reference to the lowest layer | |
306 | in a stack of stream layers. | |
307 | ||
308 | @return A reference to the lowest layer in the stack of | |
309 | stream layers. Ownership is not transferred to the caller. | |
310 | */ | |
311 | lowest_layer_type& | |
312 | lowest_layer() | |
313 | { | |
314 | return stream_.lowest_layer(); | |
315 | } | |
316 | ||
317 | /** Get a reference to the lowest layer. | |
318 | ||
319 | This function returns a reference to the lowest layer | |
320 | in a stack of stream layers. | |
321 | ||
322 | @return A reference to the lowest layer in the stack of | |
323 | stream layers. Ownership is not transferred to the caller. | |
324 | */ | |
325 | lowest_layer_type const& | |
326 | lowest_layer() const | |
327 | { | |
328 | return stream_.lowest_layer(); | |
329 | } | |
330 | ||
331 | /** Returns the close reason received from the peer. | |
332 | ||
333 | This is only valid after a read completes with error::closed. | |
334 | */ | |
335 | close_reason const& | |
336 | reason() const | |
337 | { | |
338 | return cr_; | |
339 | } | |
340 | ||
341 | /** Read and respond to a WebSocket HTTP Upgrade request. | |
342 | ||
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: | |
346 | ||
347 | @li A HTTP request finishes receiving, and a HTTP response finishes | |
348 | sending. | |
349 | ||
350 | @li An error occurs on the stream. | |
351 | ||
352 | This function is implemented in terms of one or more calls to the | |
353 | next layer's `read_some` and `write_some` functions. | |
354 | ||
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. | |
359 | ||
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. | |
363 | ||
364 | @throws system_error Thrown on failure. | |
365 | */ | |
366 | void | |
367 | accept(); | |
368 | ||
369 | /** Read and respond to a WebSocket HTTP Upgrade request. | |
370 | ||
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: | |
374 | ||
375 | @li A HTTP request finishes receiving, and a HTTP response finishes | |
376 | sending. | |
377 | ||
378 | @li An error occurs on the stream. | |
379 | ||
380 | This function is implemented in terms of one or more calls to the | |
381 | next layer's `read_some` and `write_some` functions. | |
382 | ||
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. | |
387 | ||
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. | |
391 | ||
392 | @param ec Set to indicate what error occurred, if any. | |
393 | */ | |
394 | void | |
395 | accept(error_code& ec); | |
396 | ||
397 | /** Start reading and responding to a WebSocket HTTP Upgrade request. | |
398 | ||
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: | |
403 | ||
404 | @li A HTTP request finishes receiving, and a HTTP response finishes | |
405 | sending. | |
406 | ||
407 | @li An error occurs on the stream. | |
408 | ||
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 | |
413 | completes. | |
414 | ||
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. | |
419 | ||
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. | |
423 | ||
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: | |
427 | @code void handler( | |
428 | error_code const& error // result of operation | |
429 | ); @endcode | |
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`. | |
434 | */ | |
435 | template<class AcceptHandler> | |
436 | #if BEAST_DOXYGEN | |
437 | void_or_deduced | |
438 | #else | |
439 | typename async_completion< | |
440 | AcceptHandler, void(error_code)>::result_type | |
441 | #endif | |
442 | async_accept(AcceptHandler&& handler); | |
443 | ||
444 | /** Read and respond to a WebSocket HTTP Upgrade request. | |
445 | ||
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: | |
449 | ||
450 | @li A HTTP request finishes receiving, and a HTTP response finishes | |
451 | sending. | |
452 | ||
453 | @li An error occurs on the stream. | |
454 | ||
455 | This function is implemented in terms of one or more calls to the | |
456 | next layer's `read_some` and `write_some` functions. | |
457 | ||
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. | |
462 | ||
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. | |
466 | ||
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. | |
473 | ||
474 | @throws system_error Thrown on failure. | |
475 | */ | |
476 | template<class ConstBufferSequence> | |
477 | void | |
478 | accept(ConstBufferSequence const& buffers); | |
479 | ||
480 | /** Read and respond to a WebSocket HTTP Upgrade request. | |
481 | ||
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: | |
485 | ||
486 | @li A HTTP request finishes receiving, and a HTTP response finishes | |
487 | sending. | |
488 | ||
489 | @li An error occurs on the stream. | |
490 | ||
491 | This function is implemented in terms of one or more calls to the | |
492 | next layer's `read_some` and `write_some` functions. | |
493 | ||
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. | |
498 | ||
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. | |
502 | ||
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. | |
509 | ||
510 | @param ec Set to indicate what error occurred, if any. | |
511 | */ | |
512 | template<class ConstBufferSequence> | |
513 | void | |
514 | accept(ConstBufferSequence const& buffers, error_code& ec); | |
515 | ||
516 | /** Start reading and responding to a WebSocket HTTP Upgrade request. | |
517 | ||
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: | |
522 | ||
523 | @li A HTTP request finishes receiving, and a HTTP response finishes | |
524 | sending. | |
525 | ||
526 | @li An error occurs on the stream. | |
527 | ||
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 | |
532 | completes. | |
533 | ||
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. | |
538 | ||
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. | |
542 | ||
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. | |
549 | ||
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: | |
553 | @code void handler( | |
554 | error_code const& error // result of operation | |
555 | ); @endcode | |
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`. | |
560 | */ | |
561 | template<class ConstBufferSequence, class AcceptHandler> | |
562 | #if BEAST_DOXYGEN | |
563 | void_or_deduced | |
564 | #else | |
565 | typename async_completion< | |
566 | AcceptHandler, void(error_code)>::result_type | |
567 | #endif | |
568 | async_accept(ConstBufferSequence const& buffers, | |
569 | AcceptHandler&& handler); | |
570 | ||
571 | /** Respond to a WebSocket HTTP Upgrade request | |
572 | ||
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: | |
576 | ||
577 | @li A HTTP response finishes sending. | |
578 | ||
579 | @li An error occurs on the stream. | |
580 | ||
581 | This function is implemented in terms of one or more calls to the | |
582 | next layer's `write_some` functions. | |
583 | ||
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. | |
588 | ||
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. | |
592 | ||
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. | |
596 | ||
597 | @throws system_error Thrown on failure. | |
598 | */ | |
599 | // VFALCO TODO This should also take a DynamicBuffer with any leftover bytes. | |
600 | template<class Fields> | |
601 | void | |
602 | accept(http::header<true, Fields> const& request); | |
603 | ||
604 | /** Respond to a WebSocket HTTP Upgrade request | |
605 | ||
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: | |
609 | ||
610 | @li A HTTP response finishes sending. | |
611 | ||
612 | @li An error occurs on the stream. | |
613 | ||
614 | This function is implemented in terms of one or more calls to the | |
615 | next layer's `write_some` functions. | |
616 | ||
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. | |
621 | ||
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. | |
625 | ||
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. | |
629 | ||
630 | @param ec Set to indicate what error occurred, if any. | |
631 | */ | |
632 | template<class Fields> | |
633 | void | |
634 | accept(http::header<true, Fields> const& request, error_code& ec); | |
635 | ||
636 | /** Start responding to a WebSocket HTTP Upgrade request. | |
637 | ||
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 | |
642 | true: | |
643 | ||
644 | @li A HTTP response finishes sending. | |
645 | ||
646 | @li An error occurs on the stream. | |
647 | ||
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. | |
652 | ||
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. | |
657 | ||
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. | |
661 | ||
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. | |
665 | ||
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: | |
669 | @code void handler( | |
670 | error_code const& error // result of operation | |
671 | ); @endcode | |
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`. | |
676 | */ | |
677 | template<class Fields, class AcceptHandler> | |
678 | #if BEAST_DOXYGEN | |
679 | void_or_deduced | |
680 | #else | |
681 | typename async_completion< | |
682 | AcceptHandler, void(error_code)>::result_type | |
683 | #endif | |
684 | async_accept(http::header<true, | |
685 | Fields> const& request, AcceptHandler&& handler); | |
686 | ||
687 | /** Send a HTTP WebSocket Upgrade request and receive the response. | |
688 | ||
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: | |
692 | ||
693 | @li A HTTP request finishes sending and a HTTP response finishes | |
694 | receiving. | |
695 | ||
696 | @li An error occurs on the stream | |
697 | ||
698 | This function is implemented in terms of one or more calls to the | |
699 | next layer's `read_some` and `write_some` functions. | |
700 | ||
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"). | |
704 | ||
705 | @param host The name of the remote host, | |
706 | required by the HTTP protocol. | |
707 | ||
708 | @param resource The requesting URI, which may not be empty, | |
709 | required by the HTTP protocol. | |
710 | ||
711 | @throws system_error Thrown on failure. | |
712 | ||
713 | @par Example | |
714 | @code | |
715 | websocket::stream<ip::tcp::socket> ws(io_service); | |
716 | ... | |
717 | try | |
718 | { | |
719 | ws.upgrade("localhost", "/"); | |
720 | } | |
721 | catch(...) | |
722 | { | |
723 | // An error occurred. | |
724 | } | |
725 | @endcode | |
726 | */ | |
727 | void | |
728 | handshake(boost::string_ref const& host, | |
729 | boost::string_ref const& resource); | |
730 | ||
731 | /** Send a HTTP WebSocket Upgrade request and receive the response. | |
732 | ||
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: | |
736 | ||
737 | @li A HTTP request finishes sending and a HTTP response finishes | |
738 | receiving. | |
739 | ||
740 | @li An error occurs on the stream | |
741 | ||
742 | This function is implemented in terms of one or more calls to the | |
743 | next layer's `read_some` and `write_some` functions. | |
744 | ||
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"). | |
748 | ||
749 | @param host The name of the remote host, | |
750 | required by the HTTP protocol. | |
751 | ||
752 | @param resource The requesting URI, which may not be empty, | |
753 | required by the HTTP protocol. | |
754 | ||
755 | @param ec Set to indicate what error occurred, if any. | |
756 | ||
757 | @par Example | |
758 | @code | |
759 | websocket::stream<ip::tcp::socket> ws(io_service); | |
760 | ... | |
761 | error_code ec; | |
762 | ws.upgrade(host, resource, ec); | |
763 | if(ec) | |
764 | { | |
765 | // An error occurred. | |
766 | } | |
767 | @endcode | |
768 | */ | |
769 | void | |
770 | handshake(boost::string_ref const& host, | |
771 | boost::string_ref const& resource, error_code& ec); | |
772 | ||
773 | /** Start an asynchronous operation to send an upgrade request and receive the response. | |
774 | ||
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 | |
779 | true: | |
780 | ||
781 | @li A HTTP request finishes sending and a HTTP response finishes | |
782 | receiving. | |
783 | ||
784 | @li An error occurs on the stream. | |
785 | ||
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 | |
790 | completes. | |
791 | ||
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"). | |
795 | ||
796 | @param host The name of the remote host, required by | |
797 | the HTTP protocol. Copies may be made as needed. | |
798 | ||
799 | @param resource The requesting URI, which may not be empty, | |
800 | required by the HTTP protocol. Copies may be made as | |
801 | needed. | |
802 | ||
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: | |
806 | @code void handler( | |
807 | error_code const& error // result of operation | |
808 | ); @endcode | |
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`. | |
813 | */ | |
814 | template<class HandshakeHandler> | |
815 | #if BEAST_DOXYGEN | |
816 | void_or_deduced | |
817 | #else | |
818 | typename async_completion< | |
819 | HandshakeHandler, void(error_code)>::result_type | |
820 | #endif | |
821 | async_handshake(boost::string_ref const& host, | |
822 | boost::string_ref const& resource, HandshakeHandler&& h); | |
823 | ||
824 | /** Send a WebSocket close frame. | |
825 | ||
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: | |
828 | ||
829 | @li The close frame finishes sending. | |
830 | ||
831 | @li An error occurs on the stream. | |
832 | ||
833 | This function is implemented in terms of one or more calls | |
834 | to the next layer's `write_some` functions. | |
835 | ||
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. | |
840 | ||
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. | |
845 | ||
846 | @param cr The reason for the close. | |
847 | ||
848 | @throws system_error Thrown on failure. | |
849 | */ | |
850 | void | |
851 | close(close_reason const& cr); | |
852 | ||
853 | /** Send a WebSocket close frame. | |
854 | ||
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: | |
857 | ||
858 | @li The close frame finishes sending. | |
859 | ||
860 | @li An error occurs on the stream. | |
861 | ||
862 | This function is implemented in terms of one or more calls | |
863 | to the next layer's `write_some` functions. | |
864 | ||
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. | |
869 | ||
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. | |
874 | ||
875 | @param cr The reason for the close. | |
876 | ||
877 | @param ec Set to indicate what error occurred, if any. | |
878 | */ | |
879 | void | |
880 | close(close_reason const& cr, error_code& ec); | |
881 | ||
882 | /** Start an asynchronous operation to send a WebSocket close frame. | |
883 | ||
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 | |
887 | conditions is true: | |
888 | ||
889 | @li The close frame finishes sending. | |
890 | ||
891 | @li An error occurs on the stream. | |
892 | ||
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. | |
899 | ||
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. | |
904 | ||
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. | |
909 | ||
910 | @param cr The reason for the close. | |
911 | ||
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: | |
915 | @code | |
916 | void handler( | |
917 | error_code const& error // Result of operation | |
918 | ); | |
919 | @endcode | |
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`. | |
924 | */ | |
925 | template<class CloseHandler> | |
926 | #if BEAST_DOXYGEN | |
927 | void_or_deduced | |
928 | #else | |
929 | typename async_completion< | |
930 | CloseHandler, void(error_code)>::result_type | |
931 | #endif | |
932 | async_close(close_reason const& cr, CloseHandler&& handler); | |
933 | ||
934 | /** Send a WebSocket ping frame. | |
935 | ||
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: | |
938 | ||
939 | @li The ping frame finishes sending. | |
940 | ||
941 | @li An error occurs on the stream. | |
942 | ||
943 | This function is implemented in terms of one or more calls to the | |
944 | next layer's `write_some` functions. | |
945 | ||
946 | @param payload The payload of the ping message, which may be empty. | |
947 | ||
948 | @throws system_error Thrown on failure. | |
949 | */ | |
950 | void | |
951 | ping(ping_data const& payload); | |
952 | ||
953 | /** Send a WebSocket ping frame. | |
954 | ||
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: | |
957 | ||
958 | @li The ping frame finishes sending. | |
959 | ||
960 | @li An error occurs on the stream. | |
961 | ||
962 | This function is implemented in terms of one or more calls to the | |
963 | next layer's `write_some` functions. | |
964 | ||
965 | @param payload The payload of the ping message, which may be empty. | |
966 | ||
967 | @param ec Set to indicate what error occurred, if any. | |
968 | */ | |
969 | void | |
970 | ping(ping_data const& payload, error_code& ec); | |
971 | ||
972 | /** Start an asynchronous operation to send a WebSocket ping frame. | |
973 | ||
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 | |
977 | is true: | |
978 | ||
979 | @li The entire ping frame is sent. | |
980 | ||
981 | @li An error occurs on the stream. | |
982 | ||
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. | |
987 | ||
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`. | |
991 | ||
992 | @param payload The payload of the ping message, which may be empty. | |
993 | ||
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: | |
997 | @code | |
998 | void handler( | |
999 | error_code const& error // Result of operation | |
1000 | ); | |
1001 | @endcode | |
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`. | |
1006 | */ | |
1007 | template<class WriteHandler> | |
1008 | #if BEAST_DOXYGEN | |
1009 | void_or_deduced | |
1010 | #else | |
1011 | typename async_completion< | |
1012 | WriteHandler, void(error_code)>::result_type | |
1013 | #endif | |
1014 | async_ping(ping_data const& payload, WriteHandler&& handler); | |
1015 | ||
1016 | /** Send a WebSocket pong frame. | |
1017 | ||
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: | |
1020 | ||
1021 | @li The pong frame finishes sending. | |
1022 | ||
1023 | @li An error occurs on the stream. | |
1024 | ||
1025 | This function is implemented in terms of one or more calls to the | |
1026 | next layer's `write_some` functions. | |
1027 | ||
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. | |
1032 | ||
1033 | @param payload The payload of the pong message, which may be empty. | |
1034 | ||
1035 | @throws system_error Thrown on failure. | |
1036 | */ | |
1037 | void | |
1038 | pong(ping_data const& payload); | |
1039 | ||
1040 | /** Send a WebSocket pong frame. | |
1041 | ||
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: | |
1044 | ||
1045 | @li The pong frame finishes sending. | |
1046 | ||
1047 | @li An error occurs on the stream. | |
1048 | ||
1049 | This function is implemented in terms of one or more calls to the | |
1050 | next layer's `write_some` functions. | |
1051 | ||
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. | |
1056 | ||
1057 | @param payload The payload of the pong message, which may be empty. | |
1058 | ||
1059 | @param ec Set to indicate what error occurred, if any. | |
1060 | */ | |
1061 | void | |
1062 | pong(ping_data const& payload, error_code& ec); | |
1063 | ||
1064 | /** Start an asynchronous operation to send a WebSocket pong frame. | |
1065 | ||
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 | |
1069 | is true: | |
1070 | ||
1071 | @li The entire pong frame is sent. | |
1072 | ||
1073 | @li An error occurs on the stream. | |
1074 | ||
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. | |
1079 | ||
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. | |
1084 | ||
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`. | |
1088 | ||
1089 | @param payload The payload of the pong message, which may be empty. | |
1090 | ||
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: | |
1094 | @code | |
1095 | void handler( | |
1096 | error_code const& error // Result of operation | |
1097 | ); | |
1098 | @endcode | |
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`. | |
1103 | */ | |
1104 | template<class WriteHandler> | |
1105 | #if BEAST_DOXYGEN | |
1106 | void_or_deduced | |
1107 | #else | |
1108 | typename async_completion< | |
1109 | WriteHandler, void(error_code)>::result_type | |
1110 | #endif | |
1111 | async_pong(ping_data const& payload, WriteHandler&& handler); | |
1112 | ||
1113 | /** Read a message from the stream. | |
1114 | ||
1115 | This function is used to synchronously read a message from | |
1116 | the stream. The call blocks until one of the following is true: | |
1117 | ||
1118 | @li A complete message is received. | |
1119 | ||
1120 | @li An error occurs on the stream. | |
1121 | ||
1122 | This call is implemented in terms of one or more calls to the | |
1123 | stream's `read_some` and `write_some` operations. | |
1124 | ||
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). | |
1128 | ||
1129 | During reads, the implementation handles control frames as | |
1130 | follows: | |
1131 | ||
1132 | @li A pong frame is sent when a ping frame is received. | |
1133 | ||
1134 | @li The @ref ping_callback is invoked when a ping frame | |
1135 | or pong frame is received. | |
1136 | ||
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. | |
1140 | ||
1141 | @param op A value to receive the message type. | |
1142 | This object must remain valid until the handler is called. | |
1143 | ||
1144 | @param dynabuf A dynamic buffer to hold the message data after | |
1145 | any masking or decompression has been applied. | |
1146 | ||
1147 | @throws system_error Thrown on failure. | |
1148 | */ | |
1149 | template<class DynamicBuffer> | |
1150 | void | |
1151 | read(opcode& op, DynamicBuffer& dynabuf); | |
1152 | ||
1153 | /** Read a message from the stream. | |
1154 | ||
1155 | This function is used to synchronously read a message from | |
1156 | the stream. The call blocks until one of the following is true: | |
1157 | ||
1158 | @li A complete message is received. | |
1159 | ||
1160 | @li An error occurs on the stream. | |
1161 | ||
1162 | This call is implemented in terms of one or more calls to the | |
1163 | stream's `read_some` and `write_some` operations. | |
1164 | ||
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). | |
1168 | ||
1169 | During reads, the implementation handles control frames as | |
1170 | follows: | |
1171 | ||
1172 | @li The @ref ping_callback is invoked when a ping frame | |
1173 | or pong frame is received. | |
1174 | ||
1175 | @li A pong frame is sent when a ping frame is received. | |
1176 | ||
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. | |
1180 | ||
1181 | @param op A value to receive the message type. | |
1182 | This object must remain valid until the handler is called. | |
1183 | ||
1184 | @param dynabuf A dynamic buffer to hold the message data after | |
1185 | any masking or decompression has been applied. | |
1186 | ||
1187 | @param ec Set to indicate what error occurred, if any. | |
1188 | */ | |
1189 | template<class DynamicBuffer> | |
1190 | void | |
1191 | read(opcode& op, DynamicBuffer& dynabuf, error_code& ec); | |
1192 | ||
1193 | /** Start an asynchronous operation to read a message from the stream. | |
1194 | ||
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 | |
1198 | is true: | |
1199 | ||
1200 | @li A complete message is received. | |
1201 | ||
1202 | @li An error occurs on the stream. | |
1203 | ||
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 | |
1208 | completes. | |
1209 | ||
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). | |
1213 | ||
1214 | During reads, the implementation handles control frames as | |
1215 | follows: | |
1216 | ||
1217 | @li The @ref ping_callback is invoked when a ping frame | |
1218 | or pong frame is received. | |
1219 | ||
1220 | @li A pong frame is sent when a ping frame is received. | |
1221 | ||
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. | |
1225 | ||
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). | |
1231 | ||
1232 | @param op A value to receive the message type. | |
1233 | This object must remain valid until the handler is called. | |
1234 | ||
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. | |
1238 | ||
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: | |
1242 | @code | |
1243 | void handler( | |
1244 | error_code const& error // Result of operation | |
1245 | ); | |
1246 | @endcode | |
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`. | |
1251 | */ | |
1252 | template<class DynamicBuffer, class ReadHandler> | |
1253 | #if BEAST_DOXYGEN | |
1254 | void_or_deduced | |
1255 | #else | |
1256 | typename async_completion< | |
1257 | ReadHandler, void(error_code)>::result_type | |
1258 | #endif | |
1259 | async_read(opcode& op, DynamicBuffer& dynabuf, ReadHandler&& handler); | |
1260 | ||
1261 | /** Read a message frame from the stream. | |
1262 | ||
1263 | This function is used to synchronously read a single message | |
1264 | frame from the stream. The call blocks until one of the following | |
1265 | is true: | |
1266 | ||
1267 | @li A complete frame is received. | |
1268 | ||
1269 | @li An error occurs on the stream. | |
1270 | ||
1271 | This call is implemented in terms of one or more calls to the | |
1272 | stream's `read_some` and `write_some` operations. | |
1273 | ||
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. | |
1280 | ||
1281 | During reads, the implementation handles control frames as | |
1282 | follows: | |
1283 | ||
1284 | @li The @ref ping_callback is invoked when a ping frame | |
1285 | or pong frame is received. | |
1286 | ||
1287 | @li A pong frame is sent when a ping frame is received. | |
1288 | ||
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. | |
1292 | ||
1293 | @param fi An object to store metadata about the message. | |
1294 | ||
1295 | @param dynabuf A dynamic buffer to hold the message data after | |
1296 | any masking or decompression has been applied. | |
1297 | ||
1298 | @throws system_error Thrown on failure. | |
1299 | */ | |
1300 | template<class DynamicBuffer> | |
1301 | void | |
1302 | read_frame(frame_info& fi, DynamicBuffer& dynabuf); | |
1303 | ||
1304 | /** Read a message frame from the stream. | |
1305 | ||
1306 | This function is used to synchronously read a single message | |
1307 | frame from the stream. The call blocks until one of the following | |
1308 | is true: | |
1309 | ||
1310 | @li A complete frame is received. | |
1311 | ||
1312 | @li An error occurs on the stream. | |
1313 | ||
1314 | This call is implemented in terms of one or more calls to the | |
1315 | stream's `read_some` and `write_some` operations. | |
1316 | ||
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. | |
1323 | ||
1324 | During reads, the implementation handles control frames as | |
1325 | follows: | |
1326 | ||
1327 | @li The @ref ping_callback is invoked when a ping frame | |
1328 | or pong frame is received. | |
1329 | ||
1330 | @li A pong frame is sent when a ping frame is received. | |
1331 | ||
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. | |
1335 | ||
1336 | @param fi An object to store metadata about the message. | |
1337 | ||
1338 | @param dynabuf A dynamic buffer to hold the message data after | |
1339 | any masking or decompression has been applied. | |
1340 | ||
1341 | @param ec Set to indicate what error occurred, if any. | |
1342 | */ | |
1343 | template<class DynamicBuffer> | |
1344 | void | |
1345 | read_frame(frame_info& fi, DynamicBuffer& dynabuf, error_code& ec); | |
1346 | ||
1347 | /** Start an asynchronous operation to read a message frame from the stream. | |
1348 | ||
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: | |
1353 | ||
1354 | @li A complete frame is received. | |
1355 | ||
1356 | @li An error occurs on the stream. | |
1357 | ||
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 | |
1362 | completes. | |
1363 | ||
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 | |
1370 | buffer. | |
1371 | ||
1372 | During reads, the implementation handles control frames as | |
1373 | follows: | |
1374 | ||
1375 | @li The @ref ping_callback is invoked when a ping frame | |
1376 | or pong frame is received. | |
1377 | ||
1378 | @li A pong frame is sent when a ping frame is received. | |
1379 | ||
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. | |
1383 | ||
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). | |
1389 | ||
1390 | @param fi An object to store metadata about the message. | |
1391 | This object must remain valid until the handler is called. | |
1392 | ||
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. | |
1396 | ||
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: | |
1400 | @code | |
1401 | void handler( | |
1402 | error_code const& error // Result of operation | |
1403 | ); | |
1404 | @endcode | |
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(). | |
1409 | */ | |
1410 | template<class DynamicBuffer, class ReadHandler> | |
1411 | #if BEAST_DOXYGEN | |
1412 | void_or_deduced | |
1413 | #else | |
1414 | typename async_completion< | |
1415 | ReadHandler, void(error_code)>::result_type | |
1416 | #endif | |
1417 | async_read_frame(frame_info& fi, | |
1418 | DynamicBuffer& dynabuf, ReadHandler&& handler); | |
1419 | ||
1420 | /** Write a message to the stream. | |
1421 | ||
1422 | This function is used to synchronously write a message to | |
1423 | the stream. The call blocks until one of the following conditions | |
1424 | is met: | |
1425 | ||
1426 | @li The entire message is sent. | |
1427 | ||
1428 | @li An error occurs. | |
1429 | ||
1430 | This operation is implemented in terms of one or more calls to the | |
1431 | next layer's `write_some` function. | |
1432 | ||
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. | |
1438 | ||
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. | |
1445 | ||
1446 | @throws system_error Thrown on failure. | |
1447 | ||
1448 | @note This function always sends an entire message. To | |
1449 | send a message in fragments, use @ref write_frame. | |
1450 | */ | |
1451 | template<class ConstBufferSequence> | |
1452 | void | |
1453 | write(ConstBufferSequence const& buffers); | |
1454 | ||
1455 | /** Write a message to the stream. | |
1456 | ||
1457 | This function is used to synchronously write a message to | |
1458 | the stream. The call blocks until one of the following conditions | |
1459 | is met: | |
1460 | ||
1461 | @li The entire message is sent. | |
1462 | ||
1463 | @li An error occurs. | |
1464 | ||
1465 | This operation is implemented in terms of one or more calls to the | |
1466 | next layer's `write_some` function. | |
1467 | ||
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. | |
1473 | ||
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. | |
1480 | ||
1481 | @param ec Set to indicate what error occurred, if any. | |
1482 | ||
1483 | @throws system_error Thrown on failure. | |
1484 | ||
1485 | @note This function always sends an entire message. To | |
1486 | send a message in fragments, use @ref write_frame. | |
1487 | */ | |
1488 | template<class ConstBufferSequence> | |
1489 | void | |
1490 | write(ConstBufferSequence const& buffers, error_code& ec); | |
1491 | ||
1492 | /** Start an asynchronous operation to write a message to the stream. | |
1493 | ||
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: | |
1498 | ||
1499 | @li The entire message is sent. | |
1500 | ||
1501 | @li An error occurs. | |
1502 | ||
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). | |
1509 | ||
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. | |
1515 | ||
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. | |
1522 | ||
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: | |
1526 | @code | |
1527 | void handler( | |
1528 | error_code const& error // Result of operation | |
1529 | ); | |
1530 | @endcode | |
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`. | |
1535 | */ | |
1536 | template<class ConstBufferSequence, class WriteHandler> | |
1537 | #if BEAST_DOXYGEN | |
1538 | void_or_deduced | |
1539 | #else | |
1540 | typename async_completion< | |
1541 | WriteHandler, void(error_code)>::result_type | |
1542 | #endif | |
1543 | async_write(ConstBufferSequence const& buffers, | |
1544 | WriteHandler&& handler); | |
1545 | ||
1546 | /** Write partial message data on the stream. | |
1547 | ||
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: | |
1551 | ||
1552 | @li A frame is sent. | |
1553 | ||
1554 | @li Message data is transferred to the write buffer. | |
1555 | ||
1556 | @li An error occurs. | |
1557 | ||
1558 | This operation is implemented in terms of one or more calls | |
1559 | to the stream's `write_some` function. | |
1560 | ||
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. | |
1565 | ||
1566 | @param fin `true` if this is the last frame in the message. | |
1567 | ||
1568 | @param buffers The input buffer sequence holding the data to write. | |
1569 | ||
1570 | @return The number of bytes consumed in the input buffers. | |
1571 | ||
1572 | @throws system_error Thrown on failure. | |
1573 | */ | |
1574 | template<class ConstBufferSequence> | |
1575 | void | |
1576 | write_frame(bool fin, ConstBufferSequence const& buffers); | |
1577 | ||
1578 | /** Write partial message data on the stream. | |
1579 | ||
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: | |
1583 | ||
1584 | @li A frame is sent. | |
1585 | ||
1586 | @li Message data is transferred to the write buffer. | |
1587 | ||
1588 | @li An error occurs. | |
1589 | ||
1590 | This operation is implemented in terms of one or more calls | |
1591 | to the stream's `write_some` function. | |
1592 | ||
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. | |
1597 | ||
1598 | @param fin `true` if this is the last frame in the message. | |
1599 | ||
1600 | @param buffers The input buffer sequence holding the data to write. | |
1601 | ||
1602 | @param ec Set to indicate what error occurred, if any. | |
1603 | ||
1604 | @return The number of bytes consumed in the input buffers. | |
1605 | */ | |
1606 | template<class ConstBufferSequence> | |
1607 | void | |
1608 | write_frame(bool fin, | |
1609 | ConstBufferSequence const& buffers, error_code& ec); | |
1610 | ||
1611 | /** Start an asynchronous operation to send a message frame on the stream. | |
1612 | ||
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 | |
1616 | conditions is true: | |
1617 | ||
1618 | @li The entire frame is sent. | |
1619 | ||
1620 | @li An error occurs. | |
1621 | ||
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). | |
1629 | ||
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. | |
1634 | ||
1635 | @param fin A bool indicating whether or not the frame is the | |
1636 | last frame in the corresponding WebSockets message. | |
1637 | ||
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. | |
1644 | ||
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: | |
1648 | @code void handler( | |
1649 | error_code const& error // result of operation | |
1650 | ); @endcode | |
1651 | */ | |
1652 | template<class ConstBufferSequence, class WriteHandler> | |
1653 | #if BEAST_DOXYGEN | |
1654 | void_or_deduced | |
1655 | #else | |
1656 | typename async_completion< | |
1657 | WriteHandler, void(error_code)>::result_type | |
1658 | #endif | |
1659 | async_write_frame(bool fin, | |
1660 | ConstBufferSequence const& buffers, WriteHandler&& handler); | |
1661 | ||
1662 | private: | |
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; | |
1672 | ||
1673 | void | |
1674 | reset(); | |
1675 | ||
1676 | http::request_header | |
1677 | build_request(boost::string_ref const& host, | |
1678 | boost::string_ref const& resource, | |
1679 | std::string& key); | |
1680 | ||
1681 | http::response_header | |
1682 | build_response(http::request_header const& req); | |
1683 | ||
1684 | void | |
1685 | do_response(http::response_header const& resp, | |
1686 | boost::string_ref const& key, error_code& ec); | |
1687 | }; | |
1688 | ||
1689 | } // websocket | |
1690 | } // beast | |
1691 | ||
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> | |
1699 | ||
1700 | #endif |