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