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 10 #ifndef BOOST_BEAST_HTTP_SPAN_BODY_HPP 11 #define BOOST_BEAST_HTTP_SPAN_BODY_HPP 12 13 #include <boost/beast/core/detail/config.hpp> 14 #include <boost/beast/core/buffer_traits.hpp> 15 #include <boost/beast/core/span.hpp> 16 #include <boost/beast/http/error.hpp> 17 #include <boost/beast/http/message.hpp> 18 #include <boost/optional.hpp> 19 20 namespace boost { 21 namespace beast { 22 namespace http { 23 24 /** A <em>Body</em> using @ref span 25 26 This body uses @ref span as a memory-based container for 27 holding message payloads. The container represents a 28 non-owning reference to a contiguous area of memory. 29 Messages using this body type may be serialized and 30 parsed. 31 32 Unlike @ref buffer_body, only one buffer may be provided 33 during a parse or serialize operation. 34 */ 35 template<class T> 36 struct span_body 37 { 38 private: 39 static_assert( 40 std::is_trivial<T>::value && 41 std::is_standard_layout<T>::value, 42 "POD requirements not met"); 43 44 public: 45 /** The type of container used for the body 46 47 This determines the type of @ref message::body 48 when this body type is used with a message container. 49 */ 50 using value_type = span<T>; 51 52 /** Returns the payload size of the body 53 54 When this body is used with @ref message::prepare_payload, 55 the Content-Length will be set to the payload size, and 56 any chunked Transfer-Encoding will be removed. 57 */ 58 static 59 std::uint64_t sizeboost::beast::http::span_body60 size(value_type const& body) 61 { 62 return body.size(); 63 } 64 65 /** The algorithm for parsing the body 66 67 Meets the requirements of <em>BodyReader</em>. 68 */ 69 #if BOOST_BEAST_DOXYGEN 70 using reader = __implementation_defined__; 71 #else 72 class reader 73 { 74 value_type& body_; 75 76 public: 77 template<bool isRequest, class Fields> 78 explicit reader(header<isRequest,Fields> &,value_type & b)79 reader(header<isRequest, Fields>&, value_type& b) 80 : body_(b) 81 { 82 } 83 84 void init(boost::optional<std::uint64_t> const & length,error_code & ec)85 init(boost::optional< 86 std::uint64_t> const& length, error_code& ec) 87 { 88 if(length && *length > body_.size()) 89 { 90 ec = error::buffer_overflow; 91 return; 92 } 93 ec = {}; 94 } 95 96 template<class ConstBufferSequence> 97 std::size_t put(ConstBufferSequence const & buffers,error_code & ec)98 put(ConstBufferSequence const& buffers, 99 error_code& ec) 100 { 101 auto const n = buffer_bytes(buffers); 102 auto const len = body_.size(); 103 if(n > len) 104 { 105 ec = error::buffer_overflow; 106 return 0; 107 } 108 ec = {}; 109 net::buffer_copy(net::buffer( 110 body_.data(), n), buffers); 111 body_ = value_type{ 112 body_.data() + n, body_.size() - n}; 113 return n; 114 } 115 116 void finish(error_code & ec)117 finish(error_code& ec) 118 { 119 ec = {}; 120 } 121 }; 122 #endif 123 124 /** The algorithm for serializing the body 125 126 Meets the requirements of <em>BodyWriter</em>. 127 */ 128 #if BOOST_BEAST_DOXYGEN 129 using writer = __implementation_defined__; 130 #else 131 class writer 132 { 133 value_type const& body_; 134 135 public: 136 using const_buffers_type = 137 net::const_buffer; 138 139 template<bool isRequest, class Fields> 140 explicit writer(header<isRequest,Fields> const &,value_type const & b)141 writer(header<isRequest, Fields> const&, value_type const& b) 142 : body_(b) 143 { 144 } 145 146 void init(error_code & ec)147 init(error_code& ec) 148 { 149 ec = {}; 150 } 151 152 boost::optional<std::pair<const_buffers_type, bool>> get(error_code & ec)153 get(error_code& ec) 154 { 155 ec = {}; 156 return {{ 157 { body_.data(), 158 body_.size() * sizeof(typename 159 value_type::value_type)}, 160 false}}; 161 } 162 }; 163 #endif 164 }; 165 166 } // http 167 } // beast 168 } // boost 169 170 #endif 171