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