accept.hpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. //
  2. // Copyright (c) 2016-2019 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. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_WEBSOCKET_IMPL_ACCEPT_IPP
  10. #define BOOST_BEAST_WEBSOCKET_IMPL_ACCEPT_IPP
  11. #include <boost/beast/websocket/impl/stream_impl.hpp>
  12. #include <boost/beast/websocket/detail/type_traits.hpp>
  13. #include <boost/beast/http/empty_body.hpp>
  14. #include <boost/beast/http/parser.hpp>
  15. #include <boost/beast/http/read.hpp>
  16. #include <boost/beast/http/string_body.hpp>
  17. #include <boost/beast/http/write.hpp>
  18. #include <boost/beast/core/async_base.hpp>
  19. #include <boost/beast/core/buffer_traits.hpp>
  20. #include <boost/beast/core/stream_traits.hpp>
  21. #include <boost/beast/core/detail/buffer.hpp>
  22. #include <boost/beast/version.hpp>
  23. #include <boost/asio/coroutine.hpp>
  24. #include <boost/asio/post.hpp>
  25. #include <boost/assert.hpp>
  26. #include <boost/throw_exception.hpp>
  27. #include <memory>
  28. #include <type_traits>
  29. namespace boost {
  30. namespace beast {
  31. namespace websocket {
  32. //------------------------------------------------------------------------------
  33. namespace detail {
  34. template<class Body, class Allocator>
  35. void
  36. impl_base<true>::
  37. build_response_pmd(
  38. http::response<http::string_body>& res,
  39. http::request<Body,
  40. http::basic_fields<Allocator>> const& req)
  41. {
  42. pmd_offer offer;
  43. pmd_offer unused;
  44. pmd_read(offer, req);
  45. pmd_negotiate(res, unused, offer, pmd_opts_);
  46. }
  47. template<class Body, class Allocator>
  48. void
  49. impl_base<false>::
  50. build_response_pmd(
  51. http::response<http::string_body>&,
  52. http::request<Body,
  53. http::basic_fields<Allocator>> const&)
  54. {
  55. }
  56. } // detail
  57. template<class NextLayer, bool deflateSupported>
  58. template<class Body, class Allocator, class Decorator>
  59. response_type
  60. stream<NextLayer, deflateSupported>::impl_type::
  61. build_response(
  62. http::request<Body,
  63. http::basic_fields<Allocator>> const& req,
  64. Decorator const& decorator,
  65. error_code& result)
  66. {
  67. auto const decorate =
  68. [this, &decorator](response_type& res)
  69. {
  70. decorator_opt(res);
  71. decorator(res);
  72. if(! res.count(http::field::server))
  73. res.set(http::field::server,
  74. string_view(BOOST_BEAST_VERSION_STRING));
  75. };
  76. auto err =
  77. [&](error e)
  78. {
  79. result = e;
  80. response_type res;
  81. res.version(req.version());
  82. res.result(http::status::bad_request);
  83. res.body() = result.message();
  84. res.prepare_payload();
  85. decorate(res);
  86. return res;
  87. };
  88. if(req.version() != 11)
  89. return err(error::bad_http_version);
  90. if(req.method() != http::verb::get)
  91. return err(error::bad_method);
  92. if(! req.count(http::field::host))
  93. return err(error::no_host);
  94. {
  95. auto const it = req.find(http::field::connection);
  96. if(it == req.end())
  97. return err(error::no_connection);
  98. if(! http::token_list{it->value()}.exists("upgrade"))
  99. return err(error::no_connection_upgrade);
  100. }
  101. {
  102. auto const it = req.find(http::field::upgrade);
  103. if(it == req.end())
  104. return err(error::no_upgrade);
  105. if(! http::token_list{it->value()}.exists("websocket"))
  106. return err(error::no_upgrade_websocket);
  107. }
  108. string_view key;
  109. {
  110. auto const it = req.find(http::field::sec_websocket_key);
  111. if(it == req.end())
  112. return err(error::no_sec_key);
  113. key = it->value();
  114. if(key.size() > detail::sec_ws_key_type::max_size_n)
  115. return err(error::bad_sec_key);
  116. }
  117. {
  118. auto const it = req.find(http::field::sec_websocket_version);
  119. if(it == req.end())
  120. return err(error::no_sec_version);
  121. if(it->value() != "13")
  122. {
  123. response_type res;
  124. res.result(http::status::upgrade_required);
  125. res.version(req.version());
  126. res.set(http::field::sec_websocket_version, "13");
  127. result = error::bad_sec_version;
  128. res.body() = result.message();
  129. res.prepare_payload();
  130. decorate(res);
  131. return res;
  132. }
  133. }
  134. response_type res;
  135. res.result(http::status::switching_protocols);
  136. res.version(req.version());
  137. res.set(http::field::upgrade, "websocket");
  138. res.set(http::field::connection, "upgrade");
  139. {
  140. detail::sec_ws_accept_type acc;
  141. detail::make_sec_ws_accept(acc, key);
  142. res.set(http::field::sec_websocket_accept, acc);
  143. }
  144. this->build_response_pmd(res, req);
  145. decorate(res);
  146. result = {};
  147. return res;
  148. }
  149. //------------------------------------------------------------------------------
  150. /** Respond to an HTTP request
  151. */
  152. template<class NextLayer, bool deflateSupported>
  153. template<class Handler>
  154. class stream<NextLayer, deflateSupported>::response_op
  155. : public beast::stable_async_base<
  156. Handler, beast::executor_type<stream>>
  157. , public asio::coroutine
  158. {
  159. boost::weak_ptr<impl_type> wp_;
  160. error_code result_; // must come before res_
  161. response_type& res_;
  162. public:
  163. template<
  164. class Handler_,
  165. class Body, class Allocator,
  166. class Decorator>
  167. response_op(
  168. Handler_&& h,
  169. boost::shared_ptr<impl_type> const& sp,
  170. http::request<Body,
  171. http::basic_fields<Allocator>> const& req,
  172. Decorator const& decorator,
  173. bool cont = false)
  174. : stable_async_base<Handler,
  175. beast::executor_type<stream>>(
  176. std::forward<Handler_>(h),
  177. sp->stream().get_executor())
  178. , wp_(sp)
  179. , res_(beast::allocate_stable<response_type>(*this,
  180. sp->build_response(req, decorator, result_)))
  181. {
  182. (*this)({}, 0, cont);
  183. }
  184. void operator()(
  185. error_code ec = {},
  186. std::size_t bytes_transferred = 0,
  187. bool cont = true)
  188. {
  189. boost::ignore_unused(bytes_transferred);
  190. auto sp = wp_.lock();
  191. if(! sp)
  192. {
  193. ec = net::error::operation_aborted;
  194. return this->complete(cont, ec);
  195. }
  196. auto& impl = *sp;
  197. BOOST_ASIO_CORO_REENTER(*this)
  198. {
  199. impl.change_status(status::handshake);
  200. impl.update_timer(this->get_executor());
  201. // Send response
  202. BOOST_ASIO_CORO_YIELD
  203. http::async_write(
  204. impl.stream(), res_, std::move(*this));
  205. if(impl.check_stop_now(ec))
  206. goto upcall;
  207. if(! ec)
  208. ec = result_;
  209. if(! ec)
  210. {
  211. impl.do_pmd_config(res_);
  212. impl.open(role_type::server);
  213. }
  214. upcall:
  215. this->complete(cont, ec);
  216. }
  217. }
  218. };
  219. //------------------------------------------------------------------------------
  220. // read and respond to an upgrade request
  221. //
  222. template<class NextLayer, bool deflateSupported>
  223. template<class Handler, class Decorator>
  224. class stream<NextLayer, deflateSupported>::accept_op
  225. : public beast::stable_async_base<
  226. Handler, beast::executor_type<stream>>
  227. , public asio::coroutine
  228. {
  229. boost::weak_ptr<impl_type> wp_;
  230. http::request_parser<http::empty_body>& p_;
  231. Decorator d_;
  232. public:
  233. template<class Handler_, class Buffers>
  234. accept_op(
  235. Handler_&& h,
  236. boost::shared_ptr<impl_type> const& sp,
  237. Decorator const& decorator,
  238. Buffers const& buffers)
  239. : stable_async_base<Handler,
  240. beast::executor_type<stream>>(
  241. std::forward<Handler_>(h),
  242. sp->stream().get_executor())
  243. , wp_(sp)
  244. , p_(beast::allocate_stable<
  245. http::request_parser<http::empty_body>>(*this))
  246. , d_(decorator)
  247. {
  248. auto& impl = *sp;
  249. error_code ec;
  250. auto const mb =
  251. beast::detail::dynamic_buffer_prepare(
  252. impl.rd_buf, buffer_bytes(buffers),
  253. ec, error::buffer_overflow);
  254. if(! ec)
  255. impl.rd_buf.commit(
  256. net::buffer_copy(*mb, buffers));
  257. (*this)(ec);
  258. }
  259. void operator()(
  260. error_code ec = {},
  261. std::size_t bytes_transferred = 0,
  262. bool cont = true)
  263. {
  264. boost::ignore_unused(bytes_transferred);
  265. auto sp = wp_.lock();
  266. if(! sp)
  267. {
  268. ec = net::error::operation_aborted;
  269. return this->complete(cont, ec);
  270. }
  271. auto& impl = *sp;
  272. BOOST_ASIO_CORO_REENTER(*this)
  273. {
  274. impl.change_status(status::handshake);
  275. impl.update_timer(this->get_executor());
  276. // The constructor could have set ec
  277. if(ec)
  278. goto upcall;
  279. BOOST_ASIO_CORO_YIELD
  280. http::async_read(impl.stream(),
  281. impl.rd_buf, p_, std::move(*this));
  282. if(ec == http::error::end_of_stream)
  283. ec = error::closed;
  284. if(impl.check_stop_now(ec))
  285. goto upcall;
  286. {
  287. // Arguments from our state must be
  288. // moved to the stack before releasing
  289. // the handler.
  290. auto const req = p_.release();
  291. auto const decorator = d_;
  292. response_op<Handler>(
  293. this->release_handler(),
  294. sp, req, decorator, true);
  295. return;
  296. }
  297. upcall:
  298. this->complete(cont, ec);
  299. }
  300. }
  301. };
  302. template<class NextLayer, bool deflateSupported>
  303. struct stream<NextLayer, deflateSupported>::
  304. run_response_op
  305. {
  306. template<
  307. class AcceptHandler,
  308. class Body, class Allocator,
  309. class Decorator>
  310. void
  311. operator()(
  312. AcceptHandler&& h,
  313. boost::shared_ptr<impl_type> const& sp,
  314. http::request<Body,
  315. http::basic_fields<Allocator>> const* m,
  316. Decorator const& d)
  317. {
  318. // If you get an error on the following line it means
  319. // that your handler does not meet the documented type
  320. // requirements for the handler.
  321. static_assert(
  322. beast::detail::is_invocable<AcceptHandler,
  323. void(error_code)>::value,
  324. "AcceptHandler type requirements not met");
  325. response_op<
  326. typename std::decay<AcceptHandler>::type>(
  327. std::forward<AcceptHandler>(h), sp, *m, d);
  328. }
  329. };
  330. template<class NextLayer, bool deflateSupported>
  331. struct stream<NextLayer, deflateSupported>::
  332. run_accept_op
  333. {
  334. template<
  335. class AcceptHandler,
  336. class Decorator,
  337. class Buffers>
  338. void
  339. operator()(
  340. AcceptHandler&& h,
  341. boost::shared_ptr<impl_type> const& sp,
  342. Decorator const& d,
  343. Buffers const& b)
  344. {
  345. // If you get an error on the following line it means
  346. // that your handler does not meet the documented type
  347. // requirements for the handler.
  348. static_assert(
  349. beast::detail::is_invocable<AcceptHandler,
  350. void(error_code)>::value,
  351. "AcceptHandler type requirements not met");
  352. accept_op<
  353. typename std::decay<AcceptHandler>::type,
  354. Decorator>(
  355. std::forward<AcceptHandler>(h),
  356. sp,
  357. d,
  358. b);
  359. }
  360. };
  361. //------------------------------------------------------------------------------
  362. template<class NextLayer, bool deflateSupported>
  363. template<class Body, class Allocator,
  364. class Decorator>
  365. void
  366. stream<NextLayer, deflateSupported>::
  367. do_accept(
  368. http::request<Body,
  369. http::basic_fields<Allocator>> const& req,
  370. Decorator const& decorator,
  371. error_code& ec)
  372. {
  373. impl_->change_status(status::handshake);
  374. error_code result;
  375. auto const res = impl_->build_response(req, decorator, result);
  376. http::write(impl_->stream(), res, ec);
  377. if(ec)
  378. return;
  379. ec = result;
  380. if(ec)
  381. {
  382. // VFALCO TODO Respect keep alive setting, perform
  383. // teardown if Connection: close.
  384. return;
  385. }
  386. impl_->do_pmd_config(res);
  387. impl_->open(role_type::server);
  388. }
  389. template<class NextLayer, bool deflateSupported>
  390. template<class Buffers, class Decorator>
  391. void
  392. stream<NextLayer, deflateSupported>::
  393. do_accept(
  394. Buffers const& buffers,
  395. Decorator const& decorator,
  396. error_code& ec)
  397. {
  398. impl_->reset();
  399. auto const mb =
  400. beast::detail::dynamic_buffer_prepare(
  401. impl_->rd_buf, buffer_bytes(buffers), ec,
  402. error::buffer_overflow);
  403. if(ec)
  404. return;
  405. impl_->rd_buf.commit(net::buffer_copy(*mb, buffers));
  406. http::request_parser<http::empty_body> p;
  407. http::read(next_layer(), impl_->rd_buf, p, ec);
  408. if(ec == http::error::end_of_stream)
  409. ec = error::closed;
  410. if(ec)
  411. return;
  412. do_accept(p.get(), decorator, ec);
  413. }
  414. //------------------------------------------------------------------------------
  415. template<class NextLayer, bool deflateSupported>
  416. void
  417. stream<NextLayer, deflateSupported>::
  418. accept()
  419. {
  420. static_assert(is_sync_stream<next_layer_type>::value,
  421. "SyncStream type requirements not met");
  422. error_code ec;
  423. accept(ec);
  424. if(ec)
  425. BOOST_THROW_EXCEPTION(system_error{ec});
  426. }
  427. template<class NextLayer, bool deflateSupported>
  428. void
  429. stream<NextLayer, deflateSupported>::
  430. accept(error_code& ec)
  431. {
  432. static_assert(is_sync_stream<next_layer_type>::value,
  433. "SyncStream type requirements not met");
  434. do_accept(
  435. net::const_buffer{},
  436. &default_decorate_res, ec);
  437. }
  438. template<class NextLayer, bool deflateSupported>
  439. template<class ConstBufferSequence>
  440. typename std::enable_if<! http::detail::is_header<
  441. ConstBufferSequence>::value>::type
  442. stream<NextLayer, deflateSupported>::
  443. accept(ConstBufferSequence const& buffers)
  444. {
  445. static_assert(is_sync_stream<next_layer_type>::value,
  446. "SyncStream type requirements not met");
  447. static_assert(net::is_const_buffer_sequence<
  448. ConstBufferSequence>::value,
  449. "ConstBufferSequence type requirements not met");
  450. error_code ec;
  451. accept(buffers, ec);
  452. if(ec)
  453. BOOST_THROW_EXCEPTION(system_error{ec});
  454. }
  455. template<class NextLayer, bool deflateSupported>
  456. template<class ConstBufferSequence>
  457. typename std::enable_if<! http::detail::is_header<
  458. ConstBufferSequence>::value>::type
  459. stream<NextLayer, deflateSupported>::
  460. accept(
  461. ConstBufferSequence const& buffers, error_code& ec)
  462. {
  463. static_assert(is_sync_stream<next_layer_type>::value,
  464. "SyncStream type requirements not met");
  465. static_assert(net::is_const_buffer_sequence<
  466. ConstBufferSequence>::value,
  467. "ConstBufferSequence type requirements not met");
  468. do_accept(buffers, &default_decorate_res, ec);
  469. }
  470. template<class NextLayer, bool deflateSupported>
  471. template<class Body, class Allocator>
  472. void
  473. stream<NextLayer, deflateSupported>::
  474. accept(
  475. http::request<Body,
  476. http::basic_fields<Allocator>> const& req)
  477. {
  478. static_assert(is_sync_stream<next_layer_type>::value,
  479. "SyncStream type requirements not met");
  480. error_code ec;
  481. accept(req, ec);
  482. if(ec)
  483. BOOST_THROW_EXCEPTION(system_error{ec});
  484. }
  485. template<class NextLayer, bool deflateSupported>
  486. template<class Body, class Allocator>
  487. void
  488. stream<NextLayer, deflateSupported>::
  489. accept(
  490. http::request<Body,
  491. http::basic_fields<Allocator>> const& req,
  492. error_code& ec)
  493. {
  494. static_assert(is_sync_stream<next_layer_type>::value,
  495. "SyncStream type requirements not met");
  496. impl_->reset();
  497. do_accept(req, &default_decorate_res, ec);
  498. }
  499. //------------------------------------------------------------------------------
  500. template<class NextLayer, bool deflateSupported>
  501. template<
  502. class AcceptHandler>
  503. BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
  504. stream<NextLayer, deflateSupported>::
  505. async_accept(
  506. AcceptHandler&& handler)
  507. {
  508. static_assert(is_async_stream<next_layer_type>::value,
  509. "AsyncStream type requirements not met");
  510. impl_->reset();
  511. return net::async_initiate<
  512. AcceptHandler,
  513. void(error_code)>(
  514. run_accept_op{},
  515. handler,
  516. impl_,
  517. &default_decorate_res,
  518. net::const_buffer{});
  519. }
  520. template<class NextLayer, bool deflateSupported>
  521. template<
  522. class ResponseDecorator,
  523. class AcceptHandler>
  524. BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
  525. stream<NextLayer, deflateSupported>::
  526. async_accept_ex(
  527. ResponseDecorator const& decorator,
  528. AcceptHandler&& handler)
  529. {
  530. static_assert(is_async_stream<next_layer_type>::value,
  531. "AsyncStream type requirements not met");
  532. static_assert(detail::is_response_decorator<
  533. ResponseDecorator>::value,
  534. "ResponseDecorator requirements not met");
  535. impl_->reset();
  536. return net::async_initiate<
  537. AcceptHandler,
  538. void(error_code)>(
  539. run_accept_op{},
  540. handler,
  541. impl_,
  542. decorator,
  543. net::const_buffer{});
  544. }
  545. template<class NextLayer, bool deflateSupported>
  546. template<
  547. class ConstBufferSequence,
  548. class AcceptHandler>
  549. BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
  550. stream<NextLayer, deflateSupported>::
  551. async_accept(
  552. ConstBufferSequence const& buffers,
  553. AcceptHandler&& handler,
  554. typename std::enable_if<
  555. ! http::detail::is_header<
  556. ConstBufferSequence>::value>::type*
  557. )
  558. {
  559. static_assert(is_async_stream<next_layer_type>::value,
  560. "AsyncStream type requirements not met");
  561. static_assert(net::is_const_buffer_sequence<
  562. ConstBufferSequence>::value,
  563. "ConstBufferSequence type requirements not met");
  564. impl_->reset();
  565. return net::async_initiate<
  566. AcceptHandler,
  567. void(error_code)>(
  568. run_accept_op{},
  569. handler,
  570. impl_,
  571. &default_decorate_res,
  572. buffers);
  573. }
  574. template<class NextLayer, bool deflateSupported>
  575. template<
  576. class ConstBufferSequence,
  577. class ResponseDecorator,
  578. class AcceptHandler>
  579. BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
  580. stream<NextLayer, deflateSupported>::
  581. async_accept_ex(
  582. ConstBufferSequence const& buffers,
  583. ResponseDecorator const& decorator,
  584. AcceptHandler&& handler,
  585. typename std::enable_if<
  586. ! http::detail::is_header<
  587. ConstBufferSequence>::value>::type*)
  588. {
  589. static_assert(is_async_stream<next_layer_type>::value,
  590. "AsyncStream type requirements not met");
  591. static_assert(net::is_const_buffer_sequence<
  592. ConstBufferSequence>::value,
  593. "ConstBufferSequence type requirements not met");
  594. static_assert(detail::is_response_decorator<
  595. ResponseDecorator>::value,
  596. "ResponseDecorator requirements not met");
  597. impl_->reset();
  598. return net::async_initiate<
  599. AcceptHandler,
  600. void(error_code)>(
  601. run_accept_op{},
  602. handler,
  603. impl_,
  604. decorator,
  605. buffers);
  606. }
  607. template<class NextLayer, bool deflateSupported>
  608. template<
  609. class Body, class Allocator,
  610. class AcceptHandler>
  611. BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
  612. stream<NextLayer, deflateSupported>::
  613. async_accept(
  614. http::request<Body, http::basic_fields<Allocator>> const& req,
  615. AcceptHandler&& handler)
  616. {
  617. static_assert(is_async_stream<next_layer_type>::value,
  618. "AsyncStream type requirements not met");
  619. impl_->reset();
  620. return net::async_initiate<
  621. AcceptHandler,
  622. void(error_code)>(
  623. run_response_op{},
  624. handler,
  625. impl_,
  626. &req,
  627. &default_decorate_res);
  628. }
  629. template<class NextLayer, bool deflateSupported>
  630. template<
  631. class Body, class Allocator,
  632. class ResponseDecorator,
  633. class AcceptHandler>
  634. BOOST_BEAST_ASYNC_RESULT1(AcceptHandler)
  635. stream<NextLayer, deflateSupported>::
  636. async_accept_ex(
  637. http::request<Body, http::basic_fields<Allocator>> const& req,
  638. ResponseDecorator const& decorator,
  639. AcceptHandler&& handler)
  640. {
  641. static_assert(is_async_stream<next_layer_type>::value,
  642. "AsyncStream type requirements not met");
  643. static_assert(detail::is_response_decorator<
  644. ResponseDecorator>::value,
  645. "ResponseDecorator requirements not met");
  646. impl_->reset();
  647. return net::async_initiate<
  648. AcceptHandler,
  649. void(error_code)>(
  650. run_response_op{},
  651. handler,
  652. impl_,
  653. &req,
  654. decorator);
  655. }
  656. //------------------------------------------------------------------------------
  657. template<class NextLayer, bool deflateSupported>
  658. template<class ResponseDecorator>
  659. void
  660. stream<NextLayer, deflateSupported>::
  661. accept_ex(ResponseDecorator const& decorator)
  662. {
  663. #ifndef BOOST_BEAST_ALLOW_DEPRECATED
  664. static_assert(sizeof(ResponseDecorator) == 0,
  665. BOOST_BEAST_DEPRECATION_STRING);
  666. #endif
  667. static_assert(is_sync_stream<next_layer_type>::value,
  668. "SyncStream type requirements not met");
  669. static_assert(detail::is_response_decorator<
  670. ResponseDecorator>::value,
  671. "ResponseDecorator requirements not met");
  672. error_code ec;
  673. accept_ex(decorator, ec);
  674. if(ec)
  675. BOOST_THROW_EXCEPTION(system_error{ec});
  676. }
  677. template<class NextLayer, bool deflateSupported>
  678. template<class ResponseDecorator>
  679. void
  680. stream<NextLayer, deflateSupported>::
  681. accept_ex(ResponseDecorator const& decorator, error_code& ec)
  682. {
  683. #ifndef BOOST_BEAST_ALLOW_DEPRECATED
  684. static_assert(sizeof(ResponseDecorator) == 0,
  685. BOOST_BEAST_DEPRECATION_STRING);
  686. #endif
  687. static_assert(is_sync_stream<next_layer_type>::value,
  688. "SyncStream type requirements not met");
  689. static_assert(detail::is_response_decorator<
  690. ResponseDecorator>::value,
  691. "ResponseDecorator requirements not met");
  692. do_accept(
  693. net::const_buffer{},
  694. decorator, ec);
  695. }
  696. template<class NextLayer, bool deflateSupported>
  697. template<
  698. class ConstBufferSequence,
  699. class ResponseDecorator>
  700. typename std::enable_if<! http::detail::is_header<
  701. ConstBufferSequence>::value>::type
  702. stream<NextLayer, deflateSupported>::
  703. accept_ex(
  704. ConstBufferSequence const& buffers,
  705. ResponseDecorator const &decorator)
  706. {
  707. #ifndef BOOST_BEAST_ALLOW_DEPRECATED
  708. static_assert(sizeof(ResponseDecorator) == 0,
  709. BOOST_BEAST_DEPRECATION_STRING);
  710. #endif
  711. static_assert(is_sync_stream<next_layer_type>::value,
  712. "SyncStream type requirements not met");
  713. static_assert(net::is_const_buffer_sequence<
  714. ConstBufferSequence>::value,
  715. "ConstBufferSequence type requirements not met");
  716. static_assert(detail::is_response_decorator<
  717. ResponseDecorator>::value,
  718. "ResponseDecorator requirements not met");
  719. error_code ec;
  720. accept_ex(buffers, decorator, ec);
  721. if(ec)
  722. BOOST_THROW_EXCEPTION(system_error{ec});
  723. }
  724. template<class NextLayer, bool deflateSupported>
  725. template<
  726. class ConstBufferSequence,
  727. class ResponseDecorator>
  728. typename std::enable_if<! http::detail::is_header<
  729. ConstBufferSequence>::value>::type
  730. stream<NextLayer, deflateSupported>::
  731. accept_ex(
  732. ConstBufferSequence const& buffers,
  733. ResponseDecorator const& decorator,
  734. error_code& ec)
  735. {
  736. #ifndef BOOST_BEAST_ALLOW_DEPRECATED
  737. static_assert(sizeof(ResponseDecorator) == 0,
  738. BOOST_BEAST_DEPRECATION_STRING);
  739. #endif
  740. static_assert(is_sync_stream<next_layer_type>::value,
  741. "SyncStream type requirements not met");
  742. static_assert(net::is_const_buffer_sequence<
  743. ConstBufferSequence>::value,
  744. "ConstBufferSequence type requirements not met");
  745. static_assert(net::is_const_buffer_sequence<
  746. ConstBufferSequence>::value,
  747. "ConstBufferSequence type requirements not met");
  748. do_accept(buffers, decorator, ec);
  749. }
  750. template<class NextLayer, bool deflateSupported>
  751. template<
  752. class Body, class Allocator,
  753. class ResponseDecorator>
  754. void
  755. stream<NextLayer, deflateSupported>::
  756. accept_ex(
  757. http::request<Body,
  758. http::basic_fields<Allocator>> const& req,
  759. ResponseDecorator const& decorator)
  760. {
  761. #ifndef BOOST_BEAST_ALLOW_DEPRECATED
  762. static_assert(sizeof(ResponseDecorator) == 0,
  763. BOOST_BEAST_DEPRECATION_STRING);
  764. #endif
  765. static_assert(is_sync_stream<next_layer_type>::value,
  766. "SyncStream type requirements not met");
  767. static_assert(detail::is_response_decorator<
  768. ResponseDecorator>::value,
  769. "ResponseDecorator requirements not met");
  770. error_code ec;
  771. accept_ex(req, decorator, ec);
  772. if(ec)
  773. BOOST_THROW_EXCEPTION(system_error{ec});
  774. }
  775. template<class NextLayer, bool deflateSupported>
  776. template<
  777. class Body, class Allocator,
  778. class ResponseDecorator>
  779. void
  780. stream<NextLayer, deflateSupported>::
  781. accept_ex(
  782. http::request<Body,
  783. http::basic_fields<Allocator>> const& req,
  784. ResponseDecorator const& decorator,
  785. error_code& ec)
  786. {
  787. #ifndef BOOST_BEAST_ALLOW_DEPRECATED
  788. static_assert(sizeof(ResponseDecorator) == 0,
  789. BOOST_BEAST_DEPRECATION_STRING);
  790. #endif
  791. static_assert(is_sync_stream<next_layer_type>::value,
  792. "SyncStream type requirements not met");
  793. static_assert(detail::is_response_decorator<
  794. ResponseDecorator>::value,
  795. "ResponseDecorator requirements not met");
  796. impl_->reset();
  797. do_accept(req, decorator, ec);
  798. }
  799. } // websocket
  800. } // beast
  801. } // boost
  802. #endif