forked from boostorg/beast
HTTP improvements:
* Increased code coverage * New Body concepts: is_Body is_ReadableBody is_WritableBody
This commit is contained in:
@@ -41,7 +41,10 @@
|
|||||||
</simplelist>
|
</simplelist>
|
||||||
<bridgehead renderas="sect3">Type Traits</bridgehead>
|
<bridgehead renderas="sect3">Type Traits</bridgehead>
|
||||||
<simplelist type="vert" columns="1">
|
<simplelist type="vert" columns="1">
|
||||||
|
<member><link linkend="beast.ref.http__is_Body">is_Body</link></member>
|
||||||
<member><link linkend="beast.ref.http__is_Parser">is_Parser</link></member>
|
<member><link linkend="beast.ref.http__is_Parser">is_Parser</link></member>
|
||||||
|
<member><link linkend="beast.ref.http__is_ReadableBody">is_ReadableBody</link></member>
|
||||||
|
<member><link linkend="beast.ref.http__is_WritableBody">is_WritableBody</link></member>
|
||||||
</simplelist>
|
</simplelist>
|
||||||
</entry>
|
</entry>
|
||||||
<entry valign="top">
|
<entry valign="top">
|
||||||
|
@@ -22,7 +22,7 @@ In this table:
|
|||||||
[`boost::string_ref`]
|
[`boost::string_ref`]
|
||||||
[
|
[
|
||||||
This function returns a value implicitly convertible to
|
This function returns a value implicitly convertible to
|
||||||
`boost::string_ref` containing the case-insensitve field
|
`boost::string_ref` containing the case-insensitive field
|
||||||
name, without leading or trailing white space.
|
name, without leading or trailing white space.
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@@ -38,7 +38,7 @@ In this table:
|
|||||||
an error occurs, the end of the buffer is reached, or a complete
|
an error occurs, the end of the buffer is reached, or a complete
|
||||||
HTTP/1 message has been parsed. If an error occurs, `ec` is set
|
HTTP/1 message has been parsed. If an error occurs, `ec` is set
|
||||||
to the error code and parsing stops. This function returns the
|
to the error code and parsing stops. This function returns the
|
||||||
number of bytes consumed in the input buffer.
|
number of bytes consumed from the input buffer.
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
|
156
include/beast/http/concepts.hpp
Normal file
156
include/beast/http/concepts.hpp
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2013-2016 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_TYPE_CHECK_HPP
|
||||||
|
#define BEAST_HTTP_TYPE_CHECK_HPP
|
||||||
|
|
||||||
|
#include <beast/core/error.hpp>
|
||||||
|
#include <boost/asio/buffer.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
namespace http {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class has_value_type
|
||||||
|
{
|
||||||
|
template<class U, class R =
|
||||||
|
typename U::value_type>
|
||||||
|
static std::true_type check(int);
|
||||||
|
template<class>
|
||||||
|
static std::false_type check(...);
|
||||||
|
using type = decltype(check<T>(0));
|
||||||
|
public:
|
||||||
|
static bool constexpr value = type::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, bool B = has_value_type<T>::value>
|
||||||
|
struct extract_value_type
|
||||||
|
{
|
||||||
|
using type = void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct extract_value_type<T, true>
|
||||||
|
{
|
||||||
|
using type = typename T::value_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class has_reader
|
||||||
|
{
|
||||||
|
template<class U, class R =
|
||||||
|
typename U::reader>
|
||||||
|
static std::true_type check(int);
|
||||||
|
template<class>
|
||||||
|
static std::false_type check(...);
|
||||||
|
public:
|
||||||
|
using type = decltype(check<T>(0));
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class has_writer
|
||||||
|
{
|
||||||
|
template<class U, class R =
|
||||||
|
typename U::writer>
|
||||||
|
static std::true_type check(int);
|
||||||
|
template<class>
|
||||||
|
static std::false_type check(...);
|
||||||
|
public:
|
||||||
|
using type = decltype(check<T>(0));
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct is_Body
|
||||||
|
{
|
||||||
|
using type = std::integral_constant<bool,
|
||||||
|
has_value_type<T>::value &&
|
||||||
|
std::is_default_constructible<
|
||||||
|
typename extract_value_type<T>::type>::value
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class is_Parser
|
||||||
|
{
|
||||||
|
template<class U, class R =
|
||||||
|
std::is_convertible<decltype(
|
||||||
|
std::declval<U>().complete()),
|
||||||
|
bool>>
|
||||||
|
static R check1(int);
|
||||||
|
template<class>
|
||||||
|
static std::false_type check1(...);
|
||||||
|
using type1 = decltype(check1<T>(0));
|
||||||
|
|
||||||
|
template<class U, class R =
|
||||||
|
std::is_convertible<decltype(
|
||||||
|
std::declval<U>().write(
|
||||||
|
std::declval<boost::asio::const_buffer const&>(),
|
||||||
|
std::declval<error_code&>())),
|
||||||
|
std::size_t>>
|
||||||
|
static R check2(int);
|
||||||
|
template<class>
|
||||||
|
static std::false_type check2(...);
|
||||||
|
using type2 = decltype(check2<T>(0));
|
||||||
|
|
||||||
|
template<class U, class R = decltype(
|
||||||
|
std::declval<U>().write_eof(std::declval<error_code&>()),
|
||||||
|
std::true_type{})>
|
||||||
|
static R check3(int);
|
||||||
|
template<class>
|
||||||
|
static std::false_type check3(...);
|
||||||
|
using type3 = decltype(check3<T>(0));
|
||||||
|
|
||||||
|
public:
|
||||||
|
using type = std::integral_constant<bool,
|
||||||
|
type1::value &&
|
||||||
|
type2::value &&
|
||||||
|
type3::value
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // detail
|
||||||
|
|
||||||
|
/// Determine if `T` meets the requirements of `Body`.
|
||||||
|
template<class T>
|
||||||
|
#if GENERATING_DOCS
|
||||||
|
struct is_Body : std::integral_constant<bool, ...>{};
|
||||||
|
#else
|
||||||
|
using is_Body = typename detail::is_Body<T>::type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Determine if `T` meets the requirements of `ReadableBody`.
|
||||||
|
template<class T>
|
||||||
|
#if GENERATING_DOCS
|
||||||
|
struct is_ReadableBody : std::integral_constant<bool, ...>{};
|
||||||
|
#else
|
||||||
|
using is_ReadableBody = typename detail::has_reader<T>::type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Determine if `T` meets the requirements of `WritableBody`.
|
||||||
|
template<class T>
|
||||||
|
#if GENERATING_DOCS
|
||||||
|
struct is_WritableBody : std::integral_constant<bool, ...>{};
|
||||||
|
#else
|
||||||
|
using is_WritableBody = typename detail::has_writer<T>::type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Determine if `T` meets the requirements of `Parser`.
|
||||||
|
template<class T>
|
||||||
|
#if GENERATING_DOCS
|
||||||
|
struct is_Parser : std::integral_constant<bool, ...>{};
|
||||||
|
#else
|
||||||
|
using is_Parser = typename detail::is_Parser<T>::type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // http
|
||||||
|
} // beast
|
||||||
|
|
||||||
|
#endif
|
@@ -34,20 +34,6 @@ struct empty_body
|
|||||||
private:
|
private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct reader
|
|
||||||
{
|
|
||||||
template<bool isRequest, class Headers>
|
|
||||||
explicit
|
|
||||||
reader(message<isRequest, empty_body, Headers>&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
write(void const*, std::size_t, error_code&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct writer
|
struct writer
|
||||||
{
|
{
|
||||||
writer(writer const&) = delete;
|
writer(writer const&) = delete;
|
||||||
|
@@ -8,8 +8,8 @@
|
|||||||
#ifndef BEAST_HTTP_IMPL_READ_IPP_HPP
|
#ifndef BEAST_HTTP_IMPL_READ_IPP_HPP
|
||||||
#define BEAST_HTTP_IMPL_READ_IPP_HPP
|
#define BEAST_HTTP_IMPL_READ_IPP_HPP
|
||||||
|
|
||||||
|
#include <beast/http/concepts.hpp>
|
||||||
#include <beast/http/parser_v1.hpp>
|
#include <beast/http/parser_v1.hpp>
|
||||||
#include <beast/http/type_check.hpp>
|
|
||||||
#include <beast/core/bind_handler.hpp>
|
#include <beast/core/bind_handler.hpp>
|
||||||
#include <beast/core/handler_alloc.hpp>
|
#include <beast/core/handler_alloc.hpp>
|
||||||
#include <beast/core/stream_concepts.hpp>
|
#include <beast/core/stream_concepts.hpp>
|
||||||
@@ -323,6 +323,12 @@ void
|
|||||||
parse(SyncReadStream& stream,
|
parse(SyncReadStream& stream,
|
||||||
Streambuf& streambuf, Parser& parser)
|
Streambuf& streambuf, Parser& parser)
|
||||||
{
|
{
|
||||||
|
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||||
|
"SyncReadStream requirements not met");
|
||||||
|
static_assert(is_Streambuf<Streambuf>::value,
|
||||||
|
"Streambuf requirements not met");
|
||||||
|
static_assert(is_Parser<Parser>::value,
|
||||||
|
"Parser requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
parse(stream, streambuf, parser, ec);
|
parse(stream, streambuf, parser, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
@@ -403,6 +409,8 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
|||||||
"SyncReadStream requirements not met");
|
"SyncReadStream requirements not met");
|
||||||
static_assert(is_Streambuf<Streambuf>::value,
|
static_assert(is_Streambuf<Streambuf>::value,
|
||||||
"Streambuf requirements not met");
|
"Streambuf requirements not met");
|
||||||
|
static_assert(is_ReadableBody<Body>::value,
|
||||||
|
"ReadableBody requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
read(stream, streambuf, msg, ec);
|
read(stream, streambuf, msg, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
@@ -420,6 +428,8 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
|||||||
"SyncReadStream requirements not met");
|
"SyncReadStream requirements not met");
|
||||||
static_assert(is_Streambuf<Streambuf>::value,
|
static_assert(is_Streambuf<Streambuf>::value,
|
||||||
"Streambuf requirements not met");
|
"Streambuf requirements not met");
|
||||||
|
static_assert(is_ReadableBody<Body>::value,
|
||||||
|
"ReadableBody requirements not met");
|
||||||
parser_v1<isRequest, Body, Headers> p;
|
parser_v1<isRequest, Body, Headers> p;
|
||||||
parse(stream, streambuf, p, ec);
|
parse(stream, streambuf, p, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
@@ -441,6 +451,8 @@ async_read(AsyncReadStream& stream, Streambuf& streambuf,
|
|||||||
"AsyncReadStream requirements not met");
|
"AsyncReadStream requirements not met");
|
||||||
static_assert(is_Streambuf<Streambuf>::value,
|
static_assert(is_Streambuf<Streambuf>::value,
|
||||||
"Streambuf requirements not met");
|
"Streambuf requirements not met");
|
||||||
|
static_assert(is_ReadableBody<Body>::value,
|
||||||
|
"ReadableBody requirements not met");
|
||||||
beast::async_completion<ReadHandler,
|
beast::async_completion<ReadHandler,
|
||||||
void(error_code)> completion(handler);
|
void(error_code)> completion(handler);
|
||||||
detail::read_op<AsyncReadStream, Streambuf,
|
detail::read_op<AsyncReadStream, Streambuf,
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#ifndef BEAST_HTTP_IMPL_WRITE_IPP
|
#ifndef BEAST_HTTP_IMPL_WRITE_IPP
|
||||||
#define BEAST_HTTP_IMPL_WRITE_IPP
|
#define BEAST_HTTP_IMPL_WRITE_IPP
|
||||||
|
|
||||||
|
#include <beast/http/concepts.hpp>
|
||||||
#include <beast/http/resume_context.hpp>
|
#include <beast/http/resume_context.hpp>
|
||||||
#include <beast/http/detail/chunk_encode.hpp>
|
#include <beast/http/detail/chunk_encode.hpp>
|
||||||
#include <beast/http/detail/has_content_length.hpp>
|
#include <beast/http/detail/has_content_length.hpp>
|
||||||
@@ -448,6 +449,8 @@ write(SyncWriteStream& stream,
|
|||||||
{
|
{
|
||||||
static_assert(is_SyncWriteStream<SyncWriteStream>::value,
|
static_assert(is_SyncWriteStream<SyncWriteStream>::value,
|
||||||
"SyncWriteStream requirements not met");
|
"SyncWriteStream requirements not met");
|
||||||
|
static_assert(is_WritableBody<Body>::value,
|
||||||
|
"WritableBody requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
write(stream, msg, ec);
|
write(stream, msg, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
@@ -463,6 +466,8 @@ write(SyncWriteStream& stream,
|
|||||||
{
|
{
|
||||||
static_assert(is_SyncWriteStream<SyncWriteStream>::value,
|
static_assert(is_SyncWriteStream<SyncWriteStream>::value,
|
||||||
"SyncWriteStream requirements not met");
|
"SyncWriteStream requirements not met");
|
||||||
|
static_assert(is_WritableBody<Body>::value,
|
||||||
|
"WritableBody requirements not met");
|
||||||
detail::write_preparation<isRequest, Body, Headers> wp(msg);
|
detail::write_preparation<isRequest, Body, Headers> wp(msg);
|
||||||
wp.init(ec);
|
wp.init(ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
@@ -546,6 +551,8 @@ async_write(AsyncWriteStream& stream,
|
|||||||
static_assert(
|
static_assert(
|
||||||
is_AsyncWriteStream<AsyncWriteStream>::value,
|
is_AsyncWriteStream<AsyncWriteStream>::value,
|
||||||
"AsyncWriteStream requirements not met");
|
"AsyncWriteStream requirements not met");
|
||||||
|
static_assert(is_WritableBody<Body>::value,
|
||||||
|
"WritableBody requirements not met");
|
||||||
beast::async_completion<WriteHandler,
|
beast::async_completion<WriteHandler,
|
||||||
void(error_code)> completion(handler);
|
void(error_code)> completion(handler);
|
||||||
detail::write_op<AsyncWriteStream, decltype(completion.handler),
|
detail::write_op<AsyncWriteStream, decltype(completion.handler),
|
||||||
@@ -607,6 +614,8 @@ std::ostream&
|
|||||||
operator<<(std::ostream& os,
|
operator<<(std::ostream& os,
|
||||||
message_v1<isRequest, Body, Headers> const& msg)
|
message_v1<isRequest, Body, Headers> const& msg)
|
||||||
{
|
{
|
||||||
|
static_assert(is_WritableBody<Body>::value,
|
||||||
|
"WritableBody requirements not met");
|
||||||
detail::ostream_SyncStream oss(os);
|
detail::ostream_SyncStream oss(os);
|
||||||
error_code ec;
|
error_code ec;
|
||||||
write(oss, msg, ec);
|
write(oss, msg, ec);
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#define BEAST_HTTP_PARSER_V1_HPP
|
#define BEAST_HTTP_PARSER_V1_HPP
|
||||||
|
|
||||||
#include <beast/http/basic_parser_v1.hpp>
|
#include <beast/http/basic_parser_v1.hpp>
|
||||||
|
#include <beast/http/concepts.hpp>
|
||||||
#include <beast/http/message_v1.hpp>
|
#include <beast/http/message_v1.hpp>
|
||||||
#include <beast/core/error.hpp>
|
#include <beast/core/error.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@@ -54,6 +55,9 @@ public:
|
|||||||
message_v1<isRequest, Body, Headers>;
|
message_v1<isRequest, Body, Headers>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static_assert(is_ReadableBody<Body>::value,
|
||||||
|
"ReadableBody requirements not met");
|
||||||
|
|
||||||
std::string field_;
|
std::string field_;
|
||||||
std::string value_;
|
std::string value_;
|
||||||
message_type m_;
|
message_type m_;
|
||||||
|
@@ -1,60 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2013-2016 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_TYPE_CHECK_HPP
|
|
||||||
#define BEAST_HTTP_TYPE_CHECK_HPP
|
|
||||||
|
|
||||||
#include <beast/core/error.hpp>
|
|
||||||
#include <boost/asio/buffer.hpp>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace beast {
|
|
||||||
namespace http {
|
|
||||||
|
|
||||||
/// Determine if `T` meets the requirements of `Parser`.
|
|
||||||
template<class T>
|
|
||||||
class is_Parser
|
|
||||||
{
|
|
||||||
template<class U, class R =
|
|
||||||
std::is_convertible<decltype(
|
|
||||||
std::declval<U>().complete()),
|
|
||||||
bool>>
|
|
||||||
static R check1(int);
|
|
||||||
template<class>
|
|
||||||
static std::false_type check1(...);
|
|
||||||
using type1 = decltype(check1<T>(0));
|
|
||||||
|
|
||||||
template<class U, class R =
|
|
||||||
std::is_convertible<decltype(
|
|
||||||
std::declval<U>().write(
|
|
||||||
std::declval<boost::asio::const_buffer const&>(),
|
|
||||||
std::declval<error_code&>())),
|
|
||||||
std::size_t>>
|
|
||||||
static R check2(int);
|
|
||||||
template<class>
|
|
||||||
static std::false_type check2(...);
|
|
||||||
using type2 = decltype(check2<T>(0));
|
|
||||||
|
|
||||||
template<class U, class R = decltype(
|
|
||||||
std::declval<U>().write_eof(std::declval<error_code&>()),
|
|
||||||
std::true_type{})>
|
|
||||||
static R check3(int);
|
|
||||||
template<class>
|
|
||||||
static std::false_type check3(...);
|
|
||||||
using type3 = decltype(check3<T>(0));
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// `true` if `T` meets the requirements.
|
|
||||||
static bool const value =
|
|
||||||
type1::value && type2::value && type3::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // http
|
|
||||||
} // beast
|
|
||||||
|
|
||||||
#endif
|
|
@@ -33,7 +33,7 @@ class stream<NextLayer>::accept_op
|
|||||||
struct data
|
struct data
|
||||||
{
|
{
|
||||||
stream<NextLayer>& ws;
|
stream<NextLayer>& ws;
|
||||||
http::request_v1<http::empty_body> req;
|
http::request_v1<http::string_body> req;
|
||||||
Handler h;
|
Handler h;
|
||||||
bool cont;
|
bool cont;
|
||||||
int state = 0;
|
int state = 0;
|
||||||
|
@@ -253,7 +253,7 @@ accept(ConstBufferSequence const& buffers, error_code& ec)
|
|||||||
stream_.buffer().commit(buffer_copy(
|
stream_.buffer().commit(buffer_copy(
|
||||||
stream_.buffer().prepare(
|
stream_.buffer().prepare(
|
||||||
buffer_size(buffers)), buffers));
|
buffer_size(buffers)), buffers));
|
||||||
http::request_v1<http::empty_body> m;
|
http::request_v1<http::string_body> m;
|
||||||
http::read(next_layer(), stream_.buffer(), m, ec);
|
http::read(next_layer(), stream_.buffer(), m, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
return;
|
return;
|
||||||
|
@@ -44,6 +44,7 @@ unit-test http-tests :
|
|||||||
http/basic_headers.cpp
|
http/basic_headers.cpp
|
||||||
http/basic_parser_v1.cpp
|
http/basic_parser_v1.cpp
|
||||||
http/body_type.cpp
|
http/body_type.cpp
|
||||||
|
http/concepts.cpp
|
||||||
http/empty_body.cpp
|
http/empty_body.cpp
|
||||||
http/headers.cpp
|
http/headers.cpp
|
||||||
http/message.cpp
|
http/message.cpp
|
||||||
@@ -58,7 +59,6 @@ unit-test http-tests :
|
|||||||
http/status.cpp
|
http/status.cpp
|
||||||
http/streambuf_body.cpp
|
http/streambuf_body.cpp
|
||||||
http/string_body.cpp
|
http/string_body.cpp
|
||||||
http/type_check.cpp
|
|
||||||
http/write.cpp
|
http/write.cpp
|
||||||
http/detail/chunk_encode.cpp
|
http/detail/chunk_encode.cpp
|
||||||
;
|
;
|
||||||
|
@@ -66,6 +66,14 @@ public:
|
|||||||
expect(buffer_size(buffer_cat(
|
expect(buffer_size(buffer_cat(
|
||||||
sb1.data(), sb2.data())) == 12);
|
sb1.data(), sb2.data())) == 12);
|
||||||
}
|
}
|
||||||
|
for(auto it = bs.begin(); it != bs.end(); ++it)
|
||||||
|
{
|
||||||
|
decltype(bs)::const_iterator copy;
|
||||||
|
copy = it;
|
||||||
|
expect(copy == it);
|
||||||
|
copy = copy;
|
||||||
|
expect(copy == it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void testIterators()
|
void testIterators()
|
||||||
|
@@ -10,6 +10,7 @@ add_executable (http-tests
|
|||||||
basic_headers.cpp
|
basic_headers.cpp
|
||||||
basic_parser_v1.cpp
|
basic_parser_v1.cpp
|
||||||
body_type.cpp
|
body_type.cpp
|
||||||
|
concepts.cpp
|
||||||
empty_body.cpp
|
empty_body.cpp
|
||||||
headers.cpp
|
headers.cpp
|
||||||
message.cpp
|
message.cpp
|
||||||
@@ -24,7 +25,6 @@ add_executable (http-tests
|
|||||||
status.cpp
|
status.cpp
|
||||||
streambuf_body.cpp
|
streambuf_body.cpp
|
||||||
string_body.cpp
|
string_body.cpp
|
||||||
type_check.cpp
|
|
||||||
write.cpp
|
write.cpp
|
||||||
detail/chunk_encode.cpp
|
detail/chunk_encode.cpp
|
||||||
)
|
)
|
||||||
|
@@ -6,4 +6,4 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Test that header file is self-contained.
|
// Test that header file is self-contained.
|
||||||
#include <beast/http/type_check.hpp>
|
#include <beast/http/concepts.hpp>
|
@@ -12,8 +12,10 @@
|
|||||||
#include <beast/http/headers.hpp>
|
#include <beast/http/headers.hpp>
|
||||||
#include <beast/http/parser_v1.hpp>
|
#include <beast/http/parser_v1.hpp>
|
||||||
#include <beast/http/read.hpp>
|
#include <beast/http/read.hpp>
|
||||||
|
#include <beast/http/write.hpp>
|
||||||
#include <beast/test/string_stream.hpp>
|
#include <beast/test/string_stream.hpp>
|
||||||
#include <beast/unit_test/suite.hpp>
|
#include <beast/unit_test/suite.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
namespace http {
|
namespace http {
|
||||||
@@ -25,16 +27,18 @@ class streambuf_body_test : public beast::unit_test::suite
|
|||||||
public:
|
public:
|
||||||
void run() override
|
void run() override
|
||||||
{
|
{
|
||||||
test::string_stream ss(ios_,
|
std::string const s =
|
||||||
"HTTP/1.1 200 OK\r\n"
|
"HTTP/1.1 200 OK\r\n"
|
||||||
"Server: test\r\n"
|
"Server: test\r\n"
|
||||||
"Content-Length: 3\r\n"
|
"Content-Length: 3\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"xyz");
|
"xyz";
|
||||||
|
test::string_stream ss(ios_, s);
|
||||||
parser_v1<false, streambuf_body, headers> p;
|
parser_v1<false, streambuf_body, headers> p;
|
||||||
streambuf sb;
|
streambuf sb;
|
||||||
parse(ss, sb, p);
|
parse(ss, sb, p);
|
||||||
expect(to_string(p.get().body.data()) == "xyz");
|
expect(to_string(p.get().body.data()) == "xyz");
|
||||||
|
expect(boost::lexical_cast<std::string>(p.get()) == s);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user