write.hpp 24 KB

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