basic_dynamic_body.hpp 4.0 KB

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