mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Update Beast subtree to 1.0.0-b23:
Merge commit '7028579170d83cb81a97478b620f3cb15a2fd693' into develop
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
sudo: false
|
||||
language: cpp
|
||||
|
||||
env:
|
||||
@@ -11,7 +12,7 @@ env:
|
||||
- LCOV_ROOT=$HOME/lcov
|
||||
- VALGRIND_ROOT=$HOME/valgrind-install
|
||||
- BOOST_ROOT=$HOME/boost_1_61_0
|
||||
- BOOST_URL='http://downloads.sourceforge.net/project/boost/boost/1.61.0/boost_1_61_0.tar.gz?use_mirror=netix'
|
||||
- BOOST_URL='http://sourceforge.net/projects/boost/files/boost/1.61.0/boost_1_61_0.tar.gz'
|
||||
packages: &gcc5_pkgs
|
||||
- gcc-5
|
||||
- g++-5
|
||||
@@ -30,7 +31,7 @@ packages: &gcc5_pkgs
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# GCC/Coverage/Autobahn
|
||||
# GCC/Coverage/Autobahn (if master or develop branch)
|
||||
- compiler: gcc
|
||||
env:
|
||||
- GCC_VER=5
|
||||
@@ -77,7 +78,7 @@ before_install:
|
||||
- scripts/install-dependencies.sh
|
||||
|
||||
script:
|
||||
- scripts/build-and-test.sh
|
||||
- travis_retry scripts/build-and-test.sh
|
||||
|
||||
after_script:
|
||||
- cat nohup.out || echo "nohup.out already deleted"
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
1.0.0-b23
|
||||
|
||||
* Tune websocket echo server for performance
|
||||
* Add file and line number to thrown exceptions
|
||||
* Better logging in async echo server
|
||||
* Add copy special members
|
||||
* Fix message constructor and special members
|
||||
* Travis CI improvements
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
1.0.0-b22
|
||||
|
||||
* Fix broken Intellisense
|
||||
|
||||
@@ -253,7 +253,8 @@ private:
|
||||
reference
|
||||
dereference(C<sizeof...(Bn)> const&) const
|
||||
{
|
||||
throw std::logic_error("invalid iterator");
|
||||
throw detail::make_exception<std::logic_error>(
|
||||
"invalid iterator", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
@@ -269,7 +270,8 @@ private:
|
||||
void
|
||||
increment(C<sizeof...(Bn)> const&)
|
||||
{
|
||||
throw std::logic_error("invalid iterator");
|
||||
throw detail::make_exception<std::logic_error>(
|
||||
"invalid iterator", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
@@ -310,7 +312,8 @@ private:
|
||||
--iter<I>();
|
||||
return;
|
||||
}
|
||||
throw std::logic_error("invalid iterator");
|
||||
throw detail::make_exception<std::logic_error>(
|
||||
"invalid iterator", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
@@ -78,6 +80,18 @@ struct repeat_tuple<0, T>
|
||||
using type = std::tuple<>;
|
||||
};
|
||||
|
||||
template<class Exception>
|
||||
Exception
|
||||
make_exception(char const* reason, char const* file, int line)
|
||||
{
|
||||
char const* n = file;
|
||||
for(auto p = file; *p; ++p)
|
||||
if(*p == '\\' || *p == '/')
|
||||
n = p + 1;
|
||||
return Exception{std::string(reason) + " (" +
|
||||
n + ":" + std::to_string(line) + ")"};
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
|
||||
@@ -524,8 +524,8 @@ basic_streambuf<Allocator>::basic_streambuf(
|
||||
, alloc_size_(alloc_size)
|
||||
{
|
||||
if(alloc_size <= 0)
|
||||
throw std::invalid_argument(
|
||||
"basic_streambuf: invalid alloc_size");
|
||||
throw detail::make_exception<std::invalid_argument>(
|
||||
"invalid alloc_size", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_IMPL_BUFFERS_ADAPTER_IPP
|
||||
#define BEAST_IMPL_BUFFERS_ADAPTER_IPP
|
||||
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
@@ -413,8 +414,8 @@ buffers_adapter<MutableBufferSequence>::prepare(std::size_t n) ->
|
||||
}
|
||||
}
|
||||
if(n > 0)
|
||||
throw std::length_error(
|
||||
"no space in buffers_adapter");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"no space", __FILE__, __LINE__);
|
||||
return mutable_buffers_type{*this};
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_IMPL_STATIC_STREAMBUF_IPP
|
||||
#define BEAST_IMPL_STATIC_STREAMBUF_IPP
|
||||
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
@@ -295,7 +296,8 @@ static_streambuf::prepare(std::size_t n) ->
|
||||
mutable_buffers_type
|
||||
{
|
||||
if(n > static_cast<std::size_t>(end_ - out_))
|
||||
throw std::length_error("no space in streambuf");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"no space in streambuf", __FILE__, __LINE__);
|
||||
last_ = out_ + n;
|
||||
return mutable_buffers_type{out_, n};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_WEBSOCKET_STATIC_STRING_HPP
|
||||
#define BEAST_WEBSOCKET_STATIC_STRING_HPP
|
||||
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
@@ -329,7 +330,8 @@ static_string<N, CharT, Traits>::
|
||||
static_string(static_string<M, CharT, Traits> const& s)
|
||||
{
|
||||
if(s.size() > N)
|
||||
throw std::length_error("static_string overflow");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"static_string overflow", __FILE__, __LINE__);
|
||||
n_ = s.size();
|
||||
Traits::copy(&s_[0], &s.s_[0], n_ + 1);
|
||||
}
|
||||
@@ -353,7 +355,8 @@ operator=(static_string<M, CharT, Traits> const& s) ->
|
||||
static_string&
|
||||
{
|
||||
if(s.size() > N)
|
||||
throw std::length_error("static_string overflow");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"static_string overflow", __FILE__, __LINE__);
|
||||
n_ = s.size();
|
||||
Traits::copy(&s_[0], &s.s_[0], n_ + 1);
|
||||
return *this;
|
||||
@@ -391,7 +394,8 @@ at(size_type pos) ->
|
||||
reference
|
||||
{
|
||||
if(pos >= n_)
|
||||
throw std::out_of_range("static_string::at");
|
||||
throw detail::make_exception<std::out_of_range>(
|
||||
"invalid pos", __FILE__, __LINE__);
|
||||
return s_[pos];
|
||||
}
|
||||
|
||||
@@ -402,7 +406,8 @@ at(size_type pos) const ->
|
||||
const_reference
|
||||
{
|
||||
if(pos >= n_)
|
||||
throw std::out_of_range("static_string::at");
|
||||
throw detail::make_exception<std::out_of_range>(
|
||||
"static_string::at", __FILE__, __LINE__);
|
||||
return s_[pos];
|
||||
}
|
||||
|
||||
@@ -412,7 +417,8 @@ static_string<N, CharT, Traits>::
|
||||
resize(std::size_t n)
|
||||
{
|
||||
if(n > N)
|
||||
throw std::length_error("static_string overflow");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"static_string overflow", __FILE__, __LINE__);
|
||||
n_ = n;
|
||||
s_[n_] = 0;
|
||||
}
|
||||
@@ -423,7 +429,8 @@ static_string<N, CharT, Traits>::
|
||||
resize(std::size_t n, CharT c)
|
||||
{
|
||||
if(n > N)
|
||||
throw std::length_error("static_string overflow");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"static_string overflow", __FILE__, __LINE__);
|
||||
if(n > n_)
|
||||
Traits::assign(&s_[n_], n - n_, c);
|
||||
n_ = n;
|
||||
@@ -462,7 +469,8 @@ assign(CharT const* s)
|
||||
{
|
||||
auto const n = Traits::length(s);
|
||||
if(n > N)
|
||||
throw std::out_of_range("too large");
|
||||
throw detail::make_exception<std::out_of_range>(
|
||||
"too large", __FILE__, __LINE__);
|
||||
n_ = n;
|
||||
Traits::copy(&s_[0], s, n_ + 1);
|
||||
}
|
||||
|
||||
@@ -159,6 +159,8 @@ void
|
||||
prepare(message<isRequest, Body, Fields>& msg,
|
||||
Options&&... options)
|
||||
{
|
||||
using beast::detail::make_exception;
|
||||
|
||||
// VFALCO TODO
|
||||
static_assert(is_Body<Body>::value,
|
||||
"Body requirements not met");
|
||||
@@ -174,16 +176,16 @@ prepare(message<isRequest, Body, Fields>& msg,
|
||||
std::forward<Options>(options)...);
|
||||
|
||||
if(msg.fields.exists("Connection"))
|
||||
throw std::invalid_argument(
|
||||
"prepare called with Connection field set");
|
||||
throw make_exception<std::invalid_argument>(
|
||||
"prepare called with Connection field set", __FILE__, __LINE__);
|
||||
|
||||
if(msg.fields.exists("Content-Length"))
|
||||
throw std::invalid_argument(
|
||||
"prepare called with Content-Length field set");
|
||||
throw make_exception<std::invalid_argument>(
|
||||
"prepare called with Content-Length field set", __FILE__, __LINE__);
|
||||
|
||||
if(token_list{msg.fields["Transfer-Encoding"]}.exists("chunked"))
|
||||
throw std::invalid_argument(
|
||||
"prepare called with Transfer-Encoding: chunked set");
|
||||
throw make_exception<std::invalid_argument>(
|
||||
"prepare called with Transfer-Encoding: chunked set", __FILE__, __LINE__);
|
||||
|
||||
if(pi.connection_value != connection::upgrade)
|
||||
{
|
||||
@@ -254,8 +256,8 @@ prepare(message<isRequest, Body, Fields>& msg,
|
||||
// rfc7230 6.7.
|
||||
if(msg.version < 11 && token_list{
|
||||
msg.fields["Connection"]}.exists("upgrade"))
|
||||
throw std::invalid_argument(
|
||||
"invalid version for Connection: upgrade");
|
||||
throw make_exception<std::invalid_argument>(
|
||||
"invalid version for Connection: upgrade", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
} // http
|
||||
|
||||
@@ -246,6 +246,18 @@ struct message : header<isRequest, Fields>
|
||||
/// Default constructor
|
||||
message() = default;
|
||||
|
||||
/// Move constructor
|
||||
message(message&&) = default;
|
||||
|
||||
/// Copy constructor
|
||||
message(message const&) = default;
|
||||
|
||||
/// Move assignment
|
||||
message& operator=(message&&) = default;
|
||||
|
||||
/// Copy assignment
|
||||
message& operator=(message const&) = default;
|
||||
|
||||
/** Construct a message from a header.
|
||||
|
||||
Additional arguments, if any, are forwarded to
|
||||
@@ -281,8 +293,9 @@ struct message : header<isRequest, Fields>
|
||||
*/
|
||||
template<class U
|
||||
#if ! GENERATING_DOCS
|
||||
, class = typename std::enable_if<! std::is_convertible<
|
||||
typename std::decay<U>::type, base_type>::value>
|
||||
, class = typename std::enable_if<
|
||||
! std::is_convertible<typename
|
||||
std::decay<U>::type, base_type>::value>::type
|
||||
#endif
|
||||
>
|
||||
explicit
|
||||
@@ -303,7 +316,7 @@ struct message : header<isRequest, Fields>
|
||||
template<class U, class V
|
||||
#if ! GENERATING_DOCS
|
||||
,class = typename std::enable_if<! std::is_convertible<
|
||||
typename std::decay<U>::type, base_type>::value>
|
||||
typename std::decay<U>::type, base_type>::value>::type
|
||||
#endif
|
||||
>
|
||||
message(U&& u, V&& v)
|
||||
|
||||
@@ -16,6 +16,6 @@
|
||||
//
|
||||
#define BEAST_VERSION 100000
|
||||
|
||||
#define BEAST_VERSION_STRING "1.0.0-b22"
|
||||
#define BEAST_VERSION_STRING "1.0.0-b23"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <beast/core/prepare_buffers.hpp>
|
||||
#include <beast/core/static_streambuf.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <beast/websocket/rfc6455.hpp>
|
||||
#include <beast/websocket/detail/decorator.hpp>
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
@@ -186,7 +187,8 @@ struct message_type
|
||||
message_type(opcode op)
|
||||
{
|
||||
if(op != opcode::binary && op != opcode::text)
|
||||
throw std::domain_error("bad opcode");
|
||||
throw beast::detail::make_exception<std::invalid_argument>(
|
||||
"bad opcode", __FILE__, __LINE__);
|
||||
value = op;
|
||||
}
|
||||
};
|
||||
@@ -277,6 +279,9 @@ struct read_buffer_size
|
||||
read_buffer_size(std::size_t n)
|
||||
: value(n)
|
||||
{
|
||||
if(n < 8)
|
||||
throw beast::detail::make_exception<std::invalid_argument>(
|
||||
"read buffer size is too small", __FILE__, __LINE__);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@@ -356,7 +361,8 @@ struct write_buffer_size
|
||||
: value(n)
|
||||
{
|
||||
if(n < 8)
|
||||
throw std::domain_error("write buffer size is too small");
|
||||
throw beast::detail::make_exception<std::invalid_argument>(
|
||||
"write buffer size is too small", __FILE__, __LINE__);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include <beast/zlib/zlib.hpp>
|
||||
#include <beast/zlib/detail/ranges.hpp>
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <cstdint>
|
||||
@@ -893,14 +894,19 @@ doReset(
|
||||
if(windowBits == 8)
|
||||
windowBits = 9;
|
||||
|
||||
using beast::detail::make_exception;
|
||||
|
||||
if(level < 0 || level > 9)
|
||||
throw std::invalid_argument{"invalid level"};
|
||||
throw make_exception<std::invalid_argument>(
|
||||
"invalid level", __FILE__, __LINE__);
|
||||
|
||||
if(windowBits < 8 || windowBits > 15)
|
||||
throw std::invalid_argument{"invalid windowBits"};
|
||||
throw make_exception<std::invalid_argument>(
|
||||
"invalid windowBits", __FILE__, __LINE__);
|
||||
|
||||
if(memLevel < 1 || memLevel > MAX_MEM_LEVEL)
|
||||
throw std::invalid_argument{"invalid memLevel"};
|
||||
throw make_exception<std::invalid_argument>(
|
||||
"invalid memLevel", __FILE__, __LINE__);
|
||||
|
||||
w_bits_ = windowBits;
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <beast/zlib/detail/bitstream.hpp>
|
||||
#include <beast/zlib/detail/ranges.hpp>
|
||||
#include <beast/zlib/detail/window.hpp>
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
@@ -232,7 +233,8 @@ inflate_stream::
|
||||
doReset(int windowBits)
|
||||
{
|
||||
if(windowBits < 8 || windowBits > 15)
|
||||
throw std::domain_error("windowBits out of range");
|
||||
throw beast::detail::make_exception<std::domain_error>(
|
||||
"windowBits out of range", __FILE__, __LINE__);
|
||||
w_.reset(windowBits);
|
||||
|
||||
bi_.flush();
|
||||
@@ -706,7 +708,8 @@ doWrite(z_params& zs, Flush flush, error_code& ec)
|
||||
|
||||
case SYNC:
|
||||
default:
|
||||
throw std::logic_error("stream error");
|
||||
throw beast::detail::make_exception<std::logic_error>(
|
||||
"stream error", __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -932,8 +935,8 @@ inflate_table(
|
||||
|
||||
auto const not_enough = []
|
||||
{
|
||||
throw std::logic_error(
|
||||
"insufficient output size when inflating tables");
|
||||
throw beast::detail::make_exception<std::logic_error>(
|
||||
"insufficient output size when inflating tables", __FILE__, __LINE__);
|
||||
};
|
||||
|
||||
// check available table space
|
||||
|
||||
@@ -40,6 +40,9 @@ elif [[ $(uname -s) == "Linux" ]]; then
|
||||
if ((${num_proc_units} < ${num_jobs})); then
|
||||
num_jobs=$num_proc_units
|
||||
fi
|
||||
if [[ "${TRAVIS}" == "true" && ${NUM_PROCESSORS:=2} > ${num_jobs} ]]; then
|
||||
num_jobs=$NUM_PROCESSORS
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "using toolset: $CC"
|
||||
@@ -99,10 +102,10 @@ function run_autobahn_test_suite {
|
||||
|
||||
# We need to wait a while so wstest can connect!
|
||||
sleep 5
|
||||
# Show the output (if any) as it is generated
|
||||
tail -f nohup.out &
|
||||
cd scripts && wstest -m fuzzingclient
|
||||
cd ..
|
||||
# Show the output
|
||||
cat nohup.out
|
||||
rm nohup.out
|
||||
# Show what jobs are running
|
||||
jobs
|
||||
@@ -110,6 +113,7 @@ function run_autobahn_test_suite {
|
||||
sleep 5
|
||||
# Kill it gracefully
|
||||
kill -INT %1
|
||||
kill -INT %2
|
||||
# Wait for all the jobs to finish
|
||||
wait
|
||||
# Parse the test results, with python>=2.5<3 script
|
||||
@@ -135,9 +139,10 @@ if [[ $VARIANT == "coverage" ]]; then
|
||||
# Perform test
|
||||
if [[ $MAIN_BRANCH == "1" ]]; then
|
||||
run_tests_with_valgrind
|
||||
run_autobahn_test_suite
|
||||
# skip slow autobahn tests
|
||||
#run_autobahn_test_suite
|
||||
else
|
||||
echo "skipping autobahn tests for feature branch build"
|
||||
echo "skipping autobahn/valgrind tests for feature branch build"
|
||||
run_tests
|
||||
fi
|
||||
|
||||
|
||||
@@ -278,6 +278,19 @@ public:
|
||||
BEAST_EXPECT(m2.fields.exists("h"));
|
||||
}
|
||||
|
||||
void
|
||||
testSpecialMembers()
|
||||
{
|
||||
response<string_body> r1;
|
||||
response<string_body> r2{r1};
|
||||
response<string_body> r3{std::move(r2)};
|
||||
r2 = r3;
|
||||
r1 = std::move(r2);
|
||||
[r1]()
|
||||
{
|
||||
}();
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
testMessage();
|
||||
@@ -285,6 +298,7 @@ public:
|
||||
testFreeFunctions();
|
||||
testPrepare();
|
||||
testSwap();
|
||||
testSpecialMembers();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1416,7 +1416,10 @@ public:
|
||||
yield_to_mf(ep, &stream_test::testAsyncClient);
|
||||
}
|
||||
{
|
||||
async_echo_server server(true, any, 4);
|
||||
error_code ec;
|
||||
async_echo_server server{nullptr, 4};
|
||||
server.open(true, any, ec);
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
auto const ep = server.local_endpoint();
|
||||
testSyncClient(ep);
|
||||
testAsyncWriteFrame(ep);
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace beast {
|
||||
namespace websocket {
|
||||
|
||||
@@ -31,38 +33,24 @@ public:
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
|
||||
private:
|
||||
bool log_ = false;
|
||||
std::ostream* log_;
|
||||
boost::asio::io_service ios_;
|
||||
socket_type sock_;
|
||||
boost::asio::ip::tcp::acceptor acceptor_;
|
||||
std::vector<std::thread> thread_;
|
||||
boost::optional<boost::asio::io_service::work> work_;
|
||||
|
||||
public:
|
||||
async_echo_server(bool server,
|
||||
endpoint_type const& ep, std::size_t threads)
|
||||
: sock_(ios_)
|
||||
async_echo_server(async_echo_server const&) = delete;
|
||||
async_echo_server& operator=(async_echo_server const&) = delete;
|
||||
|
||||
async_echo_server(std::ostream* log,
|
||||
std::size_t threads)
|
||||
: log_(log)
|
||||
, sock_(ios_)
|
||||
, acceptor_(ios_)
|
||||
, work_(ios_)
|
||||
{
|
||||
if(server)
|
||||
{
|
||||
error_code ec;
|
||||
acceptor_.open(ep.protocol(), ec);
|
||||
maybe_throw(ec, "open");
|
||||
acceptor_.set_option(
|
||||
boost::asio::socket_base::reuse_address{true});
|
||||
acceptor_.bind(ep, ec);
|
||||
maybe_throw(ec, "bind");
|
||||
acceptor_.listen(
|
||||
boost::asio::socket_base::max_connections, ec);
|
||||
maybe_throw(ec, "listen");
|
||||
acceptor_.async_accept(sock_,
|
||||
std::bind(&async_echo_server::on_accept, this,
|
||||
beast::asio::placeholders::error));
|
||||
}
|
||||
else
|
||||
{
|
||||
Peer{log_, std::move(sock_), ep};
|
||||
}
|
||||
thread_.reserve(threads);
|
||||
for(std::size_t i = 0; i < threads; ++i)
|
||||
thread_.emplace_back(
|
||||
@@ -71,6 +59,7 @@ public:
|
||||
|
||||
~async_echo_server()
|
||||
{
|
||||
work_ = boost::none;
|
||||
error_code ec;
|
||||
ios_.dispatch(
|
||||
[&]{ acceptor_.close(ec); });
|
||||
@@ -78,6 +67,46 @@ public:
|
||||
t.join();
|
||||
}
|
||||
|
||||
void
|
||||
open(bool server,
|
||||
endpoint_type const& ep, error_code& ec)
|
||||
{
|
||||
if(server)
|
||||
{
|
||||
acceptor_.open(ep.protocol(), ec);
|
||||
if(ec)
|
||||
{
|
||||
if(log_)
|
||||
(*log_) << "open: " << ec.message() << std::endl;
|
||||
return;
|
||||
}
|
||||
acceptor_.set_option(
|
||||
boost::asio::socket_base::reuse_address{true});
|
||||
acceptor_.bind(ep, ec);
|
||||
if(ec)
|
||||
{
|
||||
if(log_)
|
||||
(*log_) << "bind: " << ec.message() << std::endl;
|
||||
return;
|
||||
}
|
||||
acceptor_.listen(
|
||||
boost::asio::socket_base::max_connections, ec);
|
||||
if(ec)
|
||||
{
|
||||
if(log_)
|
||||
(*log_) << "listen: " << ec.message() << std::endl;
|
||||
return;
|
||||
}
|
||||
acceptor_.async_accept(sock_,
|
||||
std::bind(&async_echo_server::on_accept, this,
|
||||
beast::asio::placeholders::error));
|
||||
}
|
||||
else
|
||||
{
|
||||
Peer{*this, std::move(sock_), ep};
|
||||
}
|
||||
}
|
||||
|
||||
endpoint_type
|
||||
local_endpoint() const
|
||||
{
|
||||
@@ -89,7 +118,7 @@ private:
|
||||
{
|
||||
struct data
|
||||
{
|
||||
bool log;
|
||||
async_echo_server& server;
|
||||
int state = 0;
|
||||
boost::optional<endpoint_type> ep;
|
||||
stream<socket_type> ws;
|
||||
@@ -98,8 +127,9 @@ private:
|
||||
beast::streambuf db;
|
||||
int id;
|
||||
|
||||
data(bool log_, socket_type&& sock_)
|
||||
: log(log_)
|
||||
data(async_echo_server& server_,
|
||||
socket_type&& sock_)
|
||||
: server(server_)
|
||||
, ws(std::move(sock_))
|
||||
, strand(ws.get_io_service())
|
||||
, id([]
|
||||
@@ -110,9 +140,9 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
data(bool log_, socket_type&& sock_,
|
||||
endpoint_type const& ep_)
|
||||
: log(log_)
|
||||
data(async_echo_server& server_,
|
||||
socket_type&& sock_, endpoint_type const& ep_)
|
||||
: server(server_)
|
||||
, ep(ep_)
|
||||
, ws(std::move(sock_))
|
||||
, strand(ws.get_io_service())
|
||||
@@ -152,14 +182,17 @@ private:
|
||||
|
||||
template<class... Args>
|
||||
explicit
|
||||
Peer(bool log, socket_type&& sock, Args&&... args)
|
||||
: d_(std::make_shared<data>(log,
|
||||
Peer(async_echo_server& server,
|
||||
socket_type&& sock, Args&&... args)
|
||||
: d_(std::make_shared<data>(server,
|
||||
std::forward<socket_type>(sock),
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
auto& d = *d_;
|
||||
d.ws.set_option(decorate(identity{}));
|
||||
d.ws.set_option(read_message_max(64 * 1024 * 1024));
|
||||
d.ws.set_option(auto_fragment{false});
|
||||
//d.ws.set_option(write_buffer_size{64 * 1024});
|
||||
run();
|
||||
}
|
||||
|
||||
@@ -289,10 +322,10 @@ private:
|
||||
fail(error_code ec, std::string what)
|
||||
{
|
||||
auto& d = *d_;
|
||||
if(d.log)
|
||||
if(d.server.log_)
|
||||
{
|
||||
if(ec != error::closed)
|
||||
std::cerr << "#" << d_->id << " " <<
|
||||
(*d.server.log_) << "#" << d.id << " " <<
|
||||
what << ": " << ec.message() << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -302,7 +335,7 @@ private:
|
||||
fail(error_code ec, std::string what)
|
||||
{
|
||||
if(log_)
|
||||
std::cerr << what << ": " <<
|
||||
(*log_) << what << ": " <<
|
||||
ec.message() << std::endl;
|
||||
}
|
||||
|
||||
@@ -328,7 +361,7 @@ private:
|
||||
acceptor_.async_accept(sock_,
|
||||
std::bind(&async_echo_server::on_accept, this,
|
||||
beast::asio::placeholders::error));
|
||||
Peer{false, std::move(sock)};
|
||||
Peer{*this, std::move(sock)};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,17 +8,27 @@
|
||||
#include "websocket_async_echo_server.hpp"
|
||||
#include "websocket_sync_echo_server.hpp"
|
||||
#include <beast/test/sig_wait.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
||||
using address_type = boost::asio::ip::address;
|
||||
|
||||
beast::websocket::async_echo_server s1(true, endpoint_type{
|
||||
address_type::from_string("127.0.0.1"), 6000 }, 4);
|
||||
try
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
beast::websocket::async_echo_server s1{nullptr, 1};
|
||||
s1.open(true, endpoint_type{
|
||||
address_type::from_string("127.0.0.1"), 6000 }, ec);
|
||||
|
||||
beast::websocket::sync_echo_server s2(true, endpoint_type{
|
||||
address_type::from_string("127.0.0.1"), 6001 });
|
||||
beast::websocket::sync_echo_server s2(true, endpoint_type{
|
||||
address_type::from_string("127.0.0.1"), 6001 });
|
||||
|
||||
beast::test::sig_wait();
|
||||
beast::test::sig_wait();
|
||||
}
|
||||
catch(std::exception const& e)
|
||||
{
|
||||
std::cout << "Error: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user