Tidy up test build scripts and projects

This commit is contained in:
Vinnie Falco
2017-06-19 12:49:42 -07:00
parent 79eb97fbd6
commit d5f15976e7
16 changed files with 186 additions and 629 deletions

View File

@@ -186,9 +186,5 @@ file(GLOB_RECURSE SERVER_INCLUDES
)
add_subdirectory (test)
add_subdirectory (example)
if (OPENSSL_FOUND)
add_subdirectory (test/websocket/ssl)
endif()

View File

@@ -85,7 +85,6 @@
[import ../test/core/doc_snippets.cpp]
[import ../test/http/doc_snippets.cpp]
[import ../test/websocket/doc_snippets.cpp]
[import ../test/websocket/ssl/doc_snippets.cpp]
[include 1_intro.qbk]
[include 2_examples.qbk]

View File

@@ -31,9 +31,9 @@ and `ssl::context` arguments are forwarded to the wrapped stream's constructor:
[wss_snippet_1]
[wss_snippet_2]
[note
Code which declares stream objects using Asio SSL types
must include the file `<beast/websocket/ssl.hpp>`.
[important
Code which declares websocket stream objects using Asio SSL types
must include the file [include_file beast/websocket/ssl.hpp].
]
[heading Non-owning References]

View File

@@ -14,83 +14,8 @@ compile version.cpp : : ;
compile websocket.cpp : : ;
compile zlib.cpp : : ;
build-project core ;
build-project http ;
build-project server ;
build-project websocket ;
unit-test core-tests :
../extras/beast/unit_test/main.cpp
core/async_result.cpp
core/bind_handler.cpp
core/buffer_bench.cpp
core/buffer_cat.cpp
core/buffer_prefix.cpp
core/buffered_read_stream.cpp
core/buffers_adapter.cpp
core/clamp.cpp
core/consuming_buffers.cpp
core/doc_examples.cpp
core/doc_snippets.cpp
core/drain_buffer.cpp
core/error.cpp
core/flat_buffer.cpp
core/handler_alloc.cpp
core/handler_ptr.cpp
core/multi_buffer.cpp
core/ostream.cpp
core/read_size.cpp
core/static_buffer.cpp
core/static_string.cpp
core/string.cpp
core/string_param.cpp
core/type_traits.cpp
core/base64.cpp
core/empty_base_optimization.cpp
core/sha1.cpp
;
unit-test http-tests :
../extras/beast/unit_test/main.cpp
http/basic_parser.cpp
http/buffer_body.cpp
http/doc_examples.cpp
http/doc_snippets.cpp
http/dynamic_body.cpp
http/error.cpp
http/field.cpp
http/fields.cpp
http/message.cpp
http/parser.cpp
http/read.cpp
http/rfc7230.cpp
http/serializer.cpp
http/status.cpp
http/string_body.cpp
http/string_view_body.cpp
http/type_traits.cpp
http/verb.cpp
http/write.cpp
;
unit-test http-bench :
../extras/beast/unit_test/main.cpp
http/nodejs_parser.cpp
http/parser_bench.cpp
;
unit-test zlib-tests :
../extras/beast/unit_test/main.cpp
zlib/zlib-1.2.8/adler32.c
zlib/zlib-1.2.8/compress.c
zlib/zlib-1.2.8/crc32.c
zlib/zlib-1.2.8/deflate.c
zlib/zlib-1.2.8/infback.c
zlib/zlib-1.2.8/inffast.c
zlib/zlib-1.2.8/inflate.c
zlib/zlib-1.2.8/inftrees.c
zlib/zlib-1.2.8/trees.c
zlib/zlib-1.2.8/uncompr.c
zlib/zlib-1.2.8/zutil.c
zlib/deflate_stream.cpp
zlib/error.cpp
zlib/inflate_stream.cpp
;
build-project zlib ;

View File

@@ -40,4 +40,11 @@ add_executable (core-tests
sha1.cpp
)
target_link_libraries(core-tests Beast ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_COROUTINE_LIBRARY} ${Boost_THREAD_LIBRARY} ${Boost_CONTEXT_LIBRARY})
target_link_libraries(core-tests
Beast
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_COROUTINE_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_CONTEXT_LIBRARY}
)

