Refactor all examples:

fix #575, fix #604, fix #608, fix #634, fix #712

All examples are rewritten:

* Using Best Practices
* Mostly self-contained
* New examples to complete the feature matrix
* The server-framework example is removed
This commit is contained in:
Vinnie Falco
2017-08-07 20:53:11 -07:00
parent 20a8f7d75b
commit dd71b0f94d
187 changed files with 11759 additions and 7098 deletions
-1
View File
@@ -8,4 +8,3 @@
#
add_subdirectory (common)
add_subdirectory (server)
-1
View File
@@ -9,7 +9,6 @@
alias run-tests :
common//run-tests
server//run-tests
;
alias fat-tests ;
+2 -2
View File
@@ -17,8 +17,8 @@ add_executable (tests-example-common
${COMMON_INCLUDES}
Jamfile
detect_ssl.cpp
mime_types.cpp
rfc7231.cpp
root_certificates.cpp
server_certificate.cpp
session_alloc.cpp
ssl_stream.cpp
write_msg.cpp
+2 -2
View File
@@ -9,8 +9,8 @@
local SOURCES =
detect_ssl.cpp
mime_types.cpp
rfc7231.cpp
root_certificates.cpp
server_certificate.cpp
session_alloc.cpp
ssl_stream.cpp
write_msg.cpp
@@ -8,5 +8,5 @@
//
// Test that header file is self-contained.
#include "example/common/mime_types.hpp"
#include "example/common/root_certificates.hpp"
@@ -8,5 +8,5 @@
//
// Test that header file is self-contained.
#include "example/common/rfc7231.hpp"
#include "example/common/server_certificate.hpp"
-37
View File
@@ -1,37 +0,0 @@
#
# Copyright (c) 2016-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)
#
# Official repository: https://github.com/boostorg/beast
#
GroupSources(example/server-framework framework)
GroupSources(example/common common)
GroupSources(test/extras/include/boost/beast extras)
GroupSources(include/boost/beast beast)
GroupSources(test/example/server "/")
add_executable (tests-example-server
${BOOST_BEAST_INCLUDES}
${COMMON_INCLUDES}
${SERVER_INCLUDES}
${TEST_MAIN}
Jamfile
file_service.cpp
framework.cpp
http_async_port.cpp
http_base.cpp
http_sync_port.cpp
https_ports.cpp
multi_port.cpp
server.cpp
service_list.cpp
ssl_certificate
tests.cpp
ws_async_port.cpp
ws_sync_port.cpp
ws_upgrade_service.cpp
wss_ports.cpp
)
-39
View File
@@ -1,39 +0,0 @@
#
# Copyright (c) 2016-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)
#
# Official repository: https://github.com/boostorg/beast
#
local SOURCES =
file_service.cpp
framework.cpp
http_async_port.cpp
http_base.cpp
http_sync_port.cpp
https_ports.cpp
multi_port.cpp
server.cpp
service_list.cpp
ssl_certificate.cpp
#tests.cpp
ws_async_port.cpp
ws_sync_port.cpp
ws_upgrade_service.cpp
wss_ports.cpp
;
local RUN_TESTS ;
for local f in $(SOURCES)
{
RUN_TESTS += [ compile $(f) ] ;
}
alias run-tests : $(RUN_TESTS) ;
alias fat-tests : run-tests ;
explicit fat-tests ;
-12
View File
@@ -1,12 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include "example/server-framework/file_service.hpp"
-12
View File
@@ -1,12 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include "example/server-framework/framework.hpp"
-12
View File
@@ -1,12 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include "example/server-framework/http_async_port.hpp"
-12
View File
@@ -1,12 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include "example/server-framework/http_base.hpp"
-12
View File
@@ -1,12 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include "example/server-framework/http_sync_port.hpp"
-15
View File
@@ -1,15 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
#if BOOST_BEAST_USE_OPENSSL
// Test that header file is self-contained.
#include "example/server-framework/https_ports.hpp"
#endif
-16
View File
@@ -1,16 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
#if BOOST_BEAST_USE_OPENSSL
// Test that header file is self-contained.
#include "example/server-framework/multi_port.hpp"
#endif
-12
View File
@@ -1,12 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include "example/server-framework/server.hpp"
-12
View File
@@ -1,12 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include "example/server-framework/service_list.hpp"
-15
View File
@@ -1,15 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
#if BOOST_BEAST_USE_OPENSSL
// Test that header file is self-contained.
#include "example/server-framework/ssl_certificate.hpp"
#endif
-320
View File
@@ -1,320 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
#include "example/server-framework/http_sync_port.hpp"
#include "example/server-framework/http_async_port.hpp"
#include "example/server-framework/ws_sync_port.hpp"
#include "example/server-framework/ws_async_port.hpp"
#include "example/server-framework/ws_upgrade_service.hpp"
#if BOOST_BEAST_USE_OPENSSL
# include "example/server-framework/https_ports.hpp"
# include "example/server-framework/multi_port.hpp"
# include "example/server-framework/ssl_certificate.hpp"
# include "example/server-framework/wss_ports.hpp"
#endif
#include <boost/beast/websocket.hpp>
#include <boost/beast/test/yield_to.hpp>
#include <boost/beast/unit_test/suite.hpp>
namespace boost {
namespace beast {
namespace websocket {
class server_test
: public beast::unit_test::suite
, public test::enable_yield_to
{
public:
static unsigned short constexpr port_num = 6000;
class set_ws_options
{
beast::websocket::permessage_deflate pmd_;
public:
set_ws_options(beast::websocket::permessage_deflate const& pmd)
: pmd_(pmd)
{
}
template<class NextLayer>
void
operator()(beast::websocket::stream<NextLayer>& ws) const
{
ws.auto_fragment(false);
ws.set_option(pmd_);
ws.read_message_max(64 * 1024 * 1024);
}
};
set_ws_options
get_ws_options()
{
beast::websocket::permessage_deflate pmd;
pmd.client_enable = true;
pmd.server_enable = true;
pmd.compLevel = 3;
return set_ws_options{pmd};
}
template<class Stream>
void
doOptions(Stream& stream, error_code& ec)
{
http::request<http::empty_body> req;
req.version = 11;
req.method(http::verb::options);
req.target("*");
req.set(http::field::user_agent, "test");
req.set(http::field::connection, "close");
http::write(stream, req, ec);
if(! BEAST_EXPECTS(
ec == http::error::end_of_stream,
ec.message()))
return;
beast::flat_buffer b;
http::response<http::string_body> res;
http::read(stream, b, res, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
}
template<class NextLayer>
void
doHello(stream<NextLayer>& ws, error_code& ec)
{
ws.handshake("localhost", "/", ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
ws.write(boost::asio::buffer(std::string("Hello, world!")), ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
beast::multi_buffer b;
ws.read(b, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
ws.close(beast::websocket::close_code::normal, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
}
void
httpClient(framework::endpoint_type const& ep)
{
error_code ec;
boost::asio::ip::tcp::socket con{ios_};
con.connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
doOptions(con, ec);
}
void
wsClient(framework::endpoint_type const& ep)
{
error_code ec;
stream<boost::asio::ip::tcp::socket> ws{ios_};
ws.next_layer().connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
doHello(ws, ec);
}
void
testPlain()
{
using namespace framework;
// ws sync
{
error_code ec;
server instance;
auto const ep1 = endpoint_type{
address_type::from_string("127.0.0.1"), port_num};
auto const wsp = instance.make_port<ws_sync_port>(
ec, ep1, instance, log, get_ws_options());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
auto const ep2 = endpoint_type{
address_type::from_string("127.0.0.1"),
static_cast<unsigned short>(port_num + 1)};
auto const sp = instance.make_port<
http_sync_port<ws_upgrade_service<ws_sync_port>>>(
ec, ep2, instance, log);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
sp->template init<0>(ec, *wsp);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
wsClient(ep1);
wsClient(ep2);
httpClient(ep2);
}
// ws async
{
error_code ec;
server instance;
auto const ep1 = endpoint_type{
address_type::from_string("127.0.0.1"), port_num};
auto const wsp = instance.make_port<ws_async_port>(
ec, ep1, instance, log, get_ws_options());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
auto const ep2 = endpoint_type{
address_type::from_string("127.0.0.1"),
static_cast<unsigned short>(port_num + 1)};
auto const sp = instance.make_port<
http_async_port<ws_upgrade_service<ws_async_port>>>(
ec, ep2, instance, log);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
sp->template init<0>(ec, *wsp);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
wsClient(ep1);
wsClient(ep2);
httpClient(ep2);
}
}
#if BOOST_BEAST_USE_OPENSSL
//
// OpenSSL enabled ports
//
void
httpsClient(framework::endpoint_type const& ep,
boost::asio::ssl::context& ctx)
{
error_code ec;
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> con{ios_, ctx};
con.next_layer().connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
con.handshake(
boost::asio::ssl::stream_base::client, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
doOptions(con, ec);
if(ec)
return;
con.shutdown(ec);
// VFALCO No idea why we get eof in the normal case
if(ec == boost::asio::error::eof)
ec.assign(0, ec.category());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
}
void
wssClient(framework::endpoint_type const& ep,
boost::asio::ssl::context& ctx)
{
error_code ec;
stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> wss{ios_, ctx};
wss.next_layer().next_layer().connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
wss.next_layer().handshake(
boost::asio::ssl::stream_base::client, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
doHello(wss, ec);
}
void
testSSL()
{
using namespace framework;
ssl_certificate cert;
// wss sync
{
error_code ec;
server instance;
auto const ep1 = endpoint_type{
address_type::from_string("127.0.0.1"), port_num};
auto const wsp = instance.make_port<wss_sync_port>(
ec, ep1, instance, log, cert.get(), get_ws_options());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
auto const ep2 = endpoint_type{
address_type::from_string("127.0.0.1"),
static_cast<unsigned short>(port_num + 1)};
auto const sp = instance.make_port<
https_sync_port<ws_upgrade_service<wss_sync_port>>>(
ec, ep2, instance, log, cert.get());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
sp->template init<0>(ec, *wsp);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
wssClient(ep1, cert.get());
wssClient(ep2, cert.get());
httpsClient(ep2, cert.get());
}
// wss async
{
error_code ec;
server instance;
auto const ep1 = endpoint_type{
address_type::from_string("127.0.0.1"), port_num};
auto const wsp = instance.make_port<wss_async_port>(
ec, ep1, instance, log, cert.get(), get_ws_options());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
auto const ep2 = endpoint_type{
address_type::from_string("127.0.0.1"),
static_cast<unsigned short>(port_num + 1)};
auto const sp = instance.make_port<
https_async_port<ws_upgrade_service<wss_async_port>>>(
ec, ep2, instance, log, cert.get());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
sp->template init<0>(ec, *wsp);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
wssClient(ep1, cert.get());
wssClient(ep2, cert.get());
httpsClient(ep2, cert.get());
}
}
#endif
void
run() override
{
testPlain();
#if BOOST_BEAST_USE_OPENSSL
testSSL();
#endif
}
};
BEAST_DEFINE_TESTSUITE(beast,websocket,server);
} // websocket
} // beast
} // boost
-12
View File
@@ -1,12 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include "example/server-framework/ws_async_port.hpp"
-12
View File
@@ -1,12 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include "example/server-framework/ws_sync_port.hpp"
@@ -1,12 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include "example/server-framework/ws_upgrade_service.hpp"
-15
View File
@@ -1,15 +0,0 @@
//
// Copyright (c) 2016-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)
//
// Official repository: https://github.com/boostorg/beast
//
#if BOOST_BEAST_USE_OPENSSL
// Test that header file is self-contained.
#include "example/server-framework/wss_ports.hpp"
#endif