span, string, vector bodies are public

This commit is contained in:
Vinnie Falco
2017-07-08 20:37:12 -07:00
parent 1f41c124c0
commit f34d4f7204
8 changed files with 1 additions and 365 deletions

View File

@@ -7,6 +7,7 @@ HTTP:
* Tidy up basic_string_body * Tidy up basic_string_body
* Add vector_body * Add vector_body
* span, string, vector bodies are public
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -152,11 +152,9 @@ the example described in the Core Foundations document section.
This code is reused between some of the examples. The header files This code is reused between some of the examples. The header files
stand alone can be directly included in your projects. stand alone can be directly included in your projects.
* [repo_file example/common/const_body.hpp]
* [repo_file example/common/detect_ssl.hpp] * [repo_file example/common/detect_ssl.hpp]
* [repo_file example/common/helpers.hpp] * [repo_file example/common/helpers.hpp]
* [repo_file example/common/mime_types.hpp] * [repo_file example/common/mime_types.hpp]
* [repo_file example/common/mutable_body.hpp]
* [repo_file example/common/rfc7231.hpp] * [repo_file example/common/rfc7231.hpp]
* [repo_file example/common/ssl_stream.hpp] * [repo_file example/common/ssl_stream.hpp]
* [repo_file example/common/write_msg.hpp] * [repo_file example/common/write_msg.hpp]

View File

@@ -1,94 +0,0 @@
//
// Copyright (c) 2017 Mike Gresens (mike dot gresens 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_EXAMPLE_COMMON_CONST_BODY_HPP
#define BEAST_EXAMPLE_COMMON_CONST_BODY_HPP
#include <beast/http/message.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/optional.hpp>
namespace detail {
template <typename T>
using is_const_character = std::integral_constant<bool,
std::is_integral<T>::value &&
sizeof(T) == 1
>;
template<class T, class = void>
struct is_const_container : std::false_type { };
template<class T>
struct is_const_container<T, beast::detail::void_t<
decltype( std::declval<typename T::size_type&>() = std::declval<T&>().size() ),
decltype( std::declval<const typename T::value_type*&>() = std::declval<T&>().data() )
> > : std::true_type { };
}
/** An HTTP message body represented by a constant character container.
Meets the requirements of @b Body.
*/
template <typename ConstContainer>
struct const_body
{
static_assert(
detail::is_const_character<typename ConstContainer::value_type>::value &&
detail::is_const_container<ConstContainer>::value,
"ConstContainer requirements not met");
/// The type of the body member when used in a message.
using value_type = ConstContainer;
/// Returns the content length of the body in a message.
static
std::uint64_t
size(value_type const& v)
{
return v.size();
}
#if BEAST_DOXYGEN
/// The algorithm to obtain buffers representing the body
using reader = implementation_defined;
#else
class reader
{
value_type const& body_;
public:
using const_buffers_type =
boost::asio::const_buffers_1;
template<bool isRequest, class Fields>
explicit
reader(beast::http::message<isRequest,
const_body, Fields> const& msg)
: body_(msg.body)
{
}
void
init(beast::error_code& ec)
{
ec.assign(0, ec.category());
}
boost::optional<std::pair<const_buffers_type, bool>>
get(beast::error_code& ec)
{
ec.assign(0, ec.category());
return {{const_buffers_type{
body_.data(), body_.size()}, false}};
}
};
#endif
};
#endif

View File

