|
|
|
|
@@ -41,7 +41,7 @@ namespace detail {
|
|
|
|
|
|
|
|
|
|
template<class _>
|
|
|
|
|
void
|
|
|
|
|
stream_base::prepare_fh(close_code& code)
|
|
|
|
|
stream_base::prepare_fh(close_code::value& code)
|
|
|
|
|
{
|
|
|
|
|
// continuation without an active message
|
|
|
|
|
if(! rd_cont_ && rd_fh_.op == opcode::cont)
|
|
|
|
|
@@ -170,11 +170,20 @@ template<class NextLayer>
|
|
|
|
|
template<class... Args>
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
stream(Args&&... args)
|
|
|
|
|
: next_layer_(std::forward<Args>(args)...)
|
|
|
|
|
, stream_(next_layer_)
|
|
|
|
|
: stream_(std::forward<Args>(args)...)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_Stream<next_layer_type>::value,
|
|
|
|
|
"Stream requirements not met");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
accept()
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
error_code ec;
|
|
|
|
|
accept(boost::asio::null_buffers{}, ec);
|
|
|
|
|
detail::maybe_throw(ec, "accept");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
@@ -182,6 +191,8 @@ void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
accept(error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
accept(boost::asio::null_buffers{}, ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -192,6 +203,8 @@ typename async_completion<
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
async_accept(AcceptHandler&& handler)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_AsyncStream<next_layer_type>::value,
|
|
|
|
|
"AsyncStream requirements requirements not met");
|
|
|
|
|
return async_accept(boost::asio::null_buffers{},
|
|
|
|
|
std::forward<AcceptHandler>(handler));
|
|
|
|
|
}
|
|
|
|
|
@@ -202,6 +215,8 @@ void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
accept(ConstBufferSequence const& buffers)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
static_assert(is_ConstBufferSequence<
|
|
|
|
|
ConstBufferSequence>::value,
|
|
|
|
|
"ConstBufferSequence requirements not met");
|
|
|
|
|
@@ -216,6 +231,8 @@ void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
accept(ConstBufferSequence const& buffers, error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
static_assert(beast::is_ConstBufferSequence<
|
|
|
|
|
ConstBufferSequence>::value,
|
|
|
|
|
"ConstBufferSequence requirements not met");
|
|
|
|
|
@@ -225,7 +242,7 @@ accept(ConstBufferSequence const& buffers, error_code& ec)
|
|
|
|
|
stream_.buffer().prepare(
|
|
|
|
|
buffer_size(buffers)), buffers));
|
|
|
|
|
http::request<http::empty_body> m;
|
|
|
|
|
http::read(next_layer_, stream_.buffer(), m, ec);
|
|
|
|
|
http::read(next_layer(), stream_.buffer(), m, ec);
|
|
|
|
|
if(ec)
|
|
|
|
|
return;
|
|
|
|
|
accept(m, ec);
|
|
|
|
|
@@ -238,6 +255,8 @@ typename async_completion<
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
async_accept(ConstBufferSequence const& bs, AcceptHandler&& handler)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_AsyncStream<next_layer_type>::value,
|
|
|
|
|
"AsyncStream requirements requirements not met");
|
|
|
|
|
static_assert(beast::is_ConstBufferSequence<
|
|
|
|
|
ConstBufferSequence>::value,
|
|
|
|
|
"ConstBufferSequence requirements not met");
|
|
|
|
|
@@ -255,6 +274,8 @@ void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
accept(http::message<true, Body, Headers> const& request)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
error_code ec;
|
|
|
|
|
accept(request, ec);
|
|
|
|
|
detail::maybe_throw(ec, "accept");
|
|
|
|
|
@@ -267,6 +288,8 @@ stream<NextLayer>::
|
|
|
|
|
accept(http::message<true, Body, Headers> const& req,
|
|
|
|
|
error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
auto resp = build_response(req);
|
|
|
|
|
http::write(stream_, resp, ec);
|
|
|
|
|
if(resp.status != 101)
|
|
|
|
|
@@ -287,6 +310,8 @@ stream<NextLayer>::
|
|
|
|
|
async_accept(http::message<true, Body, Headers> const& req,
|
|
|
|
|
AcceptHandler&& handler)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_AsyncStream<next_layer_type>::value,
|
|
|
|
|
"AsyncStream requirements requirements not met");
|
|
|
|
|
beast::async_completion<
|
|
|
|
|
AcceptHandler, void(error_code)
|
|
|
|
|
> completion(handler);
|
|
|
|
|
@@ -297,19 +322,34 @@ async_accept(http::message<true, Body, Headers> const& req,
|
|
|
|
|
return completion.result.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
handshake(boost::string_ref const& host,
|
|
|
|
|
boost::string_ref const& resource)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
error_code ec;
|
|
|
|
|
handshake(host, resource, ec);
|
|
|
|
|
detail::maybe_throw(ec, "upgrade");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
handshake(boost::string_ref const& host,
|
|
|
|
|
boost::string_ref const& resource, error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
std::string key;
|
|
|
|
|
http::write(stream_,
|
|
|
|
|
build_request(host, resource, key), ec);
|
|
|
|
|
if(ec)
|
|
|
|
|
return;
|
|
|
|
|
http::response<http::string_body> resp;
|
|
|
|
|
http::read(next_layer_, stream_.buffer(), resp, ec);
|
|
|
|
|
http::read(next_layer(), stream_.buffer(), resp, ec);
|
|
|
|
|
if(ec)
|
|
|
|
|
return;
|
|
|
|
|
do_response(resp, key, ec);
|
|
|
|
|
@@ -323,6 +363,8 @@ stream<NextLayer>::
|
|
|
|
|
async_handshake(boost::string_ref const& host,
|
|
|
|
|
boost::string_ref const& resource, HandshakeHandler&& handler)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_AsyncStream<next_layer_type>::value,
|
|
|
|
|
"AsyncStream requirements not met");
|
|
|
|
|
beast::async_completion<
|
|
|
|
|
HandshakeHandler, void(error_code)
|
|
|
|
|
> completion(handler);
|
|
|
|
|
@@ -331,11 +373,25 @@ async_handshake(boost::string_ref const& host,
|
|
|
|
|
return completion.result.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
close(close_reason const& cr)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
error_code ec;
|
|
|
|
|
close(cr, ec);
|
|
|
|
|
detail::maybe_throw(ec, "close");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
close(close_reason const& cr, error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
assert(! wr_close_);
|
|
|
|
|
wr_close_ = true;
|
|
|
|
|
detail::frame_streambuf fb;
|
|
|
|
|
@@ -351,6 +407,8 @@ typename async_completion<
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
async_close(close_reason const& cr, CloseHandler&& handler)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_AsyncStream<next_layer_type>::value,
|
|
|
|
|
"AsyncStream requirements not met");
|
|
|
|
|
beast::async_completion<
|
|
|
|
|
CloseHandler, void(error_code)
|
|
|
|
|
> completion(handler);
|
|
|
|
|
@@ -359,12 +417,27 @@ async_close(close_reason const& cr, CloseHandler&& handler)
|
|
|
|
|
return completion.result.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
template<class Streambuf>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
read(opcode& op, Streambuf& streambuf)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
error_code ec;
|
|
|
|
|
read(op, streambuf, ec);
|
|
|
|
|
detail::maybe_throw(ec, "read");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
template<class Streambuf>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
read(opcode& op, Streambuf& streambuf, error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
frame_info fi;
|
|
|
|
|
for(;;)
|
|
|
|
|
{
|
|
|
|
|
@@ -385,6 +458,8 @@ stream<NextLayer>::
|
|
|
|
|
async_read(opcode& op,
|
|
|
|
|
Streambuf& streambuf, ReadHandler&& handler)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_AsyncStream<next_layer_type>::value,
|
|
|
|
|
"AsyncStream requirements requirements not met");
|
|
|
|
|
static_assert(beast::is_Streambuf<Streambuf>::value,
|
|
|
|
|
"Streambuf requirements not met");
|
|
|
|
|
beast::async_completion<
|
|
|
|
|
@@ -395,13 +470,28 @@ async_read(opcode& op,
|
|
|
|
|
return completion.result.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
template<class Streambuf>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
read_frame(frame_info& fi, Streambuf& streambuf)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
error_code ec;
|
|
|
|
|
read_frame(fi, streambuf, ec);
|
|
|
|
|
detail::maybe_throw(ec, "read_some");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
template<class Streambuf>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
close_code code{};
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
close_code::value code{};
|
|
|
|
|
for(;;)
|
|
|
|
|
{
|
|
|
|
|
if(rd_need_ == 0)
|
|
|
|
|
@@ -409,7 +499,8 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
|
|
|
|
// read header
|
|
|
|
|
detail::frame_streambuf fb;
|
|
|
|
|
do_read_fh(fb, code, ec);
|
|
|
|
|
if((error_ = ec != 0))
|
|
|
|
|
error_ = ec != 0;
|
|
|
|
|
if(error_)
|
|
|
|
|
return;
|
|
|
|
|
if(code != close_code::none)
|
|
|
|
|
break;
|
|
|
|
|
@@ -421,7 +512,8 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
|
|
|
|
auto const mb = fb.prepare(
|
|
|
|
|
static_cast<std::size_t>(rd_fh_.len));
|
|
|
|
|
fb.commit(boost::asio::read(stream_, mb, ec));
|
|
|
|
|
if((error_ = ec != 0))
|
|
|
|
|
error_ = ec != 0;
|
|
|
|
|
if(error_)
|
|
|
|
|
return;
|
|
|
|
|
if(rd_fh_.mask)
|
|
|
|
|
detail::mask_inplace(mb, rd_key_);
|
|
|
|
|
@@ -437,7 +529,8 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
|
|
|
|
write_ping<static_streambuf>(
|
|
|
|
|
fb, opcode::pong, data);
|
|
|
|
|
boost::asio::write(stream_, fb.data(), ec);
|
|
|
|
|
if((error_ = ec != 0))
|
|
|
|
|
error_ = ec != 0;
|
|
|
|
|
if(error_)
|
|
|
|
|
return;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
@@ -445,7 +538,7 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
ping_payload_type data;
|
|
|
|
|
detail::read(data, fb.data(), code);
|
|
|
|
|
if((error_ = ec != 0))
|
|
|
|
|
if(code != close_code::none)
|
|
|
|
|
break;
|
|
|
|
|
// VFALCO How to notify callers using
|
|
|
|
|
// the synchronous interface?
|
|
|
|
|
@@ -466,7 +559,8 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
|
|
|
|
wr_close_ = true;
|
|
|
|
|
write_close<static_streambuf>(fb, cr);
|
|
|
|
|
boost::asio::write(stream_, fb.data(), ec);
|
|
|
|
|
if((error_ = ec != 0))
|
|
|
|
|
error_ = ec != 0;
|
|
|
|
|
if(error_)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
@@ -483,7 +577,8 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
|
|
|
|
detail::clamp(rd_need_));
|
|
|
|
|
auto const bytes_transferred =
|
|
|
|
|
stream_.read_some(smb, ec);
|
|
|
|
|
if((error_ = ec != 0))
|
|
|
|
|
error_ = ec != 0;
|
|
|
|
|
if(error_)
|
|
|
|
|
return;
|
|
|
|
|
rd_need_ -= bytes_transferred;
|
|
|
|
|
auto const pb = prepare_buffers(
|
|
|
|
|
@@ -514,18 +609,20 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
|
|
|
|
detail::frame_streambuf fb;
|
|
|
|
|
write_close<static_streambuf>(fb, code);
|
|
|
|
|
boost::asio::write(stream_, fb.data(), ec);
|
|
|
|
|
if((error_ = ec != 0))
|
|
|
|
|
error_ = ec != 0;
|
|
|
|
|
if(error_)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
wsproto_helpers::call_teardown(next_layer_, ec);
|
|
|
|
|
if((error_ = ec != 0))
|
|
|
|
|
wsproto_helpers::call_teardown(next_layer(), ec);
|
|
|
|
|
error_ = ec != 0;
|
|
|
|
|
if(error_)
|
|
|
|
|
return;
|
|
|
|
|
ec = error::failed;
|
|
|
|
|
error_ = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if(! ec)
|
|
|
|
|
wsproto_helpers::call_teardown(next_layer_, ec);
|
|
|
|
|
wsproto_helpers::call_teardown(next_layer(), ec);
|
|
|
|
|
if(! ec)
|
|
|
|
|
ec = error::closed;
|
|
|
|
|
error_ = ec != 0;
|
|
|
|
|
@@ -539,6 +636,8 @@ stream<NextLayer>::
|
|
|
|
|
async_read_frame(frame_info& fi,
|
|
|
|
|
Streambuf& streambuf, ReadHandler&& handler)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_AsyncStream<next_layer_type>::value,
|
|
|
|
|
"AsyncStream requirements requirements not met");
|
|
|
|
|
static_assert(beast::is_Streambuf<Streambuf>::value,
|
|
|
|
|
"Streambuf requirements not met");
|
|
|
|
|
beast::async_completion<
|
|
|
|
|
@@ -548,12 +647,27 @@ async_read_frame(frame_info& fi,
|
|
|
|
|
return completion.result.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
template<class ConstBufferSequence>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
write(ConstBufferSequence const& buffers)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
error_code ec;
|
|
|
|
|
write(buffers, ec);
|
|
|
|
|
detail::maybe_throw(ec, "write");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
template<class ConstBufferSequence>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
write(ConstBufferSequence const& bs, error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
static_assert(beast::is_ConstBufferSequence<
|
|
|
|
|
ConstBufferSequence>::value,
|
|
|
|
|
"ConstBufferSequence requirements not met");
|
|
|
|
|
@@ -582,6 +696,8 @@ typename async_completion<
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
async_write(ConstBufferSequence const& bs, WriteHandler&& handler)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_AsyncStream<next_layer_type>::value,
|
|
|
|
|
"AsyncStream requirements not met");
|
|
|
|
|
static_assert(beast::is_ConstBufferSequence<
|
|
|
|
|
ConstBufferSequence>::value,
|
|
|
|
|
"ConstBufferSequence requirements not met");
|
|
|
|
|
@@ -592,12 +708,27 @@ async_write(ConstBufferSequence const& bs, WriteHandler&& handler)
|
|
|
|
|
return completion.result.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
template<class ConstBufferSequence>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
write_frame(bool fin, ConstBufferSequence const& buffers)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
error_code ec;
|
|
|
|
|
write_frame(fin, buffers, ec);
|
|
|
|
|
detail::maybe_throw(ec, "write");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
template<class ConstBufferSequence>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
write_frame(bool fin, ConstBufferSequence const& bs, error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_SyncStream<next_layer_type>::value,
|
|
|
|
|
"SyncStream requirements not met");
|
|
|
|
|
static_assert(beast::is_ConstBufferSequence<
|
|
|
|
|
ConstBufferSequence>::value,
|
|
|
|
|
"ConstBufferSequence requirements not met");
|
|
|
|
|
@@ -678,6 +809,8 @@ stream<NextLayer>::
|
|
|
|
|
async_write_frame(bool fin,
|
|
|
|
|
ConstBufferSequence const& bs, WriteHandler&& handler)
|
|
|
|
|
{
|
|
|
|
|
static_assert(is_AsyncStream<next_layer_type>::value,
|
|
|
|
|
"AsyncStream requirements not met");
|
|
|
|
|
static_assert(beast::is_ConstBufferSequence<
|
|
|
|
|
ConstBufferSequence>::value,
|
|
|
|
|
"ConstBufferSequence requirements not met");
|
|
|
|
|
@@ -792,7 +925,7 @@ template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
stream<NextLayer>::
|
|
|
|
|
do_read_fh(detail::frame_streambuf& fb,
|
|
|
|
|
close_code& code, error_code& ec)
|
|
|
|
|
close_code::value& code, error_code& ec)
|
|
|
|
|
{
|
|
|
|
|
fb.commit(boost::asio::read(
|
|
|
|
|
stream_, fb.prepare(2), ec));
|
|
|
|
|
|