37
test/core/Jamfile Normal file
View File

@@ -0,0 +1,37 @@
#
# 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)
#
unit-test core-tests :
../../extras/beast/unit_test/main.cpp
async_result.cpp
bind_handler.cpp
buffer_bench.cpp
buffer_cat.cpp
buffer_prefix.cpp
buffered_read_stream.cpp
buffers_adapter.cpp
clamp.cpp
consuming_buffers.cpp
doc_examples.cpp
doc_snippets.cpp
drain_buffer.cpp
error.cpp
flat_buffer.cpp
handler_alloc.cpp
handler_ptr.cpp
multi_buffer.cpp
ostream.cpp
read_size.cpp
static_buffer.cpp
static_string.cpp
string.cpp
string_param.cpp
type_traits.cpp
base64.cpp
empty_base_optimization.cpp
sha1.cpp
;

View File

@@ -35,7 +35,14 @@ add_executable (http-tests
write.cpp
)
target_link_libraries(http-tests Beast ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_COROUTINE_LIBRARY} ${Boost_THREAD_LIBRARY} ${Boost_CONTEXT_LIBRARY})
target_link_libraries(http-tests
Beast
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_COROUTINE_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_CONTEXT_LIBRARY}
)
add_executable (http-bench
${BEAST_INCLUDES}
@@ -47,4 +54,8 @@ add_executable (http-bench
parser_bench.cpp
)
target_link_libraries(http-bench Beast ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY})
target_link_libraries(http-bench
Beast
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
)

35
test/http/Jamfile Normal file
View File

@@ -0,0 +1,35 @@
#
# 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)
#
unit-test http-tests :
../../extras/beast/unit_test/main.cpp
basic_parser.cpp
buffer_body.cpp
doc_examples.cpp
doc_snippets.cpp
dynamic_body.cpp
error.cpp
field.cpp
fields.cpp
message.cpp
parser.cpp
read.cpp
rfc7230.cpp
serializer.cpp
status.cpp
string_body.cpp
string_view_body.cpp
type_traits.cpp
verb.cpp
write.cpp
;
unit-test http-bench :
../../extras/beast/unit_test/main.cpp
nodejs_parser.cpp
parser_bench.cpp
;

View File

@@ -6,6 +6,10 @@ GroupSources(test/websocket "/")
include_directories(../../example/)
if (OPENSSL_FOUND)
include_directories(${OPENSSL_INCLUDE_DIR})
endif()
add_executable (websocket-tests
${BEAST_INCLUDES}
${EXTRAS_INCLUDES}
@@ -31,3 +35,7 @@ target_link_libraries(websocket-tests
${Boost_THREAD_LIBRARY}
${Boost_CONTEXT_LIBRARY}
)
if (OPENSSL_FOUND)
target_link_libraries(websocket-tests ${OPENSSL_LIBRARIES})
endif()

View File

@@ -229,3 +229,53 @@ void echo(stream<boost::asio::ip::tcp::socket>& ws,
#endif
} // doc_ws_snippets
//------------------------------------------------------------------------------
#if BEAST_USE_OPENSSL
//[wss_snippet_1
#include <beast/websocket/ssl.hpp>
#include <boost/asio/ssl.hpp>
//]
namespace doc_wss_snippets {
void fxx() {
boost::asio::io_service ios;
boost::asio::io_service::work work{ios};
std::thread t{[&](){ ios.run(); }};
error_code ec;
boost::asio::ip::tcp::socket sock{ios};
{
//[wss_snippet_2
boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23};
stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> wss{ios, ctx};
//]
}
{
//[wss_snippet_3
boost::asio::ip::tcp::endpoint ep;
boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23};
stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> ws{ios, ctx};
// connect the underlying TCP/IP socket
ws.next_layer().next_layer().connect(ep);
// perform SSL handshake
ws.next_layer().handshake(boost::asio::ssl::stream_base::client);
// perform WebSocket handshake
ws.handshake("localhost", "/");
//]
}
} // fxx()
} // doc_wss_snippets
#endif