@@ -1,172 +0,0 @@
//
// Copyright (c) 2017 Mike Gresens (mike dot gresens 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_EXAMPLE_COMMON_MUTABLE_BODY_HPP
#define BEAST_EXAMPLE_COMMON_MUTABLE_BODY_HPP
#include <beast/http/message.hpp>
#include <beast/http/error.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/optional.hpp>
namespace detail {
template <typename T>
using is_mutable_character = std::integral_constant<bool,
std::is_integral<T>::value &&
sizeof(T) == 1
>;
template<class T, class = void>
struct is_mutable_container : std::false_type { };
template< class T >
struct is_mutable_container<T, beast::detail::void_t<
decltype( std::declval<typename T::size_type&>() = std::declval<T&>().size() ),
decltype( std::declval<const typename T::value_type*&>() = std::declval<T&>().data() ),
decltype( std::declval<T&>().reserve(0) ),
decltype( std::declval<T&>().resize(0) )
> > : std::true_type { };
}
/** An HTTP message body represented by a mutable character container.
Meets the requirements of @b Body.
*/
template <typename MutableContainer>
struct mutable_body
{
static_assert(
detail::is_mutable_character<typename MutableContainer::value_type>::value &&
detail::is_mutable_container<MutableContainer>::value,
"MutableContainer requirements not met");
/// The type of the body member when used in a message.
using value_type = MutableContainer;
/// Returns the content length of the body in a message.
static
std::uint64_t
size(value_type const& v)
{
return v.size();
}
#if BEAST_DOXYGEN
/// The algorithm to obtain buffers representing the body
using reader = implementation_defined;
#else
class reader
{
value_type const& body_;
public:
using const_buffers_type =
boost::asio::const_buffers_1;
template<bool isRequest, class Fields>
explicit
reader(beast::http::message<isRequest,
mutable_body, Fields> const& msg)
: body_(msg.body)
{
}
void
init(beast::error_code& ec)
{
ec.assign(0, ec.category());
}
boost::optional<std::pair<const_buffers_type, bool>>
get(beast::error_code& ec)
{
ec.assign(0, ec.category());
return {{const_buffers_type{
body_.data(), body_.size()}, false}};
}
};
#endif
#if BEAST_DOXYGEN
/// The algorithm used store buffers in this body
using writer = implementation_defined;
#else
class writer
{
value_type& body_;
public:
template<bool isRequest, class Fields>
explicit
writer(beast::http::message<
isRequest, mutable_body, Fields>& m)
: body_(m.body)
{
}
void
init(boost::optional<
std::uint64_t> const& length, beast::error_code& ec)
{
if(length)
{
if(*length > (std::numeric_limits<
std::size_t>::max)())
{
ec = beast::http::error::buffer_overflow;
return;
}
try
{
body_.reserve(static_cast<
std::size_t>(*length));
}
catch(std::exception const&)
{
ec = beast::http::error::buffer_overflow;
return;
}
}
ec.assign(0, ec.category());
}
template<class ConstBufferSequence>
std::size_t
put(ConstBufferSequence const& buffers,
beast::error_code& ec)
{
using boost::asio::buffer_size;
using boost::asio::buffer_copy;
auto const n = buffer_size(buffers);
auto const len = body_.size();
try
{
body_.resize(len + n);
}
catch(std::exception const&)
{
ec = beast::http::error::buffer_overflow;
return 0;
}
ec.assign(0, ec.category());
return buffer_copy(boost::asio::buffer(
&body_[0] + len, n), buffers);
}
void
finish(beast::error_code& ec)
{
ec.assign(0, ec.category());
}
};
#endif
};
#endif

View File

