write.hpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  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_WRITE_HPP
  10. #define BOOST_BEAST_HTTP_WRITE_HPP
  11. #include <boost/beast/core/detail/config.hpp>
  12. #include <boost/beast/http/message.hpp>
  13. #include <boost/beast/http/serializer.hpp>
  14. #include <boost/beast/http/type_traits.hpp>
  15. #include <boost/beast/http/detail/chunk_encode.hpp>
  16. #include <boost/beast/core/error.hpp>
  17. #include <boost/beast/core/stream_traits.hpp>
  18. #include <boost/asio/async_result.hpp>
  19. #include <iosfwd>
  20. #include <limits>
  21. #include <memory>
  22. #include <type_traits>
  23. #include <utility>
  24. namespace boost {
  25. namespace beast {
  26. namespace http {
  27. /** Write part of a message to a stream using a serializer.
  28. This function is used to write part of a message to a stream using
  29. a caller-provided HTTP/1 serializer. The call will block until one
  30. of the following conditions is true:
  31. @li One or more bytes have been transferred.
  32. @li The function @ref serializer::is_done returns `true`
  33. @li An error occurs on the stream.
  34. This operation is implemented in terms of one or more calls
  35. to the stream's `write_some` function.
  36. The amount of data actually transferred is controlled by the behavior
  37. of the underlying stream, subject to the buffer size limit of the
  38. serializer obtained or set through a call to @ref serializer::limit.
  39. Setting a limit and performing bounded work helps applications set
  40. reasonable timeouts. It also allows application-level flow control
  41. to function correctly. For example when using a TCP/IP based
  42. stream.
  43. @param stream The stream to which the data is to be written.
  44. The type must support the <em>SyncWriteStream</em> concept.
  45. @param sr The serializer to use.
  46. @return The number of bytes written to the stream.
  47. @throws system_error Thrown on failure.
  48. @see serializer
  49. */
  50. template<
  51. class SyncWriteStream,
  52. bool isRequest, class Body, class Fields>
  53. std::size_t
  54. write_some(
  55. SyncWriteStream& stream,
  56. serializer<isRequest, Body, Fields>& sr);
  57. /** Write part of a message to a stream using a serializer.
  58. This function is used to write part of a message to a stream using
  59. a caller-provided HTTP/1 serializer. The call will block until one
  60. of the following conditions is true:
  61. @li One or more bytes have been transferred.
  62. @li The function @ref serializer::is_done returns `true`
  63. @li An error occurs on the stream.
  64. This operation is implemented in terms of one or more calls
  65. to the stream's `write_some` function.
  66. The amount of data actually transferred is controlled by the behavior
  67. of the underlying stream, subject to the buffer size limit of the
  68. serializer obtained or set through a call to @ref serializer::limit.
  69. Setting a limit and performing bounded work helps applications set
  70. reasonable timeouts. It also allows application-level flow control
  71. to function correctly. For example when using a TCP/IP based
  72. stream.
  73. @param stream The stream to which the data is to be written.
  74. The type must support the <em>SyncWriteStream</em> concept.
  75. @param sr The serializer to use.
  76. @param ec Set to indicate what error occurred, if any.
  77. @return The number of bytes written to the stream.
  78. @see async_write_some, serializer
  79. */
  80. template<
  81. class SyncWriteStream,
  82. bool isRequest, class Body, class Fields>
  83. std::size_t
  84. write_some(
  85. SyncWriteStream& stream,
  86. serializer<isRequest, Body, Fields>& sr,
  87. error_code& ec);
  88. /** Write part of a message to a stream asynchronously using a serializer.
  89. This function is used to write part of a message to a stream
  90. asynchronously using a caller-provided HTTP/1 serializer. The function
  91. call always returns immediately. The asynchronous operation will continue
  92. until one of the following conditions is true:
  93. @li One or more bytes have been transferred.
  94. @li The function @ref serializer::is_done returns `true`
  95. @li An error occurs on the stream.
  96. This operation is implemented in terms of zero or more calls to the stream's
  97. `async_write_some` function, and is known as a <em>composed operation</em>.
  98. The program must ensure that the stream performs no other writes
  99. until this operation completes.
  100. The amount of data actually transferred is controlled by the behavior
  101. of the underlying stream, subject to the buffer size limit of the
  102. serializer obtained or set through a call to @ref serializer::limit.
  103. Setting a limit and performing bounded work helps applications set
  104. reasonable timeouts. It also allows application-level flow control
  105. to function correctly. For example when using a TCP/IP based
  106. stream.
  107. @param stream The stream to which the data is to be written.
  108. The type must support the <em>AsyncWriteStream</em> concept.
  109. @param sr The serializer to use.
  110. The object must remain valid at least until the
  111. handler is called; ownership is not transferred.
  112. @param handler The completion handler to invoke when the operation
  113. completes. The implementation takes ownership of the handler by
  114. performing a decay-copy. The equivalent function signature of
  115. the handler must be:
  116. @code
  117. void handler(
  118. error_code const& error, // result of operation
  119. std::size_t bytes_transferred // the number of bytes written to the stream
  120. );
  121. @endcode
  122. Regardless of whether the asynchronous operation completes
  123. immediately or not, the handler will not be invoked from within
  124. this function. Invocation of the handler will be performed in a
  125. manner equivalent to using `net::post`.
  126. @par Per-Operation Cancellation
  127. This asynchronous operation supports cancellation for the following
  128. net::cancellation_type values:
  129. @li @c net::cancellation_type::terminal
  130. if the `stream` also supports terminal cancellation.
  131. `terminal` cancellation leaves the stream in an undefined state,
  132. so that only closing it is guaranteed to succeed.
  133. @see serializer
  134. */
  135. template<
  136. class AsyncWriteStream,
  137. bool isRequest, class Body, class Fields,
  138. BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
  139. net::default_completion_token_t<
  140. executor_type<AsyncWriteStream>>>
  141. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  142. async_write_some(
  143. AsyncWriteStream& stream,
  144. serializer<isRequest, Body, Fields>& sr,
  145. WriteHandler&& handler =
  146. net::default_completion_token_t<
  147. executor_type<AsyncWriteStream>>{});
  148. //------------------------------------------------------------------------------
  149. /** Write a header to a stream using a serializer.
  150. This function is used to write a header to a stream using a
  151. caller-provided HTTP/1 serializer. The call will block until one
  152. of the following conditions is true:
  153. @li The function @ref serializer::is_header_done returns `true`
  154. @li An error occurs.
  155. This operation is implemented in terms of one or more calls
  156. to the stream's `write_some` function.
  157. @param stream The stream to which the data is to be written.
  158. The type must support the <em>SyncWriteStream</em> concept.
  159. @param sr The serializer to use.
  160. @return The number of bytes written to the stream.
  161. @throws system_error Thrown on failure.
  162. @note The implementation will call @ref serializer::split with
  163. the value `true` on the serializer passed in.
  164. @see serializer
  165. */
  166. template<
  167. class SyncWriteStream,
  168. bool isRequest, class Body, class Fields>
  169. std::size_t
  170. write_header(
  171. SyncWriteStream& stream,
  172. serializer<isRequest, Body, Fields>& sr);
  173. /** Write a header to a stream using a serializer.
  174. This function is used to write a header to a stream using a
  175. caller-provided HTTP/1 serializer. The call will block until one
  176. of the following conditions is true:
  177. @li The function @ref serializer::is_header_done returns `true`
  178. @li An error occurs.
  179. This operation is implemented in terms of one or more calls
  180. to the stream's `write_some` function.
  181. @param stream The stream to which the data is to be written.
  182. The type must support the <em>SyncWriteStream</em> concept.
  183. @param sr The serializer to use.
  184. @param ec Set to indicate what error occurred, if any.
  185. @return The number of bytes written to the stream.
  186. @note The implementation will call @ref serializer::split with
  187. the value `true` on the serializer passed in.
  188. @see serializer
  189. */
  190. template<
  191. class SyncWriteStream,
  192. bool isRequest, class Body, class Fields>
  193. std::size_t
  194. write_header(
  195. SyncWriteStream& stream,
  196. serializer<isRequest, Body, Fields>& sr,
  197. error_code& ec);
  198. /** Write a header to a stream asynchronously using a serializer.
  199. This function is used to write a header to a stream asynchronously
  200. using a caller-provided HTTP/1 serializer. The function call always
  201. returns immediately. The asynchronous operation will continue until
  202. one of the following conditions is true:
  203. @li The function @ref serializer::is_header_done returns `true`
  204. @li An error occurs.
  205. This operation is implemented in terms of zero or more calls to the stream's
  206. `async_write_some` function, and is known as a <em>composed operation</em>.
  207. The program must ensure that the stream performs no other writes
  208. until this operation completes.
  209. @param stream The stream to which the data is to be written.
  210. The type must support the <em>AsyncWriteStream</em> concept.
  211. @param sr The serializer to use.
  212. The object must remain valid at least until the
  213. handler is called; ownership is not transferred.
  214. @param handler The completion handler to invoke when the operation
  215. completes. The implementation takes ownership of the handler by
  216. performing a decay-copy. The equivalent function signature of
  217. the handler must be:
  218. @code
  219. void handler(
  220. error_code const& error, // result of operation
  221. std::size_t bytes_transferred // the number of bytes written to the stream
  222. );
  223. @endcode
  224. Regardless of whether the asynchronous operation completes
  225. immediately or not, the handler will not be invoked from within
  226. this function. Invocation of the handler will be performed in a
  227. manner equivalent to using `net::post`.
  228. @note The implementation will call @ref serializer::split with
  229. the value `true` on the serializer passed in.
  230. @par Per-Operation Cancellation
  231. This asynchronous operation supports cancellation for the following
  232. net::cancellation_type values:
  233. @li @c net::cancellation_type::terminal
  234. if the `stream` also supports terminal cancellation.
  235. `terminal` cancellation leaves the stream in an undefined state,
  236. so that only closing it is guaranteed to succeed.
  237. @see serializer
  238. */
  239. template<
  240. class AsyncWriteStream,
  241. bool isRequest, class Body, class Fields,
  242. BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
  243. net::default_completion_token_t<
  244. executor_type<AsyncWriteStream>>>
  245. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  246. async_write_header(
  247. AsyncWriteStream& stream,
  248. serializer<isRequest, Body, Fields>& sr,
  249. WriteHandler&& handler =
  250. net::default_completion_token_t<
  251. executor_type<AsyncWriteStream>>{});
  252. //------------------------------------------------------------------------------
  253. /** Write a complete message to a stream using a serializer.
  254. This function is used to write a complete message to a stream using
  255. a caller-provided HTTP/1 serializer. The call will block until one
  256. of the following conditions is true:
  257. @li The function @ref serializer::is_done returns `true`
  258. @li An error occurs.
  259. This operation is implemented in terms of one or more calls
  260. to the stream's `write_some` function.
  261. @param stream The stream to which the data is to be written.
  262. The type must support the <em>SyncWriteStream</em> concept.
  263. @param sr The serializer to use.
  264. @return The number of bytes written to the stream.
  265. @throws system_error Thrown on failure.
  266. @see serializer
  267. */
  268. template<
  269. class SyncWriteStream,
  270. bool isRequest, class Body, class Fields>
  271. std::size_t
  272. write(
  273. SyncWriteStream& stream,
  274. serializer<isRequest, Body, Fields>& sr);
  275. /** Write a complete message to a stream using a serializer.
  276. This function is used to write a complete message to a stream using
  277. a caller-provided HTTP/1 serializer. The call will block until one
  278. of the following conditions is true:
  279. @li The function @ref serializer::is_done returns `true`
  280. @li An error occurs.
  281. This operation is implemented in terms of one or more calls
  282. to the stream's `write_some` function.
  283. @param stream The stream to which the data is to be written.
  284. The type must support the <em>SyncWriteStream</em> concept.
  285. @param sr The serializer to use.
  286. @param ec Set to the error, if any occurred.
  287. @return The number of bytes written to the stream.
  288. @see serializer
  289. */
  290. template<
  291. class SyncWriteStream,
  292. bool isRequest, class Body, class Fields>
  293. std::size_t
  294. write(
  295. SyncWriteStream& stream,
  296. serializer<isRequest, Body, Fields>& sr,
  297. error_code& ec);
  298. /** Write a complete message to a stream asynchronously using a serializer.
  299. This function is used to write a complete message to a stream
  300. asynchronously using a caller-provided HTTP/1 serializer. The
  301. function call always returns immediately. The asynchronous
  302. operation will continue until one of the following conditions is true:
  303. @li The function @ref serializer::is_done returns `true`
  304. @li An error occurs.
  305. This operation is implemented in terms of zero or more calls to the stream's
  306. `async_write_some` function, and is known as a <em>composed operation</em>.
  307. The program must ensure that the stream performs no other writes
  308. until this operation completes.
  309. @param stream The stream to which the data is to be written.
  310. The type must support the <em>AsyncWriteStream</em> concept.
  311. @param sr The serializer to use.
  312. The object must remain valid at least until the
  313. handler is called; ownership is not transferred.
  314. @param handler The completion handler to invoke when the operation
  315. completes. The implementation takes ownership of the handler by
  316. performing a decay-copy. The equivalent function signature of
  317. the handler must be:
  318. @code
  319. void handler(
  320. error_code const& error, // result of operation
  321. std::size_t bytes_transferred // the number of bytes written to the stream
  322. );
  323. @endcode
  324. Regardless of whether the asynchronous operation completes
  325. immediately or not, the handler will not be invoked from within
  326. this function. Invocation of the handler will be performed in a
  327. manner equivalent to using `net::post`.
  328. @par Per-Operation Cancellation
  329. This asynchronous operation supports cancellation for the following
  330. net::cancellation_type values:
  331. @li @c net::cancellation_type::terminal
  332. if the `stream` also supports terminal cancellation.
  333. `terminal` cancellation leaves the stream in an undefined state,
  334. so that only closing it is guaranteed to succeed.
  335. @see serializer
  336. */
  337. template<
  338. class AsyncWriteStream,
  339. bool isRequest, class Body, class Fields,
  340. BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
  341. net::default_completion_token_t<
  342. executor_type<AsyncWriteStream>>>
  343. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  344. async_write(
  345. AsyncWriteStream& stream,
  346. serializer<isRequest, Body, Fields>& sr,
  347. WriteHandler&& handler =
  348. net::default_completion_token_t<
  349. executor_type<AsyncWriteStream>>{});
  350. //------------------------------------------------------------------------------
  351. /** Write a complete message to a stream.
  352. This function is used to write a complete message to a stream using
  353. HTTP/1. The call will block until one of the following conditions is true:
  354. @li The entire message is written.
  355. @li An error occurs.
  356. This operation is implemented in terms of one or more calls to the stream's
  357. `write_some` function. The algorithm will use a temporary @ref serializer
  358. with an empty chunk decorator to produce buffers.
  359. @note This function only participates in overload resolution
  360. if @ref is_mutable_body_writer for <em>Body</em> returns `true`.
  361. @param stream The stream to which the data is to be written.
  362. The type must support the <em>SyncWriteStream</em> concept.
  363. @param msg The message to write.
  364. @return The number of bytes written to the stream.
  365. @throws system_error Thrown on failure.
  366. @see message
  367. */
  368. template<
  369. class SyncWriteStream,
  370. bool isRequest, class Body, class Fields>
  371. #if BOOST_BEAST_DOXYGEN
  372. std::size_t
  373. #else
  374. typename std::enable_if<
  375. is_mutable_body_writer<Body>::value,
  376. std::size_t>::type
  377. #endif
  378. write(
  379. SyncWriteStream& stream,
  380. message<isRequest, Body, Fields>& msg);
  381. /** Write a complete message to a stream.
  382. This function is used to write a complete message to a stream using
  383. HTTP/1. The call will block until one of the following conditions is true:
  384. @li The entire message is written.
  385. @li An error occurs.
  386. This operation is implemented in terms of one or more calls to the stream's
  387. `write_some` function. The algorithm will use a temporary @ref serializer
  388. with an empty chunk decorator to produce buffers.
  389. @note This function only participates in overload resolution
  390. if @ref is_mutable_body_writer for <em>Body</em> returns `false`.
  391. @param stream The stream to which the data is to be written.
  392. The type must support the <em>SyncWriteStream</em> concept.
  393. @param msg The message to write.
  394. @return The number of bytes written to the stream.
  395. @throws system_error Thrown on failure.
  396. @see message
  397. */
  398. template<
  399. class SyncWriteStream,
  400. bool isRequest, class Body, class Fields>
  401. #if BOOST_BEAST_DOXYGEN
  402. std::size_t
  403. #else
  404. typename std::enable_if<
  405. ! is_mutable_body_writer<Body>::value,
  406. std::size_t>::type
  407. #endif
  408. write(
  409. SyncWriteStream& stream,
  410. message<isRequest, Body, Fields> const& msg);
  411. /** Write a complete message to a stream.
  412. This function is used to write a complete message to a stream using
  413. HTTP/1. The call will block until one of the following conditions is true:
  414. @li The entire message is written.
  415. @li An error occurs.
  416. This operation is implemented in terms of one or more calls to the stream's
  417. `write_some` function. The algorithm will use a temporary @ref serializer
  418. with an empty chunk decorator to produce buffers.
  419. @note This function only participates in overload resolution
  420. if @ref is_mutable_body_writer for <em>Body</em> returns `true`.
  421. @param stream The stream to which the data is to be written.
  422. The type must support the <em>SyncWriteStream</em> concept.
  423. @param msg The message to write.
  424. @param ec Set to the error, if any occurred.
  425. @return The number of bytes written to the stream.
  426. @see message
  427. */
  428. template<
  429. class SyncWriteStream,
  430. bool isRequest, class Body, class Fields>
  431. #if BOOST_BEAST_DOXYGEN
  432. std::size_t
  433. #else
  434. typename std::enable_if<
  435. is_mutable_body_writer<Body>::value,
  436. std::size_t>::type
  437. #endif
  438. write(
  439. SyncWriteStream& stream,
  440. message<isRequest, Body, Fields>& msg,
  441. error_code& ec);
  442. /** Write a complete message to a stream.
  443. This function is used to write a complete message to a stream using
  444. HTTP/1. The call will block until one of the following conditions is true:
  445. @li The entire message is written.
  446. @li An error occurs.
  447. This operation is implemented in terms of one or more calls to the stream's
  448. `write_some` function. The algorithm will use a temporary @ref serializer
  449. with an empty chunk decorator to produce buffers.
  450. @note This function only participates in overload resolution
  451. if @ref is_mutable_body_writer for <em>Body</em> returns `false`.
  452. @param stream The stream to which the data is to be written.
  453. The type must support the <em>SyncWriteStream</em> concept.
  454. @param msg The message to write.
  455. @param ec Set to the error, if any occurred.
  456. @return The number of bytes written to the stream.
  457. @see message
  458. */
  459. template<
  460. class SyncWriteStream,
  461. bool isRequest, class Body, class Fields>
  462. #if BOOST_BEAST_DOXYGEN
  463. std::size_t
  464. #else
  465. typename std::enable_if<
  466. ! is_mutable_body_writer<Body>::value,
  467. std::size_t>::type
  468. #endif
  469. write(
  470. SyncWriteStream& stream,
  471. message<isRequest, Body, Fields> const& msg,
  472. error_code& ec);
  473. /** Write a complete message to a stream asynchronously.
  474. This function is used to write a complete message to a stream asynchronously
  475. using HTTP/1. The function call always returns immediately. The asynchronous
  476. operation will continue until one of the following conditions is true:
  477. @li The entire message is written.
  478. @li An error occurs.
  479. This operation is implemented in terms of zero or more calls to the stream's
  480. `async_write_some` function, and is known as a <em>composed operation</em>.
  481. The program must ensure that the stream performs no other writes
  482. until this operation completes. The algorithm will use a temporary
  483. @ref serializer with an empty chunk decorator to produce buffers.
  484. @note This function only participates in overload resolution
  485. if @ref is_mutable_body_writer for <em>Body</em> returns `true`.
  486. @param stream The stream to which the data is to be written.
  487. The type must support the <em>AsyncWriteStream</em> concept.
  488. @param msg The message to write.
  489. The object must remain valid at least until the
  490. handler is called; ownership is not transferred.
  491. @param handler The completion handler to invoke when the operation
  492. completes. The implementation takes ownership of the handler by
  493. performing a decay-copy. The equivalent function signature of
  494. the handler must be:
  495. @code
  496. void handler(
  497. error_code const& error, // result of operation
  498. std::size_t bytes_transferred // the number of bytes written to the stream
  499. );
  500. @endcode
  501. Regardless of whether the asynchronous operation completes
  502. immediately or not, the handler will not be invoked from within
  503. this function. Invocation of the handler will be performed in a
  504. manner equivalent to using `net::post`.
  505. @par Per-Operation Cancellation
  506. This asynchronous operation supports cancellation for the following
  507. net::cancellation_type values:
  508. @li @c net::cancellation_type::terminal
  509. if the `stream` also supports terminal cancellation.
  510. `terminal` cancellation leaves the stream in an undefined state,
  511. so that only closing it is guaranteed to succeed.
  512. @see message
  513. */
  514. template<
  515. class AsyncWriteStream,
  516. bool isRequest, class Body, class Fields,
  517. BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
  518. net::default_completion_token_t<
  519. executor_type<AsyncWriteStream>>>
  520. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  521. async_write(
  522. AsyncWriteStream& stream,
  523. message<isRequest, Body, Fields>& msg,
  524. WriteHandler&& handler =
  525. net::default_completion_token_t<
  526. executor_type<AsyncWriteStream>>{}
  527. #ifndef BOOST_BEAST_DOXYGEN
  528. , typename std::enable_if<
  529. is_mutable_body_writer<Body>::value>::type* = 0
  530. #endif
  531. );
  532. /** Write a complete message to a stream asynchronously.
  533. This function is used to write a complete message to a stream asynchronously
  534. using HTTP/1. The function call always returns immediately. The asynchronous
  535. operation will continue until one of the following conditions is true:
  536. @li The entire message is written.
  537. @li An error occurs.
  538. This operation is implemented in terms of zero or more calls to the stream's
  539. `async_write_some` function, and is known as a <em>composed operation</em>.
  540. The program must ensure that the stream performs no other writes
  541. until this operation completes. The algorithm will use a temporary
  542. @ref serializer with an empty chunk decorator to produce buffers.
  543. @note This function only participates in overload resolution
  544. if @ref is_mutable_body_writer for <em>Body</em> returns `false`.
  545. @param stream The stream to which the data is to be written.
  546. The type must support the <em>AsyncWriteStream</em> concept.
  547. @param msg The message to write.
  548. The object must remain valid at least until the
  549. handler is called; ownership is not transferred.
  550. @param handler The completion handler to invoke when the operation
  551. completes. The implementation takes ownership of the handler by
  552. performing a decay-copy. The equivalent function signature of
  553. the handler must be:
  554. @code
  555. void handler(
  556. error_code const& error, // result of operation
  557. std::size_t bytes_transferred // the number of bytes written to the stream
  558. );
  559. @endcode
  560. Regardless of whether the asynchronous operation completes
  561. immediately or not, the handler will not be invoked from within
  562. this function. Invocation of the handler will be performed in a
  563. manner equivalent to using `net::post`.
  564. @par Per-Operation Cancellation
  565. This asynchronous operation supports cancellation for the following
  566. net::cancellation_type values:
  567. @li @c net::cancellation_type::terminal
  568. if the `stream` also supports terminal cancellation.
  569. `terminal` cancellation leaves the stream in an undefined state,
  570. so that only closing it is guaranteed to succeed.
  571. @see message
  572. */
  573. template<
  574. class AsyncWriteStream,
  575. bool isRequest, class Body, class Fields,
  576. BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
  577. net::default_completion_token_t<
  578. executor_type<AsyncWriteStream>>>
  579. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  580. async_write(
  581. AsyncWriteStream& stream,
  582. message<isRequest, Body, Fields> const& msg,
  583. WriteHandler&& handler =
  584. net::default_completion_token_t<
  585. executor_type<AsyncWriteStream>>{}
  586. #ifndef BOOST_BEAST_DOXYGEN
  587. , typename std::enable_if<
  588. ! is_mutable_body_writer<Body>::value>::type* = 0
  589. #endif
  590. );
  591. //------------------------------------------------------------------------------
  592. /** Serialize an HTTP/1 header to a `std::ostream`.
  593. The function converts the header to its HTTP/1 serialized
  594. representation and stores the result in the output stream.
  595. @param os The output stream to write to.
  596. @param msg The message fields to write.
  597. */
  598. template<bool isRequest, class Fields>
  599. std::ostream&
  600. operator<<(std::ostream& os,
  601. header<isRequest, Fields> const& msg);
  602. /** Serialize an HTTP/1 message to a `std::ostream`.
  603. The function converts the message to its HTTP/1 serialized
  604. representation and stores the result in the output stream.
  605. The implementation will automatically perform chunk encoding if
  606. the contents of the message indicate that chunk encoding is required.
  607. @param os The output stream to write to.
  608. @param msg The message to write.
  609. */
  610. template<bool isRequest, class Body, class Fields>
  611. std::ostream&
  612. operator<<(std::ostream& os,
  613. message<isRequest, Body, Fields> const& msg);
  614. } // http
  615. } // beast
  616. } // boost
  617. #include <boost/beast/http/impl/write.hpp>
  618. #endif