basic_dynamic_body.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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_BASIC_DYNAMIC_BODY_HPP
  10. #define BOOST_BEAST_HTTP_BASIC_DYNAMIC_BODY_HPP
  11. #include <boost/beast/http/basic_dynamic_body_fwd.hpp>
  12. #include <boost/beast/core/buffer_traits.hpp>
  13. #include <boost/beast/core/detail/buffer.hpp>
  14. #include <boost/beast/core/detail/clamp.hpp>
  15. #include <boost/beast/core/detail/config.hpp>
  16. #include <boost/beast/http/error.hpp>
  17. #include <boost/beast/http/message.hpp>
  18. #include <boost/optional.hpp>
  19. #include <algorithm>
  20. #include <cstdint>
  21. #include <utility>
  22. namespace boost {
  23. namespace beast {
  24. namespace http {
  25. /** A <em>Body</em> using a <em>DynamicBuffer</em>
  26. This body uses a <em>DynamicBuffer</em> as a memory-based container
  27. for holding message payloads. Messages using this body type
  28. may be serialized and parsed.
  29. */
  30. template<class DynamicBuffer>
  31. struct basic_dynamic_body
  32. {
  33. static_assert(
  34. net::is_dynamic_buffer<DynamicBuffer>::value,
  35. "DynamicBuffer type requirements not met");
  36. /** The type of container used for the body
  37. This determines the type of @ref message::body
  38. when this body type is used with a message container.
  39. */
  40. using value_type = DynamicBuffer;
  41. /** Returns the payload size of the body
  42. When this body is used with @ref message::prepare_payload,
  43. the Content-Length will be set to the payload size, and
  44. any chunked Transfer-Encoding will be removed.
  45. */
  46. static
  47. std::uint64_t
  48. size(value_type const& v)
  49. {
  50. return v.size();
  51. }
  52. /** The algorithm for parsing the body
  53. Meets the requirements of <em>BodyReader</em>.
  54. */
  55. #if BOOST_BEAST_DOXYGEN
  56. using reader = __implementation_defined__;
  57. #else
  58. class reader
  59. {
  60. value_type& body_;
  61. public:
  62. template<bool isRequest, class Fields>
  63. explicit
  64. reader(header<isRequest, Fields>&, value_type& b)
  65. : body_(b)
  66. {
  67. }
  68. void
  69. init(boost::optional<
  70. std::uint64_t> const&, error_code& ec)
  71. {
  72. ec = {};
  73. }
  74. template<class ConstBufferSequence>
  75. std::size_t
  76. put(ConstBufferSequence const& buffers,
  77. error_code& ec)
  78. {
  79. auto const n = buffer_bytes(buffers);
  80. if(beast::detail::sum_exceeds(body_.size(), n, body_.max_size()))
  81. {
  82. BOOST_BEAST_ASSIGN_EC(ec, error::buffer_overflow);
  83. return 0;
  84. }
  85. auto const mb =
  86. beast::detail::dynamic_buffer_prepare(
  87. body_, (std::min)(n,
  88. body_.max_size() - body_.size()),
  89. ec, error::buffer_overflow);
  90. if(ec)
  91. return 0;
  92. auto const bytes_transferred =
  93. net::buffer_copy(*mb, buffers);
  94. body_.commit(bytes_transferred);
  95. return bytes_transferred;
  96. }
  97. void
  98. finish(error_code& ec)
  99. {
  100. ec = {};
  101. }
  102. };
  103. #endif
  104. /** The algorithm for serializing the body
  105. Meets the requirements of <em>BodyWriter</em>.
  106. */
  107. #if BOOST_BEAST_DOXYGEN
  108. using writer = __implementation_defined__;
  109. #else
  110. class writer
  111. {
  112. DynamicBuffer const& body_;
  113. public:
  114. using const_buffers_type =
  115. typename DynamicBuffer::const_buffers_type;
  116. template<bool isRequest, class Fields>
  117. explicit
  118. writer(header<isRequest, Fields> const&, value_type const& b)
  119. : body_(b)
  120. {
  121. }
  122. void
  123. init(error_code& ec)
  124. {
  125. ec = {};
  126. }
  127. boost::optional<std::pair<const_buffers_type, bool>>
  128. get(error_code& ec)
  129. {
  130. ec = {};
  131. return {{body_.data(), false}};
  132. }
  133. };
  134. #endif
  135. };
  136. } // http
  137. } // beast
  138. } // boost
  139. #endif