@@ -9,8 +9,6 @@ add_executable (common-test
${BEAST_INCLUDES} ${BEAST_INCLUDES}
${COMMON_INCLUDES} ${COMMON_INCLUDES}
detect_ssl.cpp detect_ssl.cpp
const_body.cpp
mutable_body.cpp
mime_types.cpp mime_types.cpp
rfc7231.cpp rfc7231.cpp
ssl_stream.cpp ssl_stream.cpp

View File

@@ -1,10 +0,0 @@
//
// Copyright (c) 2017 Mike Gresens (mike dot gresens 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 "../../example/common/const_body.hpp"

View File

@@ -1,10 +0,0 @@
//
// Copyright (c) 2017 Mike Gresens (mike dot gresens 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 "../../example/common/mutable_body.hpp"

View File

@@ -6,8 +6,6 @@
// //
#include "example/doc/http_examples.hpp" #include "example/doc/http_examples.hpp"
#include "example/common/const_body.hpp"
#include "example/common/mutable_body.hpp"
#include <beast/core/read_size.hpp> #include <beast/core/read_size.hpp>
#include <beast/core/detail/clamp.hpp> #include <beast/core/detail/clamp.hpp>
@@ -24,30 +22,6 @@
namespace beast { namespace beast {
namespace http { namespace http {
struct Thing {
char value;
};
BOOST_STATIC_ASSERT(::detail::is_const_character<char>::value == true);
BOOST_STATIC_ASSERT(::detail::is_const_character<unsigned char>::value == true);
BOOST_STATIC_ASSERT(::detail::is_const_character<char32_t>::value == false);
BOOST_STATIC_ASSERT(::detail::is_const_character<Thing>::value == false);
BOOST_STATIC_ASSERT(::detail::is_const_container<std::string>::value == true);
BOOST_STATIC_ASSERT(::detail::is_const_container<string_view>::value == true);
BOOST_STATIC_ASSERT(::detail::is_const_container<std::vector<char>>::value == true);
BOOST_STATIC_ASSERT(::detail::is_const_container<std::list<char>>::value == false);
BOOST_STATIC_ASSERT(::detail::is_mutable_character<char>::value == true);
BOOST_STATIC_ASSERT(::detail::is_mutable_character<unsigned char>::value == true);
BOOST_STATIC_ASSERT(::detail::is_mutable_character<char32_t>::value == false);
BOOST_STATIC_ASSERT(::detail::is_mutable_character<Thing>::value == false);
BOOST_STATIC_ASSERT(::detail::is_mutable_container<std::string>::value == true);
BOOST_STATIC_ASSERT(::detail::is_mutable_container<string_view>::value == false);
BOOST_STATIC_ASSERT(::detail::is_mutable_container<std::vector<char>>::value == true);
BOOST_STATIC_ASSERT(::detail::is_mutable_container<std::list<char>>::value == false);
class doc_examples_test class doc_examples_test
: public beast::unit_test::suite : public beast::unit_test::suite
, public beast::test::enable_yield_to , public beast::test::enable_yield_to
@@ -285,54 +259,6 @@ public:
BEAST_EXPECT(h.body == "Hello, world!"); BEAST_EXPECT(h.body == "Hello, world!");
} }
void
doConstAndMutableBody()
{
test::pipe c{ios_};
// people using std::array need to be careful
// because the entire array will be written out
// no matter how big the string is!
std::array<char, 15> const body {{"Hello, world!\n"}};
{
request<const_body<std::array<char, 15>>> req;
req.version = 11;
req.method(verb::put);
req.target("/");
req.body = body;
req.prepare_payload();
write(c.client, req);
}
{
flat_buffer b;
request_parser<empty_body> p0;
read_header(c.server, b, p0);
BEAST_EXPECTS(p0.get().method() == verb::put,
p0.get().method_string());
{
request_parser<mutable_body<std::vector<char>>> p{std::move(p0)};
p.get().body = std::vector<char>(body.begin(), body.end());
read(c.server, b, p);
}
}
{
response<const_body<std::array<char, 15>>> res;
res.version = 11;
res.result(status::ok);
res.insert(field::server, "test");
res.body = body;
res.prepare_payload();
write(c.server, res);
}
{
flat_buffer b;
response<mutable_body<std::vector<char>>> res;
read(c.client, b, res);
BEAST_EXPECTS(res.body == std::vector<char>(body.begin(), body.end()),
std::string(body.begin(), body.end()));
}
}
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
void void
@@ -367,7 +293,6 @@ public:
doCustomParser(); doCustomParser();
doHEAD(); doHEAD();
doDeferredBody(); doDeferredBody();
doConstAndMutableBody();
doIncrementalRead(); doIncrementalRead();
} }
}; };