write.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  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/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 <em>SyncWriteStream</em> 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 <em>SyncWriteStream</em> 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 async_write_some, 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 <em>AsyncWriteStream</em> 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 The completion handler to invoke when the operation
  116. completes. The implementation takes ownership of the handler by
  117. performing a decay-copy. The equivalent function signature of
  118. the handler must be:
  119. @code
  120. void handler(
  121. error_code const& error, // result of operation
  122. std::size_t bytes_transferred // the number of bytes written to the stream
  123. );
  124. @endcode
  125. Regardless of whether the asynchronous operation completes
  126. immediately or not, the handler will not be invoked from within
  127. this function. Invocation of the handler will be performed in a
  128. manner equivalent to using `net::post`.
  129. @see serializer
  130. */
  131. template<
  132. class AsyncWriteStream,
  133. bool isRequest, class Body, class Fields,
  134. class WriteHandler>
  135. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  136. async_write_some(
  137. AsyncWriteStream& stream,
  138. serializer<isRequest, Body, Fields>& sr,
  139. WriteHandler&& handler);
  140. //------------------------------------------------------------------------------
  141. /** Write a header to a stream using a serializer.
  142. This function is used to write a header to a stream using a
  143. caller-provided HTTP/1 serializer. The call will block until one
  144. of the following conditions is true:
  145. @li The function @ref serializer::is_header_done returns `true`
  146. @li An error occurs.
  147. This operation is implemented in terms of one or more calls
  148. to the stream's `write_some` function.
  149. @param stream The stream to which the data is to be written.
  150. The type must support the <em>SyncWriteStream</em> concept.
  151. @param sr The serializer to use.
  152. @return The number of bytes written to the stream.
  153. @throws system_error Thrown on failure.
  154. @note The implementation will call @ref serializer::split with
  155. the value `true` on the serializer passed in.
  156. @see serializer
  157. */
  158. template<
  159. class SyncWriteStream,
  160. bool isRequest, class Body, class Fields>
  161. std::size_t
  162. write_header(
  163. SyncWriteStream& stream,
  164. serializer<isRequest, Body, Fields>& sr);
  165. /** Write a header to a stream using a serializer.
  166. This function is used to write a header to a stream using a
  167. caller-provided HTTP/1 serializer. The call will block until one
  168. of the following conditions is true:
  169. @li The function @ref serializer::is_header_done returns `true`
  170. @li An error occurs.
  171. This operation is implemented in terms of one or more calls
  172. to the stream's `write_some` function.
  173. @param stream The stream to which the data is to be written.
  174. The type must support the <em>SyncWriteStream</em> concept.
  175. @param sr The serializer to use.
  176. @param ec Set to indicate what error occurred, if any.
  177. @return The number of bytes written to the stream.
  178. @note The implementation will call @ref serializer::split with
  179. the value `true` on the serializer passed in.
  180. @see serializer
  181. */
  182. template<
  183. class SyncWriteStream,
  184. bool isRequest, class Body, class Fields>
  185. std::size_t
  186. write_header(
  187. SyncWriteStream& stream,
  188. serializer<isRequest, Body, Fields>& sr,
  189. error_code& ec);
  190. /** Write a header to a stream asynchronously using a serializer.
  191. This function is used to write a header to a stream asynchronously
  192. using a caller-provided HTTP/1 serializer. The function call always
  193. returns immediately. The asynchronous operation will continue until
  194. one of the following conditions is true:
  195. @li The function @ref serializer::is_header_done returns `true`
  196. @li An error occurs.
  197. This operation is implemented in terms of zero or more calls to the stream's
  198. `async_write_some` function, and is known as a <em>composed operation</em>.
  199. The program must ensure that the stream performs no other writes
  200. until this operation completes.
  201. @param stream The stream to which the data is to be written.
  202. The type must support the <em>AsyncWriteStream</em> concept.
  203. @param sr The serializer to use.
  204. The object must remain valid at least until the
  205. handler is called; ownership is not transferred.
  206. @param handler The completion handler to invoke when the operation
  207. completes. The implementation takes ownership of the handler by
  208. performing a decay-copy. The equivalent function signature of
  209. the handler must be:
  210. @code
  211. void handler(
  212. error_code const& error, // result of operation
  213. std::size_t bytes_transferred // the number of bytes written to the stream
  214. );
  215. @endcode
  216. Regardless of whether the asynchronous operation completes
  217. immediately or not, the handler will not be invoked from within
  218. this function. Invocation of the handler will be performed in a
  219. manner equivalent to using `net::post`.
  220. @note The implementation will call @ref serializer::split with
  221. the value `true` on the serializer passed in.
  222. @see serializer
  223. */
  224. template<
  225. class AsyncWriteStream,
  226. bool isRequest, class Body, class Fields,
  227. class WriteHandler>
  228. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  229. async_write_header(
  230. AsyncWriteStream& stream,
  231. serializer<isRequest, Body, Fields>& sr,
  232. WriteHandler&& handler);
  233. //------------------------------------------------------------------------------
  234. /** Write a complete message to a stream using a serializer.
  235. This function is used to write a complete message to a stream using
  236. a caller-provided HTTP/1 serializer. The call will block until one
  237. of the following conditions is true:
  238. @li The function @ref serializer::is_done returns `true`
  239. @li An error occurs.
  240. This operation is implemented in terms of one or more calls
  241. to the stream's `write_some` function.
  242. @param stream The stream to which the data is to be written.
  243. The type must support the <em>SyncWriteStream</em> concept.
  244. @param sr The serializer to use.
  245. @return The number of bytes written to the stream.
  246. @throws system_error Thrown on failure.
  247. @see serializer
  248. */
  249. template<
  250. class SyncWriteStream,
  251. bool isRequest, class Body, class Fields>
  252. std::size_t
  253. write(
  254. SyncWriteStream& stream,
  255. serializer<isRequest, Body, Fields>& sr);
  256. /** Write a complete message to a stream using a serializer.
  257. This function is used to write a complete message to a stream using
  258. a caller-provided HTTP/1 serializer. The call will block until one
  259. of the following conditions is true:
  260. @li The function @ref serializer::is_done returns `true`
  261. @li An error occurs.
  262. This operation is implemented in terms of one or more calls
  263. to the stream's `write_some` function.
  264. @param stream The stream to which the data is to be written.
  265. The type must support the <em>SyncWriteStream</em> concept.
  266. @param sr The serializer to use.
  267. @param ec Set to the error, if any occurred.
  268. @return The number of bytes written to the stream.
  269. @see serializer
  270. */
  271. template<
  272. class SyncWriteStream,
  273. bool isRequest, class Body, class Fields>
  274. std::size_t
  275. write(
  276. SyncWriteStream& stream,
  277. serializer<isRequest, Body, Fields>& sr,
  278. error_code& ec);
  279. /** Write a complete message to a stream asynchronously using a serializer.
  280. This function is used to write a complete message to a stream
  281. asynchronously using a caller-provided HTTP/1 serializer. The
  282. function call always returns immediately. The asynchronous
  283. operation will continue until one of the following conditions is true:
  284. @li The function @ref serializer::is_done returns `true`
  285. @li An error occurs.
  286. This operation is implemented in terms of zero or more calls to the stream's
  287. `async_write_some` function, and is known as a <em>composed operation</em>.
  288. The program must ensure that the stream performs no other writes
  289. until this operation completes.
  290. @param stream The stream to which the data is to be written.
  291. The type must support the <em>AsyncWriteStream</em> concept.
  292. @param sr The serializer to use.
  293. The object must remain valid at least until the
  294. handler is called; ownership is not transferred.
  295. @param handler The completion handler to invoke when the operation
  296. completes. The implementation takes ownership of the handler by
  297. performing a decay-copy. The equivalent function signature of
  298. the handler must be:
  299. @code
  300. void handler(
  301. error_code const& error, // result of operation
  302. std::size_t bytes_transferred // the number of bytes written to the stream
  303. );
  304. @endcode
  305. Regardless of whether the asynchronous operation completes
  306. immediately or not, the handler will not be invoked from within
  307. this function. Invocation of the handler will be performed in a
  308. manner equivalent to using `net::post`.
  309. @see serializer
  310. */
  311. template<
  312. class AsyncWriteStream,
  313. bool isRequest, class Body, class Fields,
  314. class WriteHandler>
  315. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  316. async_write(
  317. AsyncWriteStream& stream,
  318. serializer<isRequest, Body, Fields>& sr,
  319. WriteHandler&& handler);
  320. //------------------------------------------------------------------------------
  321. /** Write a complete message to a stream.
  322. This function is used to write a complete message to a stream using
  323. HTTP/1. The call will block until one of the following conditions is true:
  324. @li The entire message is written.
  325. @li An error occurs.
  326. This operation is implemented in terms of one or more calls to the stream's
  327. `write_some` function. The algorithm will use a temporary @ref serializer
  328. with an empty chunk decorator to produce buffers.
  329. @note This function only participates in overload resolution
  330. if @ref is_mutable_body_writer for <em>Body</em> returns `true`.
  331. @param stream The stream to which the data is to be written.
  332. The type must support the <em>SyncWriteStream</em> concept.
  333. @param msg The message to write.
  334. @return The number of bytes written to the stream.
  335. @throws system_error Thrown on failure.
  336. @see message
  337. */
  338. template<
  339. class SyncWriteStream,
  340. bool isRequest, class Body, class Fields>
  341. #if BOOST_BEAST_DOXYGEN
  342. std::size_t
  343. #else
  344. typename std::enable_if<
  345. is_mutable_body_writer<Body>::value,
  346. std::size_t>::type
  347. #endif
  348. write(
  349. SyncWriteStream& stream,
  350. message<isRequest, Body, Fields>& msg);
  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 `false`.
  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> const& 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 `true`.
  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. @param ec Set to the error, if any occurred.
  395. @return The number of bytes written to the stream.
  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>& msg,
  411. error_code& ec);
  412. /** Write a complete message to a stream.
  413. This function is used to write a complete message to a stream using
  414. HTTP/1. The call will block until one of the following conditions is true:
  415. @li The entire message is written.
  416. @li An error occurs.
  417. This operation is implemented in terms of one or more calls to the stream's
  418. `write_some` function. The algorithm will use a temporary @ref serializer
  419. with an empty chunk decorator to produce buffers.
  420. @note This function only participates in overload resolution
  421. if @ref is_mutable_body_writer for <em>Body</em> returns `false`.
  422. @param stream The stream to which the data is to be written.
  423. The type must support the <em>SyncWriteStream</em> concept.
  424. @param msg The message to write.
  425. @param ec Set to the error, if any occurred.
  426. @return The number of bytes written to the stream.
  427. @see message
  428. */
  429. template<
  430. class SyncWriteStream,
  431. bool isRequest, class Body, class Fields>
  432. #if BOOST_BEAST_DOXYGEN
  433. std::size_t
  434. #else
  435. typename std::enable_if<
  436. ! is_mutable_body_writer<Body>::value,
  437. std::size_t>::type
  438. #endif
  439. write(
  440. SyncWriteStream& stream,
  441. message<isRequest, Body, Fields> const& msg,
  442. error_code& ec);
  443. /** Write a complete message to a stream asynchronously.
  444. This function is used to write a complete message to a stream asynchronously
  445. using HTTP/1. The function call always returns immediately. The asynchronous
  446. operation will continue until one of the following conditions is true:
  447. @li The entire message is written.
  448. @li An error occurs.
  449. This operation is implemented in terms of zero or more calls to the stream's
  450. `async_write_some` function, and is known as a <em>composed operation</em>.
  451. The program must ensure that the stream performs no other writes
  452. until this operation completes. The algorithm will use a temporary
  453. @ref serializer with an empty chunk decorator to produce buffers.
  454. @note This function only participates in overload resolution
  455. if @ref is_mutable_body_writer for <em>Body</em> returns `true`.
  456. @param stream The stream to which the data is to be written.
  457. The type must support the <em>AsyncWriteStream</em> concept.
  458. @param msg The message to write.
  459. The object must remain valid at least until the
  460. handler is called; ownership is not transferred.
  461. @param handler The completion handler to invoke when the operation
  462. completes. The implementation takes ownership of the handler by
  463. performing a decay-copy. The equivalent function signature of
  464. the handler must be:
  465. @code
  466. void handler(
  467. error_code const& error, // result of operation
  468. std::size_t bytes_transferred // the number of bytes written to the stream
  469. );
  470. @endcode
  471. Regardless of whether the asynchronous operation completes
  472. immediately or not, the handler will not be invoked from within
  473. this function. Invocation of the handler will be performed in a
  474. manner equivalent to using `net::post`.
  475. @see message
  476. */
  477. template<
  478. class AsyncWriteStream,
  479. bool isRequest, class Body, class Fields,
  480. class WriteHandler>
  481. #if BOOST_BEAST_DOXYGEN
  482. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  483. #else
  484. typename std::enable_if<
  485. is_mutable_body_writer<Body>::value,
  486. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)>::type
  487. #endif
  488. async_write(
  489. AsyncWriteStream& stream,
  490. message<isRequest, Body, Fields>& msg,
  491. WriteHandler&& handler);
  492. /** Write a complete message to a stream asynchronously.
  493. This function is used to write a complete message to a stream asynchronously
  494. using HTTP/1. The function call always returns immediately. The asynchronous
  495. operation will continue until one of the following conditions is true:
  496. @li The entire message is written.
  497. @li An error occurs.
  498. This operation is implemented in terms of zero or more calls to the stream's
  499. `async_write_some` function, and is known as a <em>composed operation</em>.
  500. The program must ensure that the stream performs no other writes
  501. until this operation completes. The algorithm will use a temporary
  502. @ref serializer with an empty chunk decorator to produce buffers.
  503. @note This function only participates in overload resolution
  504. if @ref is_mutable_body_writer for <em>Body</em> returns `false`.
  505. @param stream The stream to which the data is to be written.
  506. The type must support the <em>AsyncWriteStream</em> concept.
  507. @param msg The message to write.
  508. The object must remain valid at least until the
  509. handler is called; ownership is not transferred.
  510. @param handler The completion handler to invoke when the operation
  511. completes. The implementation takes ownership of the handler by
  512. performing a decay-copy. The equivalent function signature of
  513. the handler must be:
  514. @code
  515. void handler(
  516. error_code const& error, // result of operation
  517. std::size_t bytes_transferred // the number of bytes written to the stream
  518. );
  519. @endcode
  520. Regardless of whether the asynchronous operation completes
  521. immediately or not, the handler will not be invoked from within
  522. this function. Invocation of the handler will be performed in a
  523. manner equivalent to using `net::post`.
  524. @see message
  525. */
  526. template<
  527. class AsyncWriteStream,
  528. bool isRequest, class Body, class Fields,
  529. class WriteHandler>
  530. #if BOOST_BEAST_DOXYGEN
  531. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  532. #else
  533. typename std::enable_if<
  534. ! is_mutable_body_writer<Body>::value,
  535. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)>::type
  536. #endif
  537. async_write(
  538. AsyncWriteStream& stream,
  539. message<isRequest, Body, Fields> const& msg,
  540. WriteHandler&& handler);
  541. //------------------------------------------------------------------------------
  542. /** Serialize an HTTP/1 header to a `std::ostream`.
  543. The function converts the header to its HTTP/1 serialized
  544. representation and stores the result in the output stream.
  545. @param os The output stream to write to.
  546. @param msg The message fields to write.
  547. */
  548. template<bool isRequest, class Fields>
  549. std::ostream&
  550. operator<<(std::ostream& os,
  551. header<isRequest, Fields> const& msg);
  552. /** Serialize an HTTP/1 message to a `std::ostream`.
  553. The function converts the message to its HTTP/1 serialized
  554. representation and stores the result in the output stream.
  555. The implementation will automatically perform chunk encoding if
  556. the contents of the message indicate that chunk encoding is required.
  557. @param os The output stream to write to.
  558. @param msg The message to write.
  559. */
  560. template<bool isRequest, class Body, class Fields>
  561. std::ostream&
  562. operator<<(std::ostream& os,
  563. message<isRequest, Body, Fields> const& msg);
  564. } // http
  565. } // beast
  566. } // boost
  567. #include <boost/beast/http/impl/write.hpp>
  568. #endif