write.hpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  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_HTTP_IMPL_WRITE_HPP
  10. #define BOOST_BEAST_HTTP_IMPL_WRITE_HPP
  11. #include <boost/beast/http/type_traits.hpp>
  12. #include <boost/beast/core/async_base.hpp>
  13. #include <boost/beast/core/bind_handler.hpp>
  14. #include <boost/beast/core/buffers_range.hpp>
  15. #include <boost/beast/core/make_printable.hpp>
  16. #include <boost/beast/core/stream_traits.hpp>
  17. #include <boost/beast/core/detail/is_invocable.hpp>
  18. #include <boost/asio/coroutine.hpp>
  19. #include <boost/asio/post.hpp>
  20. #include <boost/asio/write.hpp>
  21. #include <boost/optional.hpp>
  22. #include <boost/throw_exception.hpp>
  23. #include <ostream>
  24. #include <sstream>
  25. namespace boost {
  26. namespace beast {
  27. namespace http {
  28. namespace detail {
  29. template<
  30. class Handler,
  31. class Stream,
  32. bool isRequest, class Body, class Fields>
  33. class write_some_op
  34. : public beast::async_base<
  35. Handler, beast::executor_type<Stream>>
  36. {
  37. Stream& s_;
  38. serializer<isRequest,Body, Fields>& sr_;
  39. class lambda
  40. {
  41. write_some_op& op_;
  42. public:
  43. bool invoked = false;
  44. explicit
  45. lambda(write_some_op& op)
  46. : op_(op)
  47. {
  48. }
  49. template<class ConstBufferSequence>
  50. void
  51. operator()(
  52. error_code& ec,
  53. ConstBufferSequence const& buffers)
  54. {
  55. invoked = true;
  56. ec = {};
  57. op_.s_.async_write_some(
  58. buffers, std::move(op_));
  59. }
  60. };
  61. public:
  62. template<class Handler_>
  63. write_some_op(
  64. Handler_&& h,
  65. Stream& s,
  66. serializer<isRequest, Body, Fields>& sr)
  67. : async_base<
  68. Handler, beast::executor_type<Stream>>(
  69. std::forward<Handler_>(h), s.get_executor())
  70. , s_(s)
  71. , sr_(sr)
  72. {
  73. (*this)();
  74. }
  75. void
  76. operator()()
  77. {
  78. error_code ec;
  79. if(! sr_.is_done())
  80. {
  81. lambda f{*this};
  82. sr_.next(ec, f);
  83. if(ec)
  84. {
  85. BOOST_ASSERT(! f.invoked);
  86. return net::post(
  87. s_.get_executor(),
  88. beast::bind_front_handler(
  89. std::move(*this), ec, 0));
  90. }
  91. if(f.invoked)
  92. {
  93. // *this is now moved-from,
  94. return;
  95. }
  96. // What else could it be?
  97. BOOST_ASSERT(sr_.is_done());
  98. }
  99. return net::post(
  100. s_.get_executor(),
  101. beast::bind_front_handler(
  102. std::move(*this), ec, 0));
  103. }
  104. void
  105. operator()(
  106. error_code ec,
  107. std::size_t bytes_transferred)
  108. {
  109. if(! ec)
  110. sr_.consume(bytes_transferred);
  111. this->complete_now(ec, bytes_transferred);
  112. }
  113. };
  114. //------------------------------------------------------------------------------
  115. struct serializer_is_header_done
  116. {
  117. template<
  118. bool isRequest, class Body, class Fields>
  119. bool
  120. operator()(
  121. serializer<isRequest, Body, Fields>& sr) const
  122. {
  123. return sr.is_header_done();
  124. }
  125. };
  126. struct serializer_is_done
  127. {
  128. template<
  129. bool isRequest, class Body, class Fields>
  130. bool
  131. operator()(
  132. serializer<isRequest, Body, Fields>& sr) const
  133. {
  134. return sr.is_done();
  135. }
  136. };
  137. //------------------------------------------------------------------------------
  138. template<
  139. class Handler,
  140. class Stream,
  141. class Predicate,
  142. bool isRequest, class Body, class Fields>
  143. class write_op
  144. : public beast::async_base<
  145. Handler, beast::executor_type<Stream>>
  146. , public asio::coroutine
  147. {
  148. Stream& s_;
  149. serializer<isRequest, Body, Fields>& sr_;
  150. std::size_t bytes_transferred_ = 0;
  151. public:
  152. template<class Handler_>
  153. write_op(
  154. Handler_&& h,
  155. Stream& s,
  156. serializer<isRequest, Body, Fields>& sr)
  157. : async_base<
  158. Handler, beast::executor_type<Stream>>(
  159. std::forward<Handler_>(h), s.get_executor())
  160. , s_(s)
  161. , sr_(sr)
  162. {
  163. (*this)();
  164. }
  165. void
  166. operator()(
  167. error_code ec = {},
  168. std::size_t bytes_transferred = 0)
  169. {
  170. BOOST_ASIO_CORO_REENTER(*this)
  171. {
  172. if(Predicate{}(sr_))
  173. {
  174. BOOST_ASIO_CORO_YIELD
  175. net::post(
  176. s_.get_executor(),
  177. std::move(*this));
  178. goto upcall;
  179. }
  180. for(;;)
  181. {
  182. BOOST_ASIO_CORO_YIELD
  183. beast::http::async_write_some(
  184. s_, sr_, std::move(*this));
  185. bytes_transferred_ += bytes_transferred;
  186. if(ec)
  187. goto upcall;
  188. if(Predicate{}(sr_))
  189. break;
  190. }
  191. upcall:
  192. this->complete_now(ec, bytes_transferred_);
  193. }
  194. }
  195. };
  196. //------------------------------------------------------------------------------
  197. template<
  198. class Handler,
  199. class Stream,
  200. bool isRequest, class Body, class Fields>
  201. class write_msg_op
  202. : public beast::stable_async_base<
  203. Handler, beast::executor_type<Stream>>
  204. {
  205. Stream& s_;
  206. serializer<isRequest, Body, Fields>& sr_;
  207. public:
  208. template<
  209. class Handler_,
  210. class... Args>
  211. write_msg_op(
  212. Handler_&& h,
  213. Stream& s,
  214. Args&&... args)
  215. : stable_async_base<
  216. Handler, beast::executor_type<Stream>>(
  217. std::forward<Handler_>(h), s.get_executor())
  218. , s_(s)
  219. , sr_(beast::allocate_stable<
  220. serializer<isRequest, Body, Fields>>(
  221. *this, std::forward<Args>(args)...))
  222. {
  223. (*this)();
  224. }
  225. void
  226. operator()()
  227. {
  228. async_write(s_, sr_, std::move(*this));
  229. }
  230. void
  231. operator()(
  232. error_code ec, std::size_t bytes_transferred)
  233. {
  234. this->complete_now(ec, bytes_transferred);
  235. }
  236. };
  237. struct run_write_some_op
  238. {
  239. template<
  240. class WriteHandler,
  241. class Stream,
  242. bool isRequest, class Body, class Fields>
  243. void
  244. operator()(
  245. WriteHandler&& h,
  246. Stream* s,
  247. serializer<isRequest, Body, Fields>* sr)
  248. {
  249. // If you get an error on the following line it means
  250. // that your handler does not meet the documented type
  251. // requirements for the handler.
  252. static_assert(
  253. beast::detail::is_invocable<WriteHandler,
  254. void(error_code, std::size_t)>::value,
  255. "WriteHandler type requirements not met");
  256. write_some_op<
  257. typename std::decay<WriteHandler>::type,
  258. Stream,
  259. isRequest, Body, Fields>(
  260. std::forward<WriteHandler>(h), *s, *sr);
  261. }
  262. };
  263. struct run_write_op
  264. {
  265. template<
  266. class WriteHandler,
  267. class Stream,
  268. class Predicate,
  269. bool isRequest, class Body, class Fields>
  270. void
  271. operator()(
  272. WriteHandler&& h,
  273. Stream* s,
  274. Predicate const&,
  275. serializer<isRequest, Body, Fields>* sr)
  276. {
  277. // If you get an error on the following line it means
  278. // that your handler does not meet the documented type
  279. // requirements for the handler.
  280. static_assert(
  281. beast::detail::is_invocable<WriteHandler,
  282. void(error_code, std::size_t)>::value,
  283. "WriteHandler type requirements not met");
  284. write_op<
  285. typename std::decay<WriteHandler>::type,
  286. Stream,
  287. Predicate,
  288. isRequest, Body, Fields>(
  289. std::forward<WriteHandler>(h), *s, *sr);
  290. }
  291. };
  292. struct run_write_msg_op
  293. {
  294. template<
  295. class WriteHandler,
  296. class Stream,
  297. bool isRequest, class Body, class Fields,
  298. class... Args>
  299. void
  300. operator()(
  301. WriteHandler&& h,
  302. Stream* s,
  303. message<isRequest, Body, Fields>* m,
  304. std::false_type,
  305. Args&&... args)
  306. {
  307. // If you get an error on the following line it means
  308. // that your handler does not meet the documented type
  309. // requirements for the handler.
  310. static_assert(
  311. beast::detail::is_invocable<WriteHandler,
  312. void(error_code, std::size_t)>::value,
  313. "WriteHandler type requirements not met");
  314. write_msg_op<
  315. typename std::decay<WriteHandler>::type,
  316. Stream,
  317. isRequest, Body, Fields>(
  318. std::forward<WriteHandler>(h), *s, *m,
  319. std::forward<Args>(args)...);
  320. }
  321. template<
  322. class WriteHandler,
  323. class Stream,
  324. bool isRequest, class Body, class Fields,
  325. class... Args>
  326. void
  327. operator()(
  328. WriteHandler&& h,
  329. Stream* s,
  330. message<isRequest, Body, Fields> const* m,
  331. std::true_type,
  332. Args&&... args)
  333. {
  334. // If you get an error on the following line it means
  335. // that your handler does not meet the documented type
  336. // requirements for the handler.
  337. static_assert(
  338. beast::detail::is_invocable<WriteHandler,
  339. void(error_code, std::size_t)>::value,
  340. "WriteHandler type requirements not met");
  341. write_msg_op<
  342. typename std::decay<WriteHandler>::type,
  343. Stream,
  344. isRequest, Body, Fields>(
  345. std::forward<WriteHandler>(h), *s, *m,
  346. std::forward<Args>(args)...);
  347. }
  348. };
  349. //------------------------------------------------------------------------------
  350. template<class Stream>
  351. class write_some_lambda
  352. {
  353. Stream& stream_;
  354. public:
  355. bool invoked = false;
  356. std::size_t bytes_transferred = 0;
  357. explicit
  358. write_some_lambda(Stream& stream)
  359. : stream_(stream)
  360. {
  361. }
  362. template<class ConstBufferSequence>
  363. void
  364. operator()(error_code& ec,
  365. ConstBufferSequence const& buffers)
  366. {
  367. invoked = true;
  368. bytes_transferred =
  369. stream_.write_some(buffers, ec);
  370. }
  371. };
  372. template<class Stream>
  373. class write_lambda
  374. {
  375. Stream& stream_;
  376. public:
  377. bool invoked = false;
  378. std::size_t bytes_transferred = 0;
  379. explicit
  380. write_lambda(Stream& stream)
  381. : stream_(stream)
  382. {
  383. }
  384. template<class ConstBufferSequence>
  385. void
  386. operator()(error_code& ec,
  387. ConstBufferSequence const& buffers)
  388. {
  389. invoked = true;
  390. bytes_transferred = net::write(
  391. stream_, buffers, ec);
  392. }
  393. };
  394. template<
  395. class SyncWriteStream,
  396. bool isRequest, class Body, class Fields>
  397. std::size_t
  398. write_some_impl(
  399. SyncWriteStream& stream,
  400. serializer<isRequest, Body, Fields>& sr,
  401. error_code& ec)
  402. {
  403. if(! sr.is_done())
  404. {
  405. write_some_lambda<SyncWriteStream> f{stream};
  406. sr.next(ec, f);
  407. if(ec)
  408. return f.bytes_transferred;
  409. if(f.invoked)
  410. sr.consume(f.bytes_transferred);
  411. return f.bytes_transferred;
  412. }
  413. ec = {};
  414. return 0;
  415. }
  416. template<
  417. class AsyncWriteStream,
  418. bool isRequest, class Body, class Fields,
  419. class WriteHandler>
  420. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  421. async_write_some_impl(
  422. AsyncWriteStream& stream,
  423. serializer<isRequest, Body, Fields>& sr,
  424. WriteHandler&& handler)
  425. {
  426. return net::async_initiate<
  427. WriteHandler,
  428. void(error_code, std::size_t)>(
  429. run_write_some_op{},
  430. handler,
  431. &stream,
  432. &sr);
  433. }
  434. } // detail
  435. //------------------------------------------------------------------------------
  436. template<
  437. class SyncWriteStream,
  438. bool isRequest, class Body, class Fields>
  439. std::size_t
  440. write_some(
  441. SyncWriteStream& stream,
  442. serializer<isRequest, Body, Fields>& sr)
  443. {
  444. static_assert(is_sync_write_stream<SyncWriteStream>::value,
  445. "SyncWriteStream type requirements not met");
  446. static_assert(is_body<Body>::value,
  447. "Body type requirements not met");
  448. static_assert(is_body_writer<Body>::value,
  449. "BodyWriter type requirements not met");
  450. error_code ec;
  451. auto const bytes_transferred =
  452. write_some(stream, sr, ec);
  453. if(ec)
  454. BOOST_THROW_EXCEPTION(system_error{ec});
  455. return bytes_transferred;
  456. }
  457. template<
  458. class SyncWriteStream,
  459. bool isRequest, class Body, class Fields>
  460. std::size_t
  461. write_some(
  462. SyncWriteStream& stream,
  463. serializer<isRequest, Body, Fields>& sr,
  464. error_code& ec)
  465. {
  466. static_assert(is_sync_write_stream<SyncWriteStream>::value,
  467. "SyncWriteStream type requirements not met");
  468. static_assert(is_body<Body>::value,
  469. "Body type requirements not met");
  470. static_assert(is_body_writer<Body>::value,
  471. "BodyWriter type requirements not met");
  472. return detail::write_some_impl(stream, sr, ec);
  473. }
  474. template<
  475. class AsyncWriteStream,
  476. bool isRequest, class Body, class Fields,
  477. class WriteHandler>
  478. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  479. async_write_some(
  480. AsyncWriteStream& stream,
  481. serializer<isRequest, Body, Fields>& sr,
  482. WriteHandler&& handler)
  483. {
  484. static_assert(is_async_write_stream<
  485. AsyncWriteStream>::value,
  486. "AsyncWriteStream type requirements not met");
  487. static_assert(is_body<Body>::value,
  488. "Body type requirements not met");
  489. static_assert(is_body_writer<Body>::value,
  490. "BodyWriter type requirements not met");
  491. return detail::async_write_some_impl(stream, sr,
  492. std::forward<WriteHandler>(handler));
  493. }
  494. //------------------------------------------------------------------------------
  495. template<
  496. class SyncWriteStream,
  497. bool isRequest, class Body, class Fields>
  498. std::size_t
  499. write_header(SyncWriteStream& stream,
  500. serializer<isRequest, Body, Fields>& sr)
  501. {
  502. static_assert(is_sync_write_stream<SyncWriteStream>::value,
  503. "SyncWriteStream type requirements not met");
  504. static_assert(is_body<Body>::value,
  505. "Body type requirements not met");
  506. static_assert(is_body_writer<Body>::value,
  507. "BodyWriter type requirements not met");
  508. error_code ec;
  509. auto const bytes_transferred =
  510. write_header(stream, sr, ec);
  511. if(ec)
  512. BOOST_THROW_EXCEPTION(system_error{ec});
  513. return bytes_transferred;
  514. }
  515. template<
  516. class SyncWriteStream,
  517. bool isRequest, class Body, class Fields>
  518. std::size_t
  519. write_header(
  520. SyncWriteStream& stream,
  521. serializer<isRequest, Body, Fields>& sr,
  522. error_code& ec)
  523. {
  524. static_assert(is_sync_write_stream<SyncWriteStream>::value,
  525. "SyncWriteStream type requirements not met");
  526. static_assert(is_body<Body>::value,
  527. "Body type requirements not met");
  528. static_assert(is_body_writer<Body>::value,
  529. "BodyWriter type requirements not met");
  530. sr.split(true);
  531. std::size_t bytes_transferred = 0;
  532. if(! sr.is_header_done())
  533. {
  534. detail::write_lambda<SyncWriteStream> f{stream};
  535. do
  536. {
  537. sr.next(ec, f);
  538. bytes_transferred += f.bytes_transferred;
  539. if(ec)
  540. return bytes_transferred;
  541. BOOST_ASSERT(f.invoked);
  542. sr.consume(f.bytes_transferred);
  543. }
  544. while(! sr.is_header_done());
  545. }
  546. else
  547. {
  548. ec = {};
  549. }
  550. return bytes_transferred;
  551. }
  552. template<
  553. class AsyncWriteStream,
  554. bool isRequest, class Body, class Fields,
  555. class WriteHandler>
  556. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  557. async_write_header(
  558. AsyncWriteStream& stream,
  559. serializer<isRequest, Body, Fields>& sr,
  560. WriteHandler&& handler)
  561. {
  562. static_assert(is_async_write_stream<
  563. AsyncWriteStream>::value,
  564. "AsyncWriteStream type requirements not met");
  565. static_assert(is_body<Body>::value,
  566. "Body type requirements not met");
  567. static_assert(is_body_writer<Body>::value,
  568. "BodyWriter type requirements not met");
  569. sr.split(true);
  570. return net::async_initiate<
  571. WriteHandler,
  572. void(error_code, std::size_t)>(
  573. detail::run_write_op{},
  574. handler,
  575. &stream,
  576. detail::serializer_is_header_done{},
  577. &sr);
  578. }
  579. //------------------------------------------------------------------------------
  580. template<
  581. class SyncWriteStream,
  582. bool isRequest, class Body, class Fields>
  583. std::size_t
  584. write(
  585. SyncWriteStream& stream,
  586. serializer<isRequest, Body, Fields>& sr)
  587. {
  588. static_assert(is_sync_write_stream<SyncWriteStream>::value,
  589. "SyncWriteStream type requirements not met");
  590. error_code ec;
  591. auto const bytes_transferred =
  592. write(stream, sr, ec);
  593. if(ec)
  594. BOOST_THROW_EXCEPTION(system_error{ec});
  595. return bytes_transferred;
  596. }
  597. template<
  598. class SyncWriteStream,
  599. bool isRequest, class Body, class Fields>
  600. std::size_t
  601. write(
  602. SyncWriteStream& stream,
  603. serializer<isRequest, Body, Fields>& sr,
  604. error_code& ec)
  605. {
  606. static_assert(is_sync_write_stream<SyncWriteStream>::value,
  607. "SyncWriteStream type requirements not met");
  608. std::size_t bytes_transferred = 0;
  609. sr.split(false);
  610. for(;;)
  611. {
  612. bytes_transferred +=
  613. write_some(stream, sr, ec);
  614. if(ec)
  615. return bytes_transferred;
  616. if(sr.is_done())
  617. break;
  618. }
  619. return bytes_transferred;
  620. }
  621. template<
  622. class AsyncWriteStream,
  623. bool isRequest, class Body, class Fields,
  624. class WriteHandler>
  625. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  626. async_write(
  627. AsyncWriteStream& stream,
  628. serializer<isRequest, Body, Fields>& sr,
  629. WriteHandler&& handler)
  630. {
  631. static_assert(is_async_write_stream<
  632. AsyncWriteStream>::value,
  633. "AsyncWriteStream type requirements not met");
  634. static_assert(is_body<Body>::value,
  635. "Body type requirements not met");
  636. static_assert(is_body_writer<Body>::value,
  637. "BodyWriter type requirements not met");
  638. sr.split(false);
  639. return net::async_initiate<
  640. WriteHandler,
  641. void(error_code, std::size_t)>(
  642. detail::run_write_op{},
  643. handler,
  644. &stream,
  645. detail::serializer_is_done{},
  646. &sr);
  647. }
  648. //------------------------------------------------------------------------------
  649. template<
  650. class SyncWriteStream,
  651. bool isRequest, class Body, class Fields>
  652. typename std::enable_if<
  653. is_mutable_body_writer<Body>::value,
  654. std::size_t>::type
  655. write(
  656. SyncWriteStream& stream,
  657. message<isRequest, Body, Fields>& msg)
  658. {
  659. static_assert(is_sync_write_stream<SyncWriteStream>::value,
  660. "SyncWriteStream type requirements not met");
  661. static_assert(is_body<Body>::value,
  662. "Body type requirements not met");
  663. static_assert(is_body_writer<Body>::value,
  664. "BodyWriter type requirements not met");
  665. error_code ec;
  666. auto const bytes_transferred =
  667. write(stream, msg, ec);
  668. if(ec)
  669. BOOST_THROW_EXCEPTION(system_error{ec});
  670. return bytes_transferred;
  671. }
  672. template<
  673. class SyncWriteStream,
  674. bool isRequest, class Body, class Fields>
  675. typename std::enable_if<
  676. ! is_mutable_body_writer<Body>::value,
  677. std::size_t>::type
  678. write(
  679. SyncWriteStream& stream,
  680. message<isRequest, Body, Fields> const& msg)
  681. {
  682. static_assert(is_sync_write_stream<SyncWriteStream>::value,
  683. "SyncWriteStream type requirements not met");
  684. static_assert(is_body<Body>::value,
  685. "Body type requirements not met");
  686. static_assert(is_body_writer<Body>::value,
  687. "BodyWriter type requirements not met");
  688. error_code ec;
  689. auto const bytes_transferred =
  690. write(stream, msg, ec);
  691. if(ec)
  692. BOOST_THROW_EXCEPTION(system_error{ec});
  693. return bytes_transferred;
  694. }
  695. template<
  696. class SyncWriteStream,
  697. bool isRequest, class Body, class Fields>
  698. typename std::enable_if<
  699. is_mutable_body_writer<Body>::value,
  700. std::size_t>::type
  701. write(
  702. SyncWriteStream& stream,
  703. message<isRequest, Body, Fields>& msg,
  704. error_code& ec)
  705. {
  706. static_assert(is_sync_write_stream<SyncWriteStream>::value,
  707. "SyncWriteStream type requirements not met");
  708. static_assert(is_body<Body>::value,
  709. "Body type requirements not met");
  710. static_assert(is_body_writer<Body>::value,
  711. "BodyWriter type requirements not met");
  712. serializer<isRequest, Body, Fields> sr{msg};
  713. return write(stream, sr, ec);
  714. }
  715. template<
  716. class SyncWriteStream,
  717. bool isRequest, class Body, class Fields>
  718. typename std::enable_if<
  719. ! is_mutable_body_writer<Body>::value,
  720. std::size_t>::type
  721. write(
  722. SyncWriteStream& stream,
  723. message<isRequest, Body, Fields> const& msg,
  724. error_code& ec)
  725. {
  726. static_assert(is_sync_write_stream<SyncWriteStream>::value,
  727. "SyncWriteStream type requirements not met");
  728. static_assert(is_body<Body>::value,
  729. "Body type requirements not met");
  730. static_assert(is_body_writer<Body>::value,
  731. "BodyWriter type requirements not met");
  732. serializer<isRequest, Body, Fields> sr{msg};
  733. return write(stream, sr, ec);
  734. }
  735. template<
  736. class AsyncWriteStream,
  737. bool isRequest, class Body, class Fields,
  738. class WriteHandler>
  739. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  740. async_write(
  741. AsyncWriteStream& stream,
  742. message<isRequest, Body, Fields>& msg,
  743. WriteHandler&& handler,
  744. typename std::enable_if<
  745. is_mutable_body_writer<Body>::value>::type*)
  746. {
  747. static_assert(
  748. is_async_write_stream<AsyncWriteStream>::value,
  749. "AsyncWriteStream type requirements not met");
  750. static_assert(is_body<Body>::value,
  751. "Body type requirements not met");
  752. static_assert(is_body_writer<Body>::value,
  753. "BodyWriter type requirements not met");
  754. return net::async_initiate<
  755. WriteHandler,
  756. void(error_code, std::size_t)>(
  757. detail::run_write_msg_op{},
  758. handler,
  759. &stream,
  760. &msg,
  761. std::false_type{});
  762. }
  763. template<
  764. class AsyncWriteStream,
  765. bool isRequest, class Body, class Fields,
  766. class WriteHandler>
  767. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  768. async_write(
  769. AsyncWriteStream& stream,
  770. message<isRequest, Body, Fields> const& msg,
  771. WriteHandler&& handler,
  772. typename std::enable_if<
  773. ! is_mutable_body_writer<Body>::value>::type*)
  774. {
  775. static_assert(
  776. is_async_write_stream<AsyncWriteStream>::value,
  777. "AsyncWriteStream type requirements not met");
  778. static_assert(is_body<Body>::value,
  779. "Body type requirements not met");
  780. static_assert(is_body_writer<Body>::value,
  781. "BodyWriter type requirements not met");
  782. return net::async_initiate<
  783. WriteHandler,
  784. void(error_code, std::size_t)>(
  785. detail::run_write_msg_op{},
  786. handler,
  787. &stream,
  788. &msg,
  789. std::true_type{});
  790. }
  791. //------------------------------------------------------------------------------
  792. namespace detail {
  793. template<class Serializer>
  794. class write_ostream_lambda
  795. {
  796. std::ostream& os_;
  797. Serializer& sr_;
  798. public:
  799. write_ostream_lambda(std::ostream& os,
  800. Serializer& sr)
  801. : os_(os)
  802. , sr_(sr)
  803. {
  804. }
  805. template<class ConstBufferSequence>
  806. void
  807. operator()(error_code& ec,
  808. ConstBufferSequence const& buffers) const
  809. {
  810. ec = {};
  811. if(os_.fail())
  812. return;
  813. std::size_t bytes_transferred = 0;
  814. for(auto b : beast::buffers_range_ref(buffers))
  815. {
  816. os_.write(static_cast<char const*>(
  817. b.data()), b.size());
  818. if(os_.fail())
  819. return;
  820. bytes_transferred += b.size();
  821. }
  822. sr_.consume(bytes_transferred);
  823. }
  824. };
  825. } // detail
  826. template<class Fields>
  827. std::ostream&
  828. operator<<(std::ostream& os,
  829. header<true, Fields> const& h)
  830. {
  831. typename Fields::writer fr{
  832. h, h.version(), h.method()};
  833. return os << beast::make_printable(fr.get());
  834. }
  835. template<class Fields>
  836. std::ostream&
  837. operator<<(std::ostream& os,
  838. header<false, Fields> const& h)
  839. {
  840. typename Fields::writer fr{
  841. h, h.version(), h.result_int()};
  842. return os << beast::make_printable(fr.get());
  843. }
  844. template<bool isRequest, class Body, class Fields>
  845. std::ostream&
  846. operator<<(std::ostream& os,
  847. message<isRequest, Body, Fields> const& msg)
  848. {
  849. static_assert(is_body<Body>::value,
  850. "Body type requirements not met");
  851. static_assert(is_body_writer<Body>::value,
  852. "BodyWriter type requirements not met");
  853. serializer<isRequest, Body, Fields> sr{msg};
  854. error_code ec;
  855. detail::write_ostream_lambda<decltype(sr)> f{os, sr};
  856. do
  857. {
  858. sr.next(ec, f);
  859. if(os.fail())
  860. break;
  861. if(ec)
  862. {
  863. os.setstate(std::ios::failbit);
  864. break;
  865. }
  866. }
  867. while(! sr.is_done());
  868. return os;
  869. }
  870. } // http
  871. } // beast
  872. } // boost
  873. #endif