| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2017-07-24 09:42:36 -07:00
										 |  |  | // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
 | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | //
 | 
					
						
							|  |  |  | // Distributed under the Boost Software License, Version 1.0. (See accompanying
 | 
					
						
							|  |  |  | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2017-07-20 13:40:34 -07:00
										 |  |  | // Official repository: https://github.com/boostorg/beast
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-20 13:40:34 -07:00
										 |  |  | #ifndef BOOST_BEAST_HTTP_BUFFER_BODY_HPP
 | 
					
						
							|  |  |  | #define BOOST_BEAST_HTTP_BUFFER_BODY_HPP
 | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-10 07:49:03 -07:00
										 |  |  | #include <boost/beast/core/detail/config.hpp>
 | 
					
						
							| 
									
										
										
										
											2017-07-20 13:40:34 -07:00
										 |  |  | #include <boost/beast/http/error.hpp>
 | 
					
						
							|  |  |  | #include <boost/beast/http/message.hpp>
 | 
					
						
							|  |  |  | #include <boost/beast/http/type_traits.hpp>
 | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | #include <boost/optional.hpp>
 | 
					
						
							|  |  |  | #include <type_traits>
 | 
					
						
							|  |  |  | #include <utility>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-20 13:40:34 -07:00
										 |  |  | namespace boost { | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | namespace beast { | 
					
						
							|  |  |  | namespace http { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-08 17:11:49 -07:00
										 |  |  | /** A @b Body using a caller provided buffer
 | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-08 17:11:49 -07:00
										 |  |  |     Messages using this body type may be serialized and parsed. | 
					
						
							|  |  |  |     To use this class, the caller must initialize the members | 
					
						
							|  |  |  |     of @ref buffer_body::value_type to appropriate values before | 
					
						
							|  |  |  |     each call to read or write during a stream operation. | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | */ | 
					
						
							|  |  |  | struct buffer_body | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  |     /// The type of the body member when used in a message.
 | 
					
						
							|  |  |  |     struct value_type | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /** A pointer to a contiguous area of memory of @ref size octets, else `nullptr`.
 | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-05 05:49:22 -07:00
										 |  |  |             @par When Serializing | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             If this is `nullptr` and `more` is `true`, the error | 
					
						
							|  |  |  |             @ref error::need_buffer will be returned from @ref serializer::get | 
					
						
							|  |  |  |             Otherwise, the serializer will use the memory pointed to | 
					
						
							|  |  |  |             by `data` having `size` octets of valid storage as the | 
					
						
							|  |  |  |             next buffer representing the body. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @par When Parsing | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             If this is `nullptr`, the error @ref error::need_buffer | 
					
						
							|  |  |  |             will be returned from @ref parser::put. Otherwise, the | 
					
						
							|  |  |  |             parser will store body octets into the memory pointed to | 
					
						
							|  |  |  |             by `data` having `size` octets of valid storage. After | 
					
						
							|  |  |  |             octets are stored, the `data` and `size` members are | 
					
						
							|  |  |  |             adjusted: `data` is incremented to point to the next | 
					
						
							|  |  |  |             octet after the data written, while `size` is decremented | 
					
						
							|  |  |  |             to reflect the remaining space at the memory location | 
					
						
							|  |  |  |             pointed to by `data`. | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  |         */ | 
					
						
							| 
									
										
										
										
											2017-06-05 05:49:22 -07:00
										 |  |  |         void* data = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** The number of octets in the buffer pointed to by @ref data.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @par When Serializing | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             If `data` is `nullptr` during serialization, this value | 
					
						
							|  |  |  |             is ignored. Otherwise, it represents the number of valid | 
					
						
							|  |  |  |             body octets pointed to by `data`. | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-05 05:49:22 -07:00
										 |  |  |             @par When Parsing | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-05 05:49:22 -07:00
										 |  |  |             The value of this field will be decremented during parsing | 
					
						
							|  |  |  |             to indicate the number of remaining free octets in the | 
					
						
							|  |  |  |             buffer pointed to by `data`. When it reaches zero, the | 
					
						
							|  |  |  |             parser will return @ref error::need_buffer, indicating to | 
					
						
							|  |  |  |             the caller that the values of `data` and `size` should be | 
					
						
							|  |  |  |             updated to point to a new memory buffer. | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  |         */ | 
					
						
							| 
									
										
										
										
											2017-06-05 05:49:22 -07:00
										 |  |  |         std::size_t size = 0; | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-05 05:49:22 -07:00
										 |  |  |         /** `true` if this is not the last buffer.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @par When Serializing | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             If this is `true` and `data` is `nullptr`, the error | 
					
						
							|  |  |  |             @ref error::need_buffer will be returned from @ref serializer::get | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @par When Parsing | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             This field is not used during parsing. | 
					
						
							|  |  |  |         */ | 
					
						
							|  |  |  |         bool more = true; | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 17:08:52 -07:00
										 |  |  |     /** The algorithm for parsing the body
 | 
					
						
							| 
									
										
										
										
											2017-07-08 17:11:49 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Meets the requirements of @b BodyReader. | 
					
						
							|  |  |  |     */ | 
					
						
							| 
									
										
										
										
											2017-07-20 13:40:34 -07:00
										 |  |  | #if BOOST_BEAST_DOXYGEN
 | 
					
						
							| 
									
										
										
										
											2018-11-11 21:53:13 -08:00
										 |  |  |     using reader = __implementation_defined__; | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-05-28 09:05:29 -07:00
										 |  |  |     class reader | 
					
						
							| 
									
										
										
										
											2017-10-30 17:08:52 -07:00
										 |  |  |     { | 
					
						
							|  |  |  |         value_type& body_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         template<bool isRequest, class Fields> | 
					
						
							|  |  |  |         explicit | 
					
						
							| 
									
										
										
										
											2017-11-13 23:34:14 +01:00
										 |  |  |         reader(header<isRequest, Fields>&, value_type& b) | 
					
						
							|  |  |  |             : body_(b) | 
					
						
							| 
									
										
										
										
											2017-10-30 17:08:52 -07:00
										 |  |  |         { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void | 
					
						
							|  |  |  |         init(boost::optional<std::uint64_t> const&, error_code& ec) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-01-20 09:50:43 -08:00
										 |  |  |             ec = {}; | 
					
						
							| 
									
										
										
										
											2017-10-30 17:08:52 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         template<class ConstBufferSequence> | 
					
						
							|  |  |  |         std::size_t | 
					
						
							|  |  |  |         put(ConstBufferSequence const& buffers, | 
					
						
							|  |  |  |             error_code& ec) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if(! body_.data) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 ec = error::need_buffer; | 
					
						
							|  |  |  |                 return 0; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             auto const bytes_transferred = | 
					
						
							| 
									
										
										
										
											2019-02-02 10:53:54 -08:00
										 |  |  |                 net::buffer_copy(net::buffer( | 
					
						
							| 
									
										
										
										
											2017-10-30 17:08:52 -07:00
										 |  |  |                     body_.data, body_.size), buffers); | 
					
						
							| 
									
										
										
										
											2018-07-15 08:57:08 -07:00
										 |  |  |             body_.data = static_cast<char*>( | 
					
						
							| 
									
										
										
										
											2017-10-30 17:08:52 -07:00
										 |  |  |                 body_.data) + bytes_transferred; | 
					
						
							|  |  |  |             body_.size -= bytes_transferred; | 
					
						
							| 
									
										
										
										
											2019-02-02 10:53:54 -08:00
										 |  |  |             using net::buffer_size; | 
					
						
							| 
									
										
										
										
											2017-10-30 17:08:52 -07:00
										 |  |  |             if(bytes_transferred == buffer_size(buffers)) | 
					
						
							| 
									
										
										
										
											2019-01-20 09:50:43 -08:00
										 |  |  |                 ec = {}; | 
					
						
							| 
									
										
										
										
											2017-10-30 17:08:52 -07:00
										 |  |  |             else | 
					
						
							|  |  |  |                 ec = error::need_buffer; | 
					
						
							|  |  |  |             return bytes_transferred; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void | 
					
						
							|  |  |  |         finish(error_code& ec) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-01-20 09:50:43 -08:00
										 |  |  |             ec = {}; | 
					
						
							| 
									
										
										
										
											2017-10-30 17:08:52 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** The algorithm for serializing the body
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Meets the requirements of @b BodyWriter. | 
					
						
							|  |  |  |     */ | 
					
						
							|  |  |  | #if BOOST_BEAST_DOXYGEN
 | 
					
						
							| 
									
										
										
										
											2018-11-11 21:53:13 -08:00
										 |  |  |     using writer = __implementation_defined__; | 
					
						
							| 
									
										
										
										
											2017-10-30 17:08:52 -07:00
										 |  |  | #else
 | 
					
						
							|  |  |  |     class writer | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  |     { | 
					
						
							|  |  |  |         bool toggle_ = false; | 
					
						
							|  |  |  |         value_type const& body_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  |         using const_buffers_type = | 
					
						
							| 
									
										
										
										
											2018-11-30 14:58:38 -08:00
										 |  |  |             net::const_buffer; | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         template<bool isRequest, class Fields> | 
					
						
							|  |  |  |         explicit | 
					
						
							| 
									
										
										
										
											2017-11-13 23:34:14 +01:00
										 |  |  |         writer(header<isRequest, Fields> const&, value_type const& b) | 
					
						
							|  |  |  |             : body_(b) | 
					
						
							| 
									
										
										
										
											2017-07-07 20:08:52 -07:00
										 |  |  |         { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void | 
					
						
							|  |  |  |         init(error_code& ec) | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-01-20 09:50:43 -08:00
										 |  |  |             ec = {}; | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  |         boost::optional< | 
					
						
							|  |  |  |             std::pair<const_buffers_type, bool>> | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  |         get(error_code& ec) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if(toggle_) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  |                 if(body_.more) | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  |                 { | 
					
						
							|  |  |  |                     toggle_ = false; | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  |                     ec = error::need_buffer; | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2017-06-13 07:08:52 -07:00
										 |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2019-01-20 09:50:43 -08:00
										 |  |  |                     ec = {}; | 
					
						
							| 
									
										
										
										
											2017-06-13 07:08:52 -07:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  |                 return boost::none; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  |             if(body_.data) | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2019-01-20 09:50:43 -08:00
										 |  |  |                 ec = {}; | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  |                 toggle_ = true; | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  |                 return {{const_buffers_type{ | 
					
						
							|  |  |  |                     body_.data, body_.size}, body_.more}}; | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  |             if(body_.more) | 
					
						
							|  |  |  |                 ec = error::need_buffer; | 
					
						
							| 
									
										
										
										
											2017-06-13 07:08:52 -07:00
										 |  |  |             else | 
					
						
							| 
									
										
										
										
											2019-01-20 09:50:43 -08:00
										 |  |  |                 ec = {}; | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  |             return boost::none; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-20 13:40:34 -07:00
										 |  |  | #if ! BOOST_BEAST_DOXYGEN
 | 
					
						
							| 
									
										
										
										
											2017-06-05 05:49:22 -07:00
										 |  |  | // operator<< is not supported for buffer_body
 | 
					
						
							|  |  |  | template<bool isRequest, class Fields> | 
					
						
							| 
									
										
										
										
											2017-05-30 16:16:20 -07:00
										 |  |  | std::ostream& | 
					
						
							| 
									
										
										
										
											2017-05-31 08:01:55 -07:00
										 |  |  | operator<<(std::ostream& os, message<isRequest, | 
					
						
							|  |  |  |     buffer_body, Fields> const& msg) = delete; | 
					
						
							| 
									
										
										
										
											2017-05-30 16:16:20 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | } // http
 | 
					
						
							|  |  |  | } // beast
 | 
					
						
							| 
									
										
										
										
											2017-07-20 13:40:34 -07:00
										 |  |  | } // boost
 | 
					
						
							| 
									
										
										
										
											2017-05-08 12:41:45 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif
 |