Update to Beast 1.0.0-b34:

Merge commit 'd8dea963fa5dc26b4be699ce6d4bf699a429ca92' into develop
This commit is contained in:
Vinnie Falco
2017-04-20 13:40:52 -07:00
79 changed files with 501 additions and 315 deletions

View File

@@ -8,6 +8,7 @@ add_executable (lib-tests
${BEAST_INCLUDES}
${EXTRAS_INCLUDES}
../extras/beast/unit_test/main.cpp
config.cpp
core.cpp
http.cpp
version.cpp
@@ -16,6 +17,8 @@ add_executable (lib-tests
)
if (NOT WIN32)
target_link_libraries(lib-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(lib-tests ${Boost_LIBRARIES})
endif()

View File

@@ -7,6 +7,7 @@
import os ;
compile config.cpp : : ;
compile core.cpp : : ;
compile http.cpp : : ;
compile version.cpp : : ;
@@ -58,7 +59,6 @@ unit-test http-tests :
http/parser_v1.cpp
http/read.cpp
http/reason.cpp
http/resume_context.cpp
http/rfc7230.cpp
http/streambuf_body.cpp
http/string_body.cpp

View File

@@ -6,4 +6,4 @@
//
// Test that header file is self-contained.
#include <beast/http/resume_context.hpp>
#include <beast/config.hpp>

View File

@@ -39,4 +39,6 @@ add_executable (core-tests
if (NOT WIN32)
target_link_libraries(core-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(core-tests ${Boost_LIBRARIES})
endif()

View File

@@ -23,7 +23,6 @@ add_executable (http-tests
parser_v1.cpp
read.cpp
reason.cpp
resume_context.cpp
rfc7230.cpp
streambuf_body.cpp
string_body.cpp
@@ -33,6 +32,8 @@ add_executable (http-tests
if (NOT WIN32)
target_link_libraries(http-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(http-tests ${Boost_LIBRARIES})
endif()
add_executable (bench-tests
@@ -45,5 +46,7 @@ add_executable (bench-tests
)
if (NOT WIN32)
target_link_libraries(bench-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(bench-tests ${Boost_LIBRARIES})
endif()

View File

@@ -17,6 +17,7 @@
#include <beast/test/yield_to.hpp>
#include <beast/unit_test/suite.hpp>
#include <boost/asio/spawn.hpp>
#include <atomic>
namespace beast {
namespace http {
@@ -374,6 +375,55 @@ public:
}
}
// Ensure completion handlers are not leaked
struct handler
{
static std::atomic<std::size_t>&
count() { static std::atomic<std::size_t> n; return n; }
handler() { ++count(); }
~handler() { --count(); }
handler(handler const&) { ++count(); }
void operator()(error_code const&) const {}
};
void
testIoService()
{
{
// Make sure handlers are not destroyed
// after calling io_service::stop
boost::asio::io_service ios;
test::string_istream is{ios,
"GET / HTTP/1.1\r\n\r\n"};
BEAST_EXPECT(handler::count() == 0);
streambuf sb;
message<true, streambuf_body, fields> m;
async_read(is, sb, m, handler{});
BEAST_EXPECT(handler::count() > 0);
ios.stop();
BEAST_EXPECT(handler::count() > 0);
ios.reset();
BEAST_EXPECT(handler::count() > 0);
ios.run_one();
BEAST_EXPECT(handler::count() == 0);
}
{
// Make sure uninvoked handlers are
// destroyed when calling ~io_service
{
boost::asio::io_service ios;
test::string_istream is{ios,
"GET / HTTP/1.1\r\n\r\n"};
BEAST_EXPECT(handler::count() == 0);
streambuf sb;
message<true, streambuf_body, fields> m;
async_read(is, sb, m, handler{});
BEAST_EXPECT(handler::count() > 0);
}
BEAST_EXPECT(handler::count() == 0);
}
}
void run() override
{
testThrow();
@@ -382,6 +432,8 @@ public:
yield_to(&read_test::testReadHeaders, this);
yield_to(&read_test::testRead, this);
yield_to(&read_test::testEof, this);
testIoService();
}
};
@@ -389,4 +441,3 @@ BEAST_DEFINE_TESTSUITE(read,http,beast);
} // http
} // beast

View File

@@ -55,9 +55,8 @@ public:
}
template<class WriteFunction>
boost::tribool
write(resume_context&&, error_code&,
WriteFunction&& wf) noexcept
bool
write(error_code&, WriteFunction&& wf) noexcept
{
wf(boost::asio::buffer(body_));
return true;
@@ -103,8 +102,6 @@ public:
{
std::size_t n_ = 0;
value_type const& body_;
bool suspend_ = false;
enable_yield_to yt_;
public:
template<bool isRequest, class Allocator>
@@ -120,37 +117,12 @@ public:
body_.fc_.fail(ec);
}
class do_resume
{
resume_context rc_;
public:
explicit
do_resume(resume_context&& rc)
: rc_(std::move(rc))
{
}
void
operator()()
{
rc_();
}
};
template<class WriteFunction>
boost::tribool
write(resume_context&& rc, error_code& ec,
WriteFunction&& wf) noexcept
bool
write(error_code& ec, WriteFunction&& wf) noexcept
{
if(body_.fc_.fail(ec))
return false;
suspend_ = ! suspend_;
if(suspend_)
{
yt_.get_io_service().post(do_resume{std::move(rc)});
return boost::indeterminate;
}
if(n_ >= body_.s_.size())
return true;
wf(boost::asio::buffer(body_.s_.data() + n_, 1));
@@ -639,6 +611,61 @@ public:
}
}
// Ensure completion handlers are not leaked
struct handler
{
static std::atomic<std::size_t>&
count() { static std::atomic<std::size_t> n; return n; }
handler() { ++count(); }
~handler() { --count(); }
handler(handler const&) { ++count(); }
void operator()(error_code const&) const {}
};
void
testIoService()
{
{
// Make sure handlers are not destroyed
// after calling io_service::stop
boost::asio::io_service ios;
test::string_ostream os{ios};
BEAST_EXPECT(handler::count() == 0);
message<true, string_body, fields> m;
m.method = "GET";
m.version = 11;
m.url = "/";
m.fields["Content-Length"] = "5";
m.body = "*****";
async_write(os, m, handler{});
BEAST_EXPECT(handler::count() > 0);
ios.stop();
BEAST_EXPECT(handler::count() > 0);
ios.reset();
BEAST_EXPECT(handler::count() > 0);
ios.run_one();
BEAST_EXPECT(handler::count() == 0);
}
{
// Make sure uninvoked handlers are
// destroyed when calling ~io_service
{
boost::asio::io_service ios;
test::string_ostream is{ios};
BEAST_EXPECT(handler::count() == 0);
message<true, string_body, fields> m;
m.method = "GET";
m.version = 11;
m.url = "/";
m.fields["Content-Length"] = "5";
m.body = "*****";
async_write(is, m, handler{});
BEAST_EXPECT(handler::count() > 0);
}
BEAST_EXPECT(handler::count() == 0);
}
}
void run() override
{
yield_to(&write_test::testAsyncWriteHeaders, this);
@@ -647,6 +674,7 @@ public:
testOutput();
test_std_ostream();
testOstream();
testIoService();
}
};

View File

@@ -22,6 +22,8 @@ add_executable (websocket-tests
if (NOT WIN32)
target_link_libraries(websocket-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(websocket-tests ${Boost_LIBRARIES})
endif()
if (MINGW)

View File

@@ -109,26 +109,38 @@ public:
return false;
}
struct identity
struct test_decorator
{
template<class Body, class Fields>
void
operator()(http::message<true, Body, Fields>&)
int& what;
test_decorator(test_decorator const&) = default;
test_decorator(int& what_)
: what(what_)
{
what = 0;
}
template<class Body, class Fields>
template<class Fields>
void
operator()(http::message<false, Body, Fields>&)
operator()(http::header<true, Fields>&) const
{
what |= 1;
}
template<class Fields>
void
operator()(http::header<false, Fields>&) const
{
what |= 2;
}
};
void testOptions()
void
testOptions()
{
stream<socket_type> ws(ios_);
ws.set_option(auto_fragment{true});
ws.set_option(decorate(identity{}));
ws.set_option(keep_alive{false});
ws.set_option(write_buffer_size{2048});
ws.set_option(message_type{opcode::text});
@@ -411,6 +423,24 @@ public:
);
}
void
testDecorator(endpoint_type const& ep)
{
error_code ec;
socket_type sock{ios_};
sock.connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
stream<socket_type&> ws{sock};
int what;
ws.set_option(decorate(test_decorator{what}));
BEAST_EXPECT(what == 0);
ws.handshake("localhost", "/", ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
BEAST_EXPECT(what == 1);
}
void testMask(endpoint_type const& ep,
yield_context do_yield)
{
@@ -775,6 +805,32 @@ public:
}
#endif
/*
https://github.com/vinniefalco/Beast/issues/300
Write a message as two individual frames
*/
void
testWriteFrames(endpoint_type const& ep)
{
error_code ec;
socket_type sock{ios_};
sock.connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
stream<socket_type&> ws{sock};
ws.handshake("localhost", "/", ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
ws.write_frame(false, sbuf("u"));
ws.write_frame(true, sbuf("v"));
streambuf sb;
opcode op;
ws.read(op, sb, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
}
void
testAsyncWriteFrame(endpoint_type const& ep)
{
@@ -1251,17 +1307,24 @@ public:
testBadHandshakes();
testBadResponses();
permessage_deflate pmd;
pmd.client_enable = false;
pmd.server_enable = false;
{
error_code ec;
::websocket::sync_echo_server server{nullptr};
server.set_option(pmd);
server.open(any, ec);
BEAST_EXPECTS(! ec, ec.message());
auto const ep = server.local_endpoint();
testDecorator(ep);
//testInvokable1(ep);
testInvokable2(ep);
testInvokable3(ep);
testInvokable4(ep);
//testInvokable5(ep);
testWriteFrames(ep);
testAsyncWriteFrame(ep);
}
@@ -1309,8 +1372,6 @@ public:
}
};
permessage_deflate pmd;
pmd.client_enable = false;
pmd.server_enable = false;
doClientTests(pmd);

View File

@@ -21,4 +21,6 @@ add_executable (zlib-tests
if (NOT WIN32)
target_link_libraries(zlib-tests ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(zlib-tests ${Boost_LIBRARIES})
endif()