View File

@@ -1,19 +0,0 @@
# Part of Beast
GroupSources(extras/beast extras)
GroupSources(include/beast beast)
GroupSources(test/websocket/ssl "/")
include_directories(${OPENSSL_INCLUDE_DIR})
add_executable (websocket-ssl-tests
${BEAST_INCLUDES}
${EXTRAS_INCLUDES}
../../../extras/beast/unit_test/main.cpp
doc_snippets.cpp
websocket_async_ssl_echo_server.hpp
ssl_server.cpp
)
target_link_libraries(websocket-ssl-tests Beast ${OPENSSL_LIBRARIES} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY})

View File

@@ -1,58 +0,0 @@
//
// 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)
//
#include <beast/core.hpp>
#include <beast/websocket.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <thread>
using namespace beast;
using namespace beast::websocket;
//[wss_snippet_1
#include <beast/websocket/ssl.hpp>
#include <boost/asio/ssl.hpp>
//]
namespace doc_wss_snippets {
void fxx() {
boost::asio::io_service ios;
boost::asio::io_service::work work{ios};
std::thread t{[&](){ ios.run(); }};
error_code ec;
boost::asio::ip::tcp::socket sock{ios};
{
//[wss_snippet_2
boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23};
stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> wss{ios, ctx};
//]
}
{
//[wss_snippet_3
boost::asio::ip::tcp::endpoint ep;
boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23};
stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> ws{ios, ctx};
// connect the underlying TCP/IP socket
ws.next_layer().next_layer().connect(ep);
// perform SSL handshake
ws.next_layer().handshake(boost::asio::ssl::stream_base::client);
// perform WebSocket handshake
ws.handshake("localhost", "/");
//]
}
} // fxx()
} // doc_wss_snippets

View File

