2 // Copyright (c) 2016-2019 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)
7 // Official repository: https://github.com/boostorg/beast
10 #ifndef BEAST_TEST_WEBSOCKET_TEST_HPP
11 #define BEAST_TEST_WEBSOCKET_TEST_HPP
13 #include <boost/beast/core/bind_handler.hpp>
14 #include <boost/beast/core/buffer_traits.hpp>
15 #include <boost/beast/core/buffers_to_string.hpp>
16 #include <boost/beast/core/ostream.hpp>
17 #include <boost/beast/core/multi_buffer.hpp>
18 #include <boost/beast/websocket/stream.hpp>
19 #include <boost/beast/_experimental/test/stream.hpp>
20 #include <boost/beast/test/yield_to.hpp>
21 #include <boost/beast/_experimental/unit_test/suite.hpp>
22 #include <boost/asio/executor_work_guard.hpp>
23 #include <boost/asio/io_context.hpp>
24 #include <boost/optional.hpp>
34 class websocket_test_suite
35 : public beast::unit_test::suite
36 , public test::enable_yield_to
39 template<bool deflateSupported>
41 websocket::stream<test::stream&, deflateSupported>;
44 websocket::stream<test::stream&>;
46 struct move_only_handler
48 move_only_handler() = default;
49 move_only_handler(move_only_handler&&) = default;
50 move_only_handler(move_only_handler const&) = delete;
52 template<class... Args>
54 operator()(Args&&...) const
75 net::executor_work_guard<
76 net::io_context::executor_type> work_;
77 static_buffer<buf_size> buffer_;
80 websocket::stream<test::stream&> ws_;
89 , work_(ioc_.get_executor())
93 permessage_deflate pmd;
94 pmd.server_enable = true;
95 pmd.server_max_window_bits = 9;
102 t_ = std::thread{[&]{ do_sync(); }};
106 t_ = std::thread{[&]{ ioc_.run(); }};
110 case kind::async_client:
111 t_ = std::thread{[&]{ ioc_.run(); }};
131 ws_.async_handshake("localhost", "/",
133 &echo_server::on_handshake,
147 &echo_server::on_close,
167 ws_.text(ws_.got_text());
168 ws_.write(buffer_.data());
169 buffer_.consume(buffer_.size());
172 catch(system_error const& se)
174 boost::ignore_unused(se);
176 if( se.code() != error::closed &&
177 se.code() != error::failed &&
178 se.code() != net::error::eof)
179 log_ << "echo_server: " << se.code().message() << std::endl;
182 catch(std::exception const& e)
184 log_ << "echo_server: " << e.what() << std::endl;
193 &echo_server::on_accept,
198 on_handshake(error_code ec)
207 on_accept(error_code ec)
214 return ws_.async_close({},
216 &echo_server::on_close,
226 ws_.async_read(buffer_,
227 beast::bind_front_handler(
228 &echo_server::on_read,
233 on_read(error_code ec, std::size_t)
237 ws_.text(ws_.got_text());
238 ws_.async_write(buffer_.data(),
239 beast::bind_front_handler(
240 &echo_server::on_write,
245 on_write(error_code ec, std::size_t)
249 buffer_.consume(buffer_.size());
254 on_close(error_code ec)
263 boost::ignore_unused(ec);
265 if( ec != error::closed &&
266 ec != error::failed &&
267 ec != net::error::eof)
269 "echo_server_async: " <<
279 Test const& f, std::size_t limit = 200)
282 for(n = 0; n < limit; ++n)
284 test::fail_count fc{n};
290 catch(system_error const& se)
293 se.code() == test::error::test_failure,
294 se.code().message());
297 BEAST_EXPECT(n < limit);
302 doStreamLoop(Test const& f)
304 // This number has to be high for the
305 // test that writes the large buffer.
306 static std::size_t constexpr limit = 200;
309 [&](test::fail_count& fc)
311 test::stream ts{ioc_, fc};
318 template<bool deflateSupported = true, class Test>
321 permessage_deflate const& pmd,
324 // This number has to be high for the
325 // test that writes the large buffer.
326 static std::size_t constexpr limit = 200;
328 for(int i = 0; i < 2; ++i)
331 for(n = 0; n < limit; ++n)
333 test::fail_count fc{n};
334 test::stream ts{ioc_, fc};
335 ws_type_t<deflateSupported> ws{ts};
338 echo_server es{log, i==1 ?
339 kind::async : kind::sync};
341 ws.next_layer().connect(es.stream());
342 ws.handshake("localhost", "/", ec);
347 ec == test::error::test_failure,
349 BOOST_THROW_EXCEPTION(system_error{ec});
358 catch(system_error const& se)
361 se.code() == test::error::test_failure,
362 se.code().message());
364 catch(std::exception const& e)
366 fail(e.what(), __FILE__, __LINE__);
371 BEAST_EXPECT(n < limit);
375 //--------------------------------------------------------------------------
377 net::const_buffer cbuf(std::initializer_list<std::uint8_t> bytes)
379 return {bytes.begin(), bytes.size()};
382 template<std::size_t N>
385 sbuf(const char (&s)[N])
387 return net::const_buffer(&s[0], N-1);
392 class ConstBufferSequence>
395 DynamicBuffer& buffer,
396 ConstBufferSequence const& buffers)
398 buffer.commit(net::buffer_copy(
399 buffer.prepare(buffer_bytes(buffers)),
405 run_until(net::io_context& ioc,
406 std::size_t limit, Pred&& pred)
408 for(std::size_t i = 0; i < limit; ++i)
420 net::io_context& ioc, Pred&& pred)
422 return run_until(ioc, 100, pred);
429 static std::string const s = []
431 std::size_t constexpr N = 16384;
435 for(std::size_t i = 0; i < N; ++ i)
436 tmp.push_back(static_cast<char>(
437 std::uniform_int_distribution<
438 unsigned>{0, 255}(mt)));
444 //--------------------------------------------------------------------------
448 template<class NextLayer, bool deflateSupported>
451 stream<NextLayer, deflateSupported>& ws) const
457 class NextLayer, bool deflateSupported,
459 typename std::enable_if<
460 ! http::detail::is_header<Buffers>::value>::type
461 accept(stream<NextLayer, deflateSupported>& ws,
462 Buffers const& buffers) const
467 template<class NextLayer, bool deflateSupported>
470 stream<NextLayer, deflateSupported>& ws,
471 http::request<http::empty_body> const& req) const
477 class NextLayer, bool deflateSupported,
481 stream<NextLayer, deflateSupported>& ws,
482 Decorator const& d) const
488 class NextLayer, bool deflateSupported,
489 class Buffers, class Decorator>
490 typename std::enable_if<
491 ! http::detail::is_header<Buffers>::value>::type
493 stream<NextLayer, deflateSupported>& ws,
494 Buffers const& buffers,
495 Decorator const& d) const
497 ws.accept_ex(buffers, d);
501 class NextLayer, bool deflateSupported,
505 stream<NextLayer, deflateSupported>& ws,
506 http::request<http::empty_body> const& req,
507 Decorator const& d) const
509 ws.accept_ex(req, d);
513 class NextLayer, bool deflateSupported,
514 class Buffers, class Decorator>
517 stream<NextLayer, deflateSupported>& ws,
518 http::request<http::empty_body> const& req,
519 Buffers const& buffers,
520 Decorator const& d) const
522 ws.accept_ex(req, buffers, d);
525 template<class NextLayer, bool deflateSupported>
528 stream<NextLayer, deflateSupported>& ws,
530 string_view path) const
532 ws.handshake(uri, path);
535 template<class NextLayer, bool deflateSupported>
538 stream<NextLayer, deflateSupported>& ws,
541 string_view path) const
543 ws.handshake(res, uri, path);
547 class NextLayer, bool deflateSupported,
551 stream<NextLayer, deflateSupported>& ws,
554 Decorator const& d) const
556 ws.handshake_ex(uri, path, d);
560 class NextLayer, bool deflateSupported,
564 stream<NextLayer, deflateSupported>& ws,
568 Decorator const& d) const
570 ws.handshake_ex(res, uri, path, d);
573 template<class NextLayer, bool deflateSupported>
575 ping(stream<NextLayer, deflateSupported>& ws,
576 ping_data const& payload) const
581 template<class NextLayer, bool deflateSupported>
583 pong(stream<NextLayer, deflateSupported>& ws,
584 ping_data const& payload) const
589 template<class NextLayer, bool deflateSupported>
591 close(stream<NextLayer, deflateSupported>& ws,
592 close_reason const& cr) const
598 class NextLayer, bool deflateSupported,
601 read(stream<NextLayer, deflateSupported>& ws,
602 DynamicBuffer& buffer) const
604 return ws.read(buffer);
608 class NextLayer, bool deflateSupported,
612 stream<NextLayer, deflateSupported>& ws,
614 DynamicBuffer& buffer) const
616 return ws.read_some(buffer, limit);
620 class NextLayer, bool deflateSupported,
621 class MutableBufferSequence>
624 stream<NextLayer, deflateSupported>& ws,
625 MutableBufferSequence const& buffers) const
627 return ws.read_some(buffers);
631 class NextLayer, bool deflateSupported,
632 class ConstBufferSequence>
635 stream<NextLayer, deflateSupported>& ws,
636 ConstBufferSequence const& buffers) const
638 return ws.write(buffers);
642 class NextLayer, bool deflateSupported,
643 class ConstBufferSequence>
646 stream<NextLayer, deflateSupported>& ws,
648 ConstBufferSequence const& buffers) const
650 return ws.write_some(fin, buffers);
654 class NextLayer, bool deflateSupported,
655 class ConstBufferSequence>
658 stream<NextLayer, deflateSupported>& ws,
659 ConstBufferSequence const& buffers) const
662 ws.next_layer(), buffers);
666 //--------------------------------------------------------------------------
670 net::yield_context& yield_;
674 AsyncClient(net::yield_context& yield)
679 template<class NextLayer, bool deflateSupported>
681 accept(stream<NextLayer, deflateSupported>& ws) const
684 ws.async_accept(yield_[ec]);
686 throw system_error{ec};
690 class NextLayer, bool deflateSupported,
692 typename std::enable_if<
693 ! http::detail::is_header<Buffers>::value>::type
695 stream<NextLayer, deflateSupported>& ws,
696 Buffers const& buffers) const
699 ws.async_accept(buffers, yield_[ec]);
701 throw system_error{ec};
704 template<class NextLayer, bool deflateSupported>
707 stream<NextLayer, deflateSupported>& ws,
708 http::request<http::empty_body> const& req) const
711 ws.async_accept(req, yield_[ec]);
713 throw system_error{ec};
717 class NextLayer, bool deflateSupported,
721 stream<NextLayer, deflateSupported>& ws,
722 Decorator const& d) const
725 ws.async_accept_ex(d, yield_[ec]);
727 throw system_error{ec};
731 class NextLayer, bool deflateSupported,
732 class Buffers, class Decorator>
733 typename std::enable_if<
734 ! http::detail::is_header<Buffers>::value>::type
736 stream<NextLayer, deflateSupported>& ws,
737 Buffers const& buffers,
738 Decorator const& d) const
741 ws.async_accept_ex(buffers, d, yield_[ec]);
743 throw system_error{ec};
747 class NextLayer, bool deflateSupported,
751 stream<NextLayer, deflateSupported>& ws,
752 http::request<http::empty_body> const& req,
753 Decorator const& d) const
756 ws.async_accept_ex(req, d, yield_[ec]);
758 throw system_error{ec};
762 class NextLayer, bool deflateSupported,
763 class Buffers, class Decorator>
766 stream<NextLayer, deflateSupported>& ws,
767 http::request<http::empty_body> const& req,
768 Buffers const& buffers,
769 Decorator const& d) const
773 req, buffers, d, yield_[ec]);
775 throw system_error{ec};
779 class NextLayer, bool deflateSupported>
782 stream<NextLayer, deflateSupported>& ws,
784 string_view path) const
788 uri, path, yield_[ec]);
790 throw system_error{ec};
793 template<class NextLayer, bool deflateSupported>
796 stream<NextLayer, deflateSupported>& ws,
799 string_view path) const
803 res, uri, path, yield_[ec]);
805 throw system_error{ec};
809 class NextLayer, bool deflateSupported,
813 stream<NextLayer, deflateSupported>& ws,
816 Decorator const &d) const
819 ws.async_handshake_ex(
820 uri, path, d, yield_[ec]);
822 throw system_error{ec};
826 class NextLayer, bool deflateSupported,
830 stream<NextLayer, deflateSupported>& ws,
834 Decorator const &d) const
837 ws.async_handshake_ex(
838 res, uri, path, d, yield_[ec]);
840 throw system_error{ec};
843 template<class NextLayer, bool deflateSupported>
846 stream<NextLayer, deflateSupported>& ws,
847 ping_data const& payload) const
850 ws.async_ping(payload, yield_[ec]);
852 throw system_error{ec};
855 template<class NextLayer, bool deflateSupported>
858 stream<NextLayer, deflateSupported>& ws,
859 ping_data const& payload) const
862 ws.async_pong(payload, yield_[ec]);
864 throw system_error{ec};
867 template<class NextLayer, bool deflateSupported>
870 stream<NextLayer, deflateSupported>& ws,
871 close_reason const& cr) const
874 ws.async_close(cr, yield_[ec]);
876 throw system_error{ec};
880 class NextLayer, bool deflateSupported,
884 stream<NextLayer, deflateSupported>& ws,
885 DynamicBuffer& buffer) const
888 auto const bytes_written =
889 ws.async_read(buffer, yield_[ec]);
891 throw system_error{ec};
892 return bytes_written;
896 class NextLayer, bool deflateSupported,
900 stream<NextLayer, deflateSupported>& ws,
902 DynamicBuffer& buffer) const
905 auto const bytes_written =
906 ws.async_read_some(buffer, limit, yield_[ec]);
908 throw system_error{ec};
909 return bytes_written;
913 class NextLayer, bool deflateSupported,
914 class MutableBufferSequence>
917 stream<NextLayer, deflateSupported>& ws,
918 MutableBufferSequence const& buffers) const
921 auto const bytes_written =
922 ws.async_read_some(buffers, yield_[ec]);
924 throw system_error{ec};
925 return bytes_written;
929 class NextLayer, bool deflateSupported,
930 class ConstBufferSequence>
933 stream<NextLayer, deflateSupported>& ws,
934 ConstBufferSequence const& buffers) const
937 auto const bytes_transferred =
938 ws.async_write(buffers, yield_[ec]);
940 throw system_error{ec};
941 return bytes_transferred;
945 class NextLayer, bool deflateSupported,
946 class ConstBufferSequence>
949 stream<NextLayer, deflateSupported>& ws,
951 ConstBufferSequence const& buffers) const
954 auto const bytes_transferred =
955 ws.async_write_some(fin, buffers, yield_[ec]);
957 throw system_error{ec};
958 return bytes_transferred;
962 class NextLayer, bool deflateSupported,
963 class ConstBufferSequence>
966 stream<NextLayer, deflateSupported>& ws,
967 ConstBufferSequence const& buffers) const
970 auto const bytes_transferred =
972 ws.next_layer(), buffers, yield_[ec]);
974 throw system_error{ec};
975 return bytes_transferred;
982 template<class NextLayer, bool deflateSupported>
985 stream<NextLayer, deflateSupported>& ws) const
991 class NextLayer, bool deflateSupported,
993 typename std::enable_if<
994 ! http::detail::is_header<Buffers>::value>::type
995 accept(stream<NextLayer, deflateSupported>& ws,
996 Buffers const& buffers) const
1001 template<class NextLayer, bool deflateSupported>
1004 stream<NextLayer, deflateSupported>& ws,
1005 http::request<http::empty_body> const& req) const
1011 class NextLayer, bool deflateSupported,
1015 stream<NextLayer, deflateSupported>& ws,
1016 Decorator const& d) const
1022 class NextLayer, bool deflateSupported,
1023 class Buffers, class Decorator>
1024 typename std::enable_if<
1025 ! http::detail::is_header<Buffers>::value>::type
1027 stream<NextLayer, deflateSupported>& ws,
1028 Buffers const& buffers,
1029 Decorator const& d) const
1031 ws.accept_ex(buffers, d);
1035 class NextLayer, bool deflateSupported,
1039 stream<NextLayer, deflateSupported>& ws,
1040 http::request<http::empty_body> const& req,
1041 Decorator const& d) const
1043 ws.accept_ex(req, d);
1047 class NextLayer, bool deflateSupported,
1048 class Buffers, class Decorator>
1051 stream<NextLayer, deflateSupported>& ws,
1052 http::request<http::empty_body> const& req,
1053 Buffers const& buffers,
1054 Decorator const& d) const
1056 ws.accept_ex(req, buffers, d);
1059 template<class NextLayer, bool deflateSupported>
1062 stream<NextLayer, deflateSupported>& ws,
1065 string_view path) const
1067 ws.handshake(res, uri, path);
1071 class NextLayer, bool deflateSupported,
1075 stream<NextLayer, deflateSupported>& ws,
1078 Decorator const& d) const
1080 ws.handshake_ex(uri, path, d);
1084 class NextLayer, bool deflateSupported,
1088 stream<NextLayer, deflateSupported>& ws,
1092 Decorator const& d) const
1094 ws.handshake_ex(res, uri, path, d);
1097 template<class NextLayer, bool deflateSupported>
1099 ping(stream<NextLayer, deflateSupported>& ws,
1100 ping_data const& payload) const
1105 template<class NextLayer, bool deflateSupported>
1107 pong(stream<NextLayer, deflateSupported>& ws,
1108 ping_data const& payload) const
1113 template<class NextLayer, bool deflateSupported>
1115 close(stream<NextLayer, deflateSupported>& ws,
1116 close_reason const& cr) const
1122 class NextLayer, bool deflateSupported,
1123 class DynamicBuffer>
1125 read(stream<NextLayer, deflateSupported>& ws,
1126 DynamicBuffer& buffer) const
1128 return ws.read(buffer);
1132 class NextLayer, bool deflateSupported,
1133 class DynamicBuffer>
1136 stream<NextLayer, deflateSupported>& ws,
1138 DynamicBuffer& buffer) const
1140 return ws.read_some(buffer, limit);
1144 class NextLayer, bool deflateSupported,
1145 class MutableBufferSequence>
1148 stream<NextLayer, deflateSupported>& ws,
1149 MutableBufferSequence const& buffers) const
1151 return ws.read_some(buffers);
1155 class NextLayer, bool deflateSupported,
1156 class ConstBufferSequence>
1159 stream<NextLayer, deflateSupported>& ws,
1160 ConstBufferSequence const& buffers) const
1162 return ws.write(buffers);
1166 class NextLayer, bool deflateSupported,
1167 class ConstBufferSequence>
1170 stream<NextLayer, deflateSupported>& ws,
1172 ConstBufferSequence const& buffers) const
1174 return ws.write_some(fin, buffers);
1178 class NextLayer, bool deflateSupported,
1179 class ConstBufferSequence>
1182 stream<NextLayer, deflateSupported>& ws,
1183 ConstBufferSequence const& buffers) const
1186 ws.next_layer(), buffers);
1190 //--------------------------------------------------------------------------
1192 class test_async_api
1197 std::size_t* n_ = 0;
1201 handler(error_code& ec)
1207 handler(error_code& ec, std::size_t& n)
1214 handler(handler&& other)
1216 , pass_(boost::exchange(other.pass_, true))
1222 BEAST_EXPECT(pass_);
1226 operator()(error_code ec)
1228 BEAST_EXPECT(! pass_);
1234 operator()(error_code ec, std::size_t n)
1236 BEAST_EXPECT(! pass_);
1245 template<class NextLayer, bool deflateSupported>
1248 stream<NextLayer, deflateSupported>& ws) const
1251 ws.async_accept(handler(ec));
1252 ws.get_executor().context().run();
1253 ws.get_executor().context().restart();
1255 throw system_error{ec};
1259 class NextLayer, bool deflateSupported,
1261 typename std::enable_if<
1262 ! http::detail::is_header<Buffers>::value>::type
1264 stream<NextLayer, deflateSupported>& ws,
1265 Buffers const& buffers) const
1268 ws.async_accept(buffers, handler(ec));
1269 ws.get_executor().context().run();
1270 ws.get_executor().context().restart();
1272 throw system_error{ec};
1275 template<class NextLayer, bool deflateSupported>
1278 stream<NextLayer, deflateSupported>& ws,
1279 http::request<http::empty_body> const& req) const
1282 ws.async_accept(req, handler(ec));
1283 ws.get_executor().context().run();
1284 ws.get_executor().context().restart();
1286 throw system_error{ec};
1290 class NextLayer, bool deflateSupported,
1294 stream<NextLayer, deflateSupported>& ws,
1295 Decorator const& d) const
1298 ws.async_accept_ex(d, handler(ec));
1299 ws.get_executor().context().run();
1300 ws.get_executor().context().restart();
1302 throw system_error{ec};
1306 class NextLayer, bool deflateSupported,
1307 class Buffers, class Decorator>
1308 typename std::enable_if<
1309 ! http::detail::is_header<Buffers>::value>::type
1311 stream<NextLayer, deflateSupported>& ws,
1312 Buffers const& buffers,
1313 Decorator const& d) const
1316 ws.async_accept_ex(buffers, d, handler(ec));
1317 ws.get_executor().context().run();
1318 ws.get_executor().context().restart();
1320 throw system_error{ec};
1324 class NextLayer, bool deflateSupported,
1328 stream<NextLayer, deflateSupported>& ws,
1329 http::request<http::empty_body> const& req,
1330 Decorator const& d) const
1333 ws.async_accept_ex(req, d, handler(ec));
1334 ws.get_executor().context().run();
1335 ws.get_executor().context().restart();
1337 throw system_error{ec};
1341 class NextLayer, bool deflateSupported,
1342 class Buffers, class Decorator>
1345 stream<NextLayer, deflateSupported>& ws,
1346 http::request<http::empty_body> const& req,
1347 Buffers const& buffers,
1348 Decorator const& d) const
1352 req, buffers, d, handler(ec));
1353 ws.get_executor().context().run();
1354 ws.get_executor().context().restart();
1356 throw system_error{ec};
1360 class NextLayer, bool deflateSupported>
1363 stream<NextLayer, deflateSupported>& ws,
1365 string_view path) const
1369 uri, path, handler(ec));
1370 ws.get_executor().context().run();
1371 ws.get_executor().context().restart();
1373 throw system_error{ec};
1376 template<class NextLayer, bool deflateSupported>
1379 stream<NextLayer, deflateSupported>& ws,
1382 string_view path) const
1386 res, uri, path, handler(ec));
1387 ws.get_executor().context().run();
1388 ws.get_executor().context().restart();
1390 throw system_error{ec};
1394 class NextLayer, bool deflateSupported,
1398 stream<NextLayer, deflateSupported>& ws,
1401 Decorator const &d) const
1404 ws.async_handshake_ex(
1405 uri, path, d, handler(ec));
1406 ws.get_executor().context().run();
1407 ws.get_executor().context().restart();
1409 throw system_error{ec};
1413 class NextLayer, bool deflateSupported,
1417 stream<NextLayer, deflateSupported>& ws,
1421 Decorator const &d) const
1424 ws.async_handshake_ex(
1425 res, uri, path, d, handler(ec));
1426 ws.get_executor().context().run();
1427 ws.get_executor().context().restart();
1429 throw system_error{ec};
1432 template<class NextLayer, bool deflateSupported>
1435 stream<NextLayer, deflateSupported>& ws,
1436 ping_data const& payload) const
1439 ws.async_ping(payload, handler(ec));
1440 ws.get_executor().context().run();
1441 ws.get_executor().context().restart();
1443 throw system_error{ec};
1446 template<class NextLayer, bool deflateSupported>
1449 stream<NextLayer, deflateSupported>& ws,
1450 ping_data const& payload) const
1453 ws.async_pong(payload, handler(ec));
1454 ws.get_executor().context().run();
1455 ws.get_executor().context().restart();
1457 throw system_error{ec};
1460 template<class NextLayer, bool deflateSupported>
1463 stream<NextLayer, deflateSupported>& ws,
1464 close_reason const& cr) const
1467 ws.async_close(cr, handler(ec));
1468 ws.get_executor().context().run();
1469 ws.get_executor().context().restart();
1471 throw system_error{ec};
1475 class NextLayer, bool deflateSupported,
1476 class DynamicBuffer>
1479 stream<NextLayer, deflateSupported>& ws,
1480 DynamicBuffer& buffer) const
1484 ws.async_read(buffer, handler(ec, n));
1485 ws.get_executor().context().run();
1486 ws.get_executor().context().restart();
1488 throw system_error{ec};
1493 class NextLayer, bool deflateSupported,
1494 class DynamicBuffer>
1497 stream<NextLayer, deflateSupported>& ws,
1499 DynamicBuffer& buffer) const
1503 ws.async_read_some(buffer, limit, handler(ec, n));
1504 ws.get_executor().context().run();
1505 ws.get_executor().context().restart();
1507 throw system_error{ec};
1512 class NextLayer, bool deflateSupported,
1513 class MutableBufferSequence>
1516 stream<NextLayer, deflateSupported>& ws,
1517 MutableBufferSequence const& buffers) const
1521 ws.async_read_some(buffers, handler(ec, n));
1522 ws.get_executor().context().run();
1523 ws.get_executor().context().restart();
1525 throw system_error{ec};
1530 class NextLayer, bool deflateSupported,
1531 class ConstBufferSequence>
1534 stream<NextLayer, deflateSupported>& ws,
1535 ConstBufferSequence const& buffers) const
1539 ws.async_write(buffers, handler(ec, n));
1540 ws.get_executor().context().run();
1541 ws.get_executor().context().restart();
1543 throw system_error{ec};
1548 class NextLayer, bool deflateSupported,
1549 class ConstBufferSequence>
1552 stream<NextLayer, deflateSupported>& ws,
1554 ConstBufferSequence const& buffers) const
1558 ws.async_write_some(fin, buffers, handler(ec, n));
1559 ws.get_executor().context().run();
1560 ws.get_executor().context().restart();
1562 throw system_error{ec};
1567 class NextLayer, bool deflateSupported,
1568 class ConstBufferSequence>
1571 stream<NextLayer, deflateSupported>& ws,
1572 ConstBufferSequence const& buffers) const
1576 net::async_write(ws.next_layer(),
1577 buffers, handler(ec, n));
1578 ws.get_executor().context().run();
1579 ws.get_executor().context().restart();
1581 throw system_error{ec};