diff --git a/CHANGELOG.md b/CHANGELOG.md index b0252aa9..9855e021 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ Version 80: * Javadoc tidying +* Add basic_dynamic_body.hpp -------------------------------------------------------------------------------- diff --git a/include/beast/http.hpp b/include/beast/http.hpp index 4f13500e..8ed2ec8c 100644 --- a/include/beast/http.hpp +++ b/include/beast/http.hpp @@ -10,6 +10,7 @@ #include +#include #include #include #include diff --git a/include/beast/http/basic_dynamic_body.hpp b/include/beast/http/basic_dynamic_body.hpp new file mode 100644 index 00000000..acc049dc --- /dev/null +++ b/include/beast/http/basic_dynamic_body.hpp @@ -0,0 +1,164 @@ +// +// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// 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) +// + +#ifndef BEAST_HTTP_BASIC_DYNAMIC_BODY_HPP +#define BEAST_HTTP_BASIC_DYNAMIC_BODY_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace beast { +namespace http { + +/** A @b Body using a @b DynamicBuffer + + This body uses a @b DynamicBuffer as a memory-based container + for holding message payloads. Messages using this body type + may be serialized and parsed. +*/ +template +struct basic_dynamic_body +{ + static_assert(is_dynamic_buffer::value, + "DynamicBuffer requirements not met"); + + /** The type of container used for the body + + This determines the type of @ref message::body + when this body type is used with a message container. + */ + using value_type = DynamicBuffer; + + /** Returns the payload size of the body + + When this body is used with @ref message::prepare_payload, + the Content-Length will be set to the payload size, and + any chunked Transfer-Encoding will be removed. + */ + static + std::uint64_t + size(value_type const& v) + { + return v.size(); + } + + /** The algorithm for serializing the body + + Meets the requirements of @b BodyReader. + */ +#if BEAST_DOXYGEN + using reader = implementation_defined; +#else + class reader + { + DynamicBuffer const& body_; + + public: + using const_buffers_type = + typename DynamicBuffer::const_buffers_type; + + template + explicit + reader(message const& m) + : body_(m.body) + { + } + + void + init(error_code& ec) + { + ec.assign(0, ec.category()); + } + + boost::optional> + get(error_code& ec) + { + ec.assign(0, ec.category()); + return {{body_.data(), false}}; + } + }; +#endif + + /** The algorithm for parsing the body + + Meets the requirements of @b BodyReader. + */ +#if BEAST_DOXYGEN + using writer = implementation_defined; +#else + class writer + { + value_type& body_; + + public: + template + explicit + writer(message& msg) + : body_(msg.body) + { + } + + void + init(boost::optional< + std::uint64_t> const&, error_code& ec) + { + ec.assign(0, ec.category()); + } + + template + std::size_t + put(ConstBufferSequence const& buffers, + error_code& ec) + { + using boost::asio::buffer_copy; + using boost::asio::buffer_size; + auto const n = buffer_size(buffers); + if(body_.size() > body_.max_size() - n) + { + ec = error::buffer_overflow; + return 0; + } + boost::optional b; + try + { + b.emplace(body_.prepare((std::min)(n, + body_.max_size() - body_.size()))); + } + catch(std::length_error const&) + { + ec = error::buffer_overflow; + return 0; + } + ec.assign(0, ec.category()); + auto const bytes_transferred = + buffer_copy(*b, buffers); + body_.commit(bytes_transferred); + return bytes_transferred; + } + + void + finish(error_code& ec) + { + ec.assign(0, ec.category()); + } + }; +#endif +}; + +} // http +} // beast + +#endif diff --git a/include/beast/http/dynamic_body.hpp b/include/beast/http/dynamic_body.hpp index c5142084..892b2699 100644 --- a/include/beast/http/dynamic_body.hpp +++ b/include/beast/http/dynamic_body.hpp @@ -8,154 +8,12 @@ #ifndef BEAST_HTTP_DYNAMIC_BODY_HPP #define BEAST_HTTP_DYNAMIC_BODY_HPP -#include #include -#include -#include -#include -#include -#include -#include +#include namespace beast { namespace http { -/** A @b Body using a @b DynamicBuffer - - This body uses a @b DynamicBuffer as a memory-based container - for holding message payloads. Messages using this body type - may be serialized and parsed. -*/ -template -struct basic_dynamic_body -{ - static_assert(is_dynamic_buffer::value, - "DynamicBuffer requirements not met"); - - /** The type of container used for the body - - This determines the type of @ref message::body - when this body type is used with a message container. - */ - using value_type = DynamicBuffer; - - /** Returns the payload size of the body - - When this body is used with @ref message::prepare_payload, - the Content-Length will be set to the payload size, and - any chunked Transfer-Encoding will be removed. - */ - static - std::uint64_t - size(value_type const& v) - { - return v.size(); - } - - /** The algorithm for serializing the body - - Meets the requirements of @b BodyReader. - */ -#if BEAST_DOXYGEN - using reader = implementation_defined; -#else - class reader - { - DynamicBuffer const& body_; - - public: - using const_buffers_type = - typename DynamicBuffer::const_buffers_type; - - template - explicit - reader(message const& m) - : body_(m.body) - { - } - - void - init(error_code& ec) - { - ec.assign(0, ec.category()); - } - - boost::optional> - get(error_code& ec) - { - ec.assign(0, ec.category()); - return {{body_.data(), false}}; - } - }; -#endif - - /** The algorithm for parsing the body - - Meets the requirements of @b BodyReader. - */ -#if BEAST_DOXYGEN - using writer = implementation_defined; -#else - class writer - { - value_type& body_; - - public: - template - explicit - writer(message& msg) - : body_(msg.body) - { - } - - void - init(boost::optional const&, error_code& ec) - { - ec.assign(0, ec.category()); - } - - template - std::size_t - put(ConstBufferSequence const& buffers, - error_code& ec) - { - using boost::asio::buffer_copy; - using boost::asio::buffer_size; - auto const n = buffer_size(buffers); - if(body_.size() > body_.max_size() - n) - { - ec = error::buffer_overflow; - return 0; - } - boost::optional b; - try - { - b.emplace(body_.prepare((std::min)(n, - body_.max_size() - body_.size()))); - } - catch(std::length_error const&) - { - ec = error::buffer_overflow; - return 0; - } - ec.assign(0, ec.category()); - auto const bytes_transferred = - buffer_copy(*b, buffers); - body_.commit(bytes_transferred); - return bytes_transferred; - } - - void - finish(error_code& ec) - { - ec.assign(0, ec.category()); - } - }; -#endif -}; - /** A dynamic message body represented by a @ref multi_buffer Meets the requirements of @b Body. diff --git a/test/http/CMakeLists.txt b/test/http/CMakeLists.txt index a609f6b1..b74e0eb6 100644 --- a/test/http/CMakeLists.txt +++ b/test/http/CMakeLists.txt @@ -13,6 +13,7 @@ add_executable (http-tests message_fuzz.hpp test_parser.hpp ../../extras/beast/unit_test/main.cpp + basic_dynamic_body.cpp basic_parser.cpp buffer_body.cpp doc_examples.cpp diff --git a/test/http/Jamfile b/test/http/Jamfile index aca16300..2145d832 100644 --- a/test/http/Jamfile +++ b/test/http/Jamfile @@ -7,6 +7,7 @@ unit-test http-tests : ../../extras/beast/unit_test/main.cpp + basic_dynamic_body.cpp basic_parser.cpp buffer_body.cpp doc_examples.cpp diff --git a/test/http/basic_dynamic_body.cpp b/test/http/basic_dynamic_body.cpp new file mode 100644 index 00000000..c9249ea0 --- /dev/null +++ b/test/http/basic_dynamic_body.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// 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) +// + +// Test that header file is self-contained. +#include