@@ -1,156 +0,0 @@
//
// 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)
//
#include "websocket_async_ssl_echo_server.hpp"
#include <beast/websocket/stream.hpp>
#include <beast/core/ostream.hpp>
#include <beast/unit_test/suite.hpp>
#include <beast/test/yield_to.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
namespace beast {
namespace websocket {
class ssl_server_test
: public beast::unit_test::suite
, public test::enable_yield_to
{
public:
using self = ssl_server_test;
using endpoint_type = boost::asio::ip::tcp::endpoint;
using address_type = boost::asio::ip::address;
using socket_type = boost::asio::ip::tcp::socket;
void
run() override
{
/*
The certificate was generated from CMD.EXE on Windows 10 using:
winpty openssl dhparam -out dh.pem 2048
winpty openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 10000 -out cert.pem -subj "//C=US\ST=CA\L=Los Angeles\O=Beast\CN=www.example.com"
*/
std::string const cert =
"-----BEGIN CERTIFICATE-----\n"
"MIIDaDCCAlCgAwIBAgIJAO8vBu8i8exWMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV\n"
"BAYTAlVTMQswCQYDVQQIDAJDQTEtMCsGA1UEBwwkTG9zIEFuZ2VsZXNPPUJlYXN0\n"
"Q049d3d3LmV4YW1wbGUuY29tMB4XDTE3MDUwMzE4MzkxMloXDTQ0MDkxODE4Mzkx\n"
"MlowSTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMS0wKwYDVQQHDCRMb3MgQW5n\n"
"ZWxlc089QmVhc3RDTj13d3cuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA\n"
"A4IBDwAwggEKAoIBAQDJ7BRKFO8fqmsEXw8v9YOVXyrQVsVbjSSGEs4Vzs4cJgcF\n"
"xqGitbnLIrOgiJpRAPLy5MNcAXE1strVGfdEf7xMYSZ/4wOrxUyVw/Ltgsft8m7b\n"
"Fu8TsCzO6XrxpnVtWk506YZ7ToTa5UjHfBi2+pWTxbpN12UhiZNUcrRsqTFW+6fO\n"
"9d7xm5wlaZG8cMdg0cO1bhkz45JSl3wWKIES7t3EfKePZbNlQ5hPy7Pd5JTmdGBp\n"
"yY8anC8u4LPbmgW0/U31PH0rRVfGcBbZsAoQw5Tc5dnb6N2GEIbq3ehSfdDHGnrv\n"
"enu2tOK9Qx6GEzXh3sekZkxcgh+NlIxCNxu//Dk9AgMBAAGjUzBRMB0GA1UdDgQW\n"
"BBTZh0N9Ne1OD7GBGJYz4PNESHuXezAfBgNVHSMEGDAWgBTZh0N9Ne1OD7GBGJYz\n"
"4PNESHuXezAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCmTJVT\n"
"LH5Cru1vXtzb3N9dyolcVH82xFVwPewArchgq+CEkajOU9bnzCqvhM4CryBb4cUs\n"
"gqXWp85hAh55uBOqXb2yyESEleMCJEiVTwm/m26FdONvEGptsiCmF5Gxi0YRtn8N\n"
"V+KhrQaAyLrLdPYI7TrwAOisq2I1cD0mt+xgwuv/654Rl3IhOMx+fKWKJ9qLAiaE\n"
"fQyshjlPP9mYVxWOxqctUdQ8UnsUKKGEUcVrA08i1OAnVKlPFjKBvk+r7jpsTPcr\n"
"9pWXTO9JrYMML7d+XRSZA1n3856OqZDX4403+9FnXCvfcLZLLKTBvwwFgEFGpzjK\n"
"UEVbkhd5qstF6qWK\n"
"-----END CERTIFICATE-----\n";
std::string const key =
"-----BEGIN PRIVATE KEY-----\n"
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDJ7BRKFO8fqmsE\n"
"Xw8v9YOVXyrQVsVbjSSGEs4Vzs4cJgcFxqGitbnLIrOgiJpRAPLy5MNcAXE1strV\n"
"GfdEf7xMYSZ/4wOrxUyVw/Ltgsft8m7bFu8TsCzO6XrxpnVtWk506YZ7ToTa5UjH\n"
"fBi2+pWTxbpN12UhiZNUcrRsqTFW+6fO9d7xm5wlaZG8cMdg0cO1bhkz45JSl3wW\n"
"KIES7t3EfKePZbNlQ5hPy7Pd5JTmdGBpyY8anC8u4LPbmgW0/U31PH0rRVfGcBbZ\n"
"sAoQw5Tc5dnb6N2GEIbq3ehSfdDHGnrvenu2tOK9Qx6GEzXh3sekZkxcgh+NlIxC\n"
"Nxu//Dk9AgMBAAECggEBAK1gV8uETg4SdfE67f9v/5uyK0DYQH1ro4C7hNiUycTB\n"
"oiYDd6YOA4m4MiQVJuuGtRR5+IR3eI1zFRMFSJs4UqYChNwqQGys7CVsKpplQOW+\n"
"1BCqkH2HN/Ix5662Dv3mHJemLCKUON77IJKoq0/xuZ04mc9csykox6grFWB3pjXY\n"
"OEn9U8pt5KNldWfpfAZ7xu9WfyvthGXlhfwKEetOuHfAQv7FF6s25UIEU6Hmnwp9\n"
"VmYp2twfMGdztz/gfFjKOGxf92RG+FMSkyAPq/vhyB7oQWxa+vdBn6BSdsfn27Qs\n"
"bTvXrGe4FYcbuw4WkAKTljZX7TUegkXiwFoSps0jegECgYEA7o5AcRTZVUmmSs8W\n"
"PUHn89UEuDAMFVk7grG1bg8exLQSpugCykcqXt1WNrqB7x6nB+dbVANWNhSmhgCg\n"
"VrV941vbx8ketqZ9YInSbGPWIU/tss3r8Yx2Ct3mQpvpGC6iGHzEc/NHJP8Efvh/\n"
"CcUWmLjLGJYYeP5oNu5cncC3fXUCgYEA2LANATm0A6sFVGe3sSLO9un1brA4zlZE\n"
"Hjd3KOZnMPt73B426qUOcw5B2wIS8GJsUES0P94pKg83oyzmoUV9vJpJLjHA4qmL\n"
"CDAd6CjAmE5ea4dFdZwDDS8F9FntJMdPQJA9vq+JaeS+k7ds3+7oiNe+RUIHR1Sz\n"
"VEAKh3Xw66kCgYB7KO/2Mchesu5qku2tZJhHF4QfP5cNcos511uO3bmJ3ln+16uR\n"
"GRqz7Vu0V6f7dvzPJM/O2QYqV5D9f9dHzN2YgvU9+QSlUeFK9PyxPv3vJt/WP1//\n"
"zf+nbpaRbwLxnCnNsKSQJFpnrE166/pSZfFbmZQpNlyeIuJU8czZGQTifQKBgHXe\n"
"/pQGEZhVNab+bHwdFTxXdDzr+1qyrodJYLaM7uFES9InVXQ6qSuJO+WosSi2QXlA\n"
"hlSfwwCwGnHXAPYFWSp5Owm34tbpp0mi8wHQ+UNgjhgsE2qwnTBUvgZ3zHpPORtD\n"
"23KZBkTmO40bIEyIJ1IZGdWO32q79nkEBTY+v/lRAoGBAI1rbouFYPBrTYQ9kcjt\n"
"1yfu4JF5MvO9JrHQ9tOwkqDmNCWx9xWXbgydsn/eFtuUMULWsG3lNjfst/Esb8ch\n"
"k5cZd6pdJZa4/vhEwrYYSuEjMCnRb0lUsm7TsHxQrUd6Fi/mUuFU/haC0o0chLq7\n"
"pVOUFq5mW8p0zbtfHbjkgxyF\n"
"-----END PRIVATE KEY-----\n";
std::string const dh =
"-----BEGIN DH PARAMETERS-----\n"
"MIIBCAKCAQEArzQc5mpm0Fs8yahDeySj31JZlwEphUdZ9StM2D8+Fo7TMduGtSi+\n"
"/HRWVwHcTFAgrxVdm+dl474mOUqqaz4MpzIb6+6OVfWHbQJmXPepZKyu4LgUPvY/\n"
"4q3/iDMjIS0fLOu/bLuObwU5ccZmDgfhmz1GanRlTQOiYRty3FiOATWZBRh6uv4u\n"
"tff4A9Bm3V9tLx9S6djq31w31Gl7OQhryodW28kc16t9TvO1BzcV3HjRPwpe701X\n"
"oEEZdnZWANkkpR/m/pfgdmGPU66S2sXMHgsliViQWpDCYeehrvFRHEdR9NV+XJfC\n"
"QMUk26jPTIVTLfXmmwU0u8vUkpR7LQKkwwIBAg==\n"
"-----END DH PARAMETERS-----\n";
using endpoint_type = boost::asio::ip::tcp::endpoint;
using address_type = boost::asio::ip::address;
::websocket::async_ssl_echo_server server{
&log, 1, cert, key, dh};
error_code ec;
server.open(endpoint_type{
address_type::from_string("127.0.0.1"), 6000 }, ec);
auto const ep = server.local_endpoint();
using boost::asio::connect;
using socket = boost::asio::ip::tcp::socket;
using io_service = boost::asio::io_service;
namespace ssl = boost::asio::ssl;
// Perform SSL handshaking
io_service ios;
using stream_type = ssl::stream<socket>;
ssl::context ctx{ssl::context::sslv23};
stream_type stream{ios_, ctx};
stream.next_layer().connect(ep);
stream.set_verify_mode(ssl::verify_none);
stream.handshake(ssl::stream_base::client);
// Secure WebSocket connect and send message using Beast
beast::websocket::stream<stream_type&> ws{stream};
ws.handshake("localhost", "/");
ws.write(boost::asio::buffer("Hello, world!", 13));
// Receive Secure WebSocket message, print and close using Beast
beast::multi_buffer b;
ws.read(b);
ws.close(beast::websocket::close_code::normal);
try
{
for(;;)
{
ws.read(b);
b.consume(b.size());
}
}
catch(system_error const& se)
{
if(se.code() != beast::websocket::error::closed)
throw;
}
BEAST_EXPECT(boost::lexical_cast<std::string>(
buffers(b.data())) == "Hello, world!");
}
};
BEAST_DEFINE_TESTSUITE(ssl_server,websocket,beast);
} // websocket
} // beast

View File

@@ -1,306 +0,0 @@
//
// 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 WEBSOCKET_ASYNC_SSL_ECHO_SERVER_HPP
#define WEBSOCKET_ASYNC_SSL_ECHO_SERVER_HPP
#include <beast/core/multi_buffer.hpp>
#include <beast/websocket/ssl.hpp>
#include <beast/websocket/stream.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/config.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
#include <atomic>
#include <functional>
#include <memory>
#include <mutex>
#include <ostream>
#include <string>
#include <thread>
#include <type_traits>
#include <typeindex>
#include <unordered_map>
#include <utility>
namespace websocket {
/** Asynchronous WebSocket echo client/server
*/
class async_ssl_echo_server
{
public:
using error_code = beast::error_code;
using address_type = boost::asio::ip::address;
using socket_type = boost::asio::ip::tcp::socket;
using endpoint_type = boost::asio::ip::tcp::endpoint;
private:
std::ostream* log_;
boost::asio::io_service ios_;
socket_type sock_;
endpoint_type ep_;
boost::asio::ip::tcp::acceptor acceptor_;
std::vector<std::thread> thread_;
boost::optional<boost::asio::io_service::work> work_;
boost::asio::ssl::context ctx_;
public:
async_ssl_echo_server(async_ssl_echo_server const&) = delete;
async_ssl_echo_server& operator=(async_ssl_echo_server const&) = delete;
/** Constructor.
@param log A pointer to a stream to log to, or `nullptr`
to disable logging.
@param threads The number of threads in the io_service.
*/
async_ssl_echo_server(std::ostream* log,
std::size_t threads, std::string const& cert,
std::string const& key, std::string const& tmp_dh)
: log_(log)
, sock_(ios_)
, acceptor_(ios_)
, work_(ios_)
, ctx_(boost::asio::ssl::context::sslv23)
{
ctx_.set_password_callback(
[](std::size_t size,
boost::asio::ssl::context_base::password_purpose)
{
return "test";
});
ctx_.set_options(
boost::asio::ssl::context::default_workarounds |
boost::asio::ssl::context::no_sslv2 |
boost::asio::ssl::context::single_dh_use);
ctx_.use_certificate_chain(
boost::asio::buffer(cert.data(), cert.size()));
ctx_.use_private_key(
boost::asio::buffer(key.data(), key.size()),
boost::asio::ssl::context::file_format::pem);
ctx_.use_tmp_dh(
boost::asio::buffer(tmp_dh.data(), tmp_dh.size()));
thread_.reserve(threads);
for(std::size_t i = 0; i < threads; ++i)
thread_.emplace_back(
[&]{ ios_.run(); });
}
/** Destructor.
*/
~async_ssl_echo_server()
{
work_ = boost::none;
error_code ec;
ios_.dispatch(
[&]{ acceptor_.close(ec); });
for(auto& t : thread_)
t.join();
}
/** Return the listening endpoint.
*/
endpoint_type
local_endpoint() const
{
return acceptor_.local_endpoint();
}
/** Open a listening port.
@param ep The address and port to bind to.
@param ec Set to the error, if any occurred.
*/
void
open(endpoint_type const& ep, error_code& ec)
{
acceptor_.open(ep.protocol(), ec);
if(ec)
return fail("open", ec);
acceptor_.set_option(
boost::asio::socket_base::reuse_address{true});
acceptor_.bind(ep, ec);
if(ec)
return fail("bind", ec);
acceptor_.listen(
boost::asio::socket_base::max_connections, ec);
if(ec)
return fail("listen", ec);
acceptor_.async_accept(sock_, ep_,
std::bind(&async_ssl_echo_server::on_accept, this,
std::placeholders::_1));
}
private:
class connection
{
struct data
{
async_ssl_echo_server& server;
endpoint_type ep;
int state = 0;
beast::websocket::stream<
boost::asio::ssl::stream<socket_type>> ws;
boost::asio::io_service::strand strand;
beast::multi_buffer db;
std::size_t id;
data(async_ssl_echo_server& server_,
endpoint_type const& ep_,
socket_type&& sock_)
: server(server_)
, ep(ep_)
, ws(sock_.get_io_service(), server_.ctx_)
, strand(ws.get_io_service())
, id([]
{
static std::atomic<std::size_t> n{0};
return ++n;
}())
{
// VFALCO This hack works around
// ssl::stream broken ctors
ws.next_layer().next_layer() = std::move(sock_);
}
};
// VFALCO This could be unique_ptr in [Net.TS]
std::shared_ptr<data> d_;
public:
connection(connection&&) = default;
connection(connection const&) = default;
connection& operator=(connection&&) = delete;
connection& operator=(connection const&) = delete;
template<class... Args>
explicit
connection(async_ssl_echo_server& server,
endpoint_type const& ep, socket_type&& sock,
Args&&... args)
: d_(std::make_shared<data>(server, ep,
std::forward<socket_type>(sock),
std::forward<Args>(args)...))
{
}
void
run()
{
(*this)(error_code{});
}
void
operator()(error_code ec)
{
auto& d = *d_;
switch(d.state)
{
// SSL handshake
case 0:
d.state = 1;
d.ws.next_layer().async_handshake(
boost::asio::ssl::stream_base::server,
d.strand.wrap(std::move(*this)));
return;
// WebSocket handshake
case 1:
if(ec)
return fail("async_handshake", ec);
d.state = 2;
d.ws.async_accept_ex(
[](beast::websocket::response_type& res)
{
res.insert(
"Server", "async_ssl_echo_server");
},
d.strand.wrap(std::move(*this)));
return;
case 2:
if(ec)
return fail("async_handshake", ec);
BOOST_FALLTHROUGH;
// WebSocket read
case 3:
if(ec)
return fail("async_write", ec);
d.db.consume(d.db.size());
d.state = 4;
d.ws.async_read(d.db,
d.strand.wrap(std::move(*this)));
return;
// WebSocket write
case 4:
if(ec == beast::websocket::error::closed)
return;
if(ec)
return fail("async_read", ec);
d.state = 3;
d.ws.binary(d.ws.got_binary());
d.ws.async_write(d.db.data(),
d.strand.wrap(std::move(*this)));
return;
}
}
private:
void
fail(std::string what, error_code ec)
{
auto& d = *d_;
if(d.server.log_)
if(ec != beast::websocket::error::closed)
d.server.fail("[#" + std::to_string(d.id) +
" " + boost::lexical_cast<std::string>(d.ep) +
"] " + what, ec);
}
};
void
fail(std::string what, error_code ec)
{
if(log_)
{
static std::mutex m;
std::lock_guard<std::mutex> lock{m};
(*log_) << what << ": " <<
ec.message() << std::endl;
}
}
void
on_accept(error_code ec)
{
if(! acceptor_.is_open())
return;
if(ec == boost::asio::error::operation_aborted)
return;
if(ec)
fail("accept", ec);
connection{*this, ep_, std::move(sock_)}.run();
acceptor_.async_accept(sock_, ep_,
std::bind(&async_ssl_echo_server::on_accept, this,
std::placeholders::_1));
}
};
} // websocket
#endif

View File

@@ -19,4 +19,8 @@ add_executable (zlib-tests
inflate_stream.cpp
)
target_link_libraries(zlib-tests Beast ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY})
target_link_libraries(zlib-tests
Beast
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
)

24
test/zlib/Jamfile Normal file
View File

@@ -0,0 +1,24 @@
#
# 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)
#
unit-test zlib-tests :
../../extras/beast/unit_test/main.cpp
zlib-1.2.8/adler32.c
zlib-1.2.8/compress.c
zlib-1.2.8/crc32.c
zlib-1.2.8/deflate.c
zlib-1.2.8/infback.c
zlib-1.2.8/inffast.c
zlib-1.2.8/inflate.c
zlib-1.2.8/inftrees.c
zlib-1.2.8/trees.c
zlib-1.2.8/uncompr.c
zlib-1.2.8/zutil.c
deflate_stream.cpp
error.cpp
inflate_stream.cpp
;