mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
Use async_initiate
This commit is contained in:
@ -4,6 +4,7 @@ Version 217:
|
||||
* RatePolicy documentation
|
||||
* Pass strand to async_accept
|
||||
* Fix file_body_win32
|
||||
* Use async_initiate
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@ -179,9 +179,6 @@ endif()
|
||||
|
||||
include_directories (.)
|
||||
|
||||
# VFALCO FIXME Need this for recent asio changes
|
||||
#add_definitions (-DBOOST_BEAST_NO_FILE_BODY_WIN32=1)
|
||||
|
||||
if (OPENSSL_FOUND)
|
||||
include_directories (${OPENSSL_INCLUDE_DIR})
|
||||
endif()
|
||||
|
@ -47,7 +47,7 @@
|
||||
[link beast.ref.boost__beast__unlimited_rate_policy `unlimited`],
|
||||
or a user-defined
|
||||
[link beast.concepts.RatePolicy ['RatePolicy]]!
|
||||
* [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html [P1322R0]]
|
||||
* [[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html P1322R0]]
|
||||
Put the strand on the socket itself, no more `bind_executor` at call sites!
|
||||
* Base classes
|
||||
[link beast.ref.boost__beast__async_op_base `async_op_base`] and
|
||||
|
@ -68,7 +68,7 @@ namespace http {
|
||||
template<class NextLayer>
|
||||
class icy_stream
|
||||
{
|
||||
template<class, class> class read_op;
|
||||
struct ops;
|
||||
|
||||
NextLayer stream_;
|
||||
bool detect_ = true;
|
||||
|
@ -118,8 +118,11 @@ public:
|
||||
} // detail
|
||||
|
||||
template<class NextLayer>
|
||||
template<class MutableBufferSequence, class Handler>
|
||||
class icy_stream<NextLayer>::read_op
|
||||
struct icy_stream<NextLayer>::ops
|
||||
{
|
||||
|
||||
template<class Buffers, class Handler>
|
||||
class read_op
|
||||
: public beast::stable_async_op_base<Handler,
|
||||
beast::executor_type<icy_stream>>
|
||||
, public net::coroutine
|
||||
@ -127,15 +130,21 @@ class icy_stream<NextLayer>::read_op
|
||||
// VFALCO We need a stable reference to `b`
|
||||
// to pass to asio's read functions.
|
||||
//
|
||||
// VFALCO Why did I do all this rigamarole?
|
||||
// we only need 6 or 8 bytes at most,
|
||||
// this should all just be tucked
|
||||
// away into the icy_stream. We can
|
||||
// simulate a dynamic buffer adaptor
|
||||
// with one or two simple ints.
|
||||
struct data
|
||||
{
|
||||
icy_stream& s;
|
||||
buffers_adaptor<MutableBufferSequence> b;
|
||||
buffers_adaptor<Buffers> b;
|
||||
bool match = false;
|
||||
|
||||
data(
|
||||
icy_stream& s_,
|
||||
MutableBufferSequence const& b_)
|
||||
Buffers const& b_)
|
||||
: s(s_)
|
||||
, b(b_)
|
||||
{
|
||||
@ -149,7 +158,7 @@ public:
|
||||
read_op(
|
||||
Handler_&& h,
|
||||
icy_stream& s,
|
||||
MutableBufferSequence const& b)
|
||||
Buffers const& b)
|
||||
: stable_async_op_base<Handler,
|
||||
beast::executor_type<icy_stream>>(
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
@ -165,7 +174,7 @@ public:
|
||||
{
|
||||
using iterator = net::buffers_iterator<
|
||||
typename beast::dynamic_buffer_ref_wrapper<
|
||||
buffers_adaptor<MutableBufferSequence>>::const_buffers_type>;
|
||||
buffers_adaptor<Buffers>>::const_buffers_type>;
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
if(d_.b.max_size() == 0)
|
||||
@ -272,7 +281,7 @@ public:
|
||||
}
|
||||
{
|
||||
buffers_suffix<beast::detail::buffers_ref<
|
||||
MutableBufferSequence>> dest(
|
||||
Buffers>> dest(
|
||||
boost::in_place_init, d_.b.value());
|
||||
dest.consume(5);
|
||||
detail::buffer_shift(
|
||||
@ -289,6 +298,33 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct run_read_op
|
||||
{
|
||||
template<class ReadHandler, class Buffers>
|
||||
void
|
||||
operator()(
|
||||
ReadHandler&& h,
|
||||
icy_stream& s,
|
||||
Buffers const& b)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<ReadHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"ReadHandler type requirements not met");
|
||||
|
||||
read_op<
|
||||
Buffers,
|
||||
typename std::decay<ReadHandler>::type>(
|
||||
std::forward<ReadHandler>(h), s, b);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class NextLayer>
|
||||
@ -449,14 +485,13 @@ async_read_some(
|
||||
static_assert(net::is_mutable_buffer_sequence<
|
||||
MutableBufferSequence >::value,
|
||||
"MutableBufferSequence type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
read_op<
|
||||
MutableBufferSequence,
|
||||
BOOST_ASIO_HANDLER_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))>(
|
||||
std::move(init.completion_handler), *this, buffers);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
ReadHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
typename ops::run_read_op{},
|
||||
handler,
|
||||
*this,
|
||||
buffers);
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
|
@ -31,20 +31,23 @@ class stream::read_op : public stream::read_op_base
|
||||
|
||||
class lambda
|
||||
{
|
||||
Handler h_;
|
||||
state& s_;
|
||||
Buffers b_;
|
||||
Handler h_;
|
||||
net::executor_work_guard<ex2_type> wg2_;
|
||||
|
||||
public:
|
||||
lambda(lambda&&) = default;
|
||||
lambda(lambda const&) = default;
|
||||
|
||||
template<class DeducedHandler>
|
||||
lambda(state& s, Buffers const& b, DeducedHandler&& h)
|
||||
: s_(s)
|
||||
template<class Handler_>
|
||||
lambda(
|
||||
Handler_&& h,
|
||||
state& s,
|
||||
Buffers const& b)
|
||||
: h_(std::forward<Handler_>(h))
|
||||
, s_(s)
|
||||
, b_(b)
|
||||
, h_(std::forward<DeducedHandler>(h))
|
||||
, wg2_(net::get_associated_executor(
|
||||
h_, s_.ioc.get_executor()))
|
||||
{
|
||||
@ -88,9 +91,11 @@ class stream::read_op : public stream::read_op_base
|
||||
|
||||
public:
|
||||
template<class Handler_>
|
||||
read_op(state& s,
|
||||
Buffers const& b, Handler_&& h)
|
||||
: fn_(s, b, std::forward<Handler_>(h))
|
||||
read_op(
|
||||
Handler_&& h,
|
||||
state& s,
|
||||
Buffers const& b)
|
||||
: fn_(std::forward<Handler_>(h), s, b)
|
||||
, wg1_(s.ioc.get_executor())
|
||||
{
|
||||
}
|
||||
@ -107,6 +112,172 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct stream::run_read_op
|
||||
{
|
||||
template<
|
||||
class ReadHandler,
|
||||
class MutableBufferSequence>
|
||||
void
|
||||
operator()(
|
||||
ReadHandler&& h,
|
||||
std::shared_ptr<state> in_,
|
||||
MutableBufferSequence const& buffers)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<ReadHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"ReadHandler type requirements not met");
|
||||
|
||||
++in_->nread;
|
||||
|
||||
std::unique_lock<std::mutex> lock(in_->m);
|
||||
if(in_->op != nullptr)
|
||||
throw std::logic_error(
|
||||
"in_->op != nullptr");
|
||||
|
||||
// test failure
|
||||
error_code ec;
|
||||
if(in_->fc && in_->fc->fail(ec))
|
||||
{
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(h),
|
||||
ec, std::size_t{0}));
|
||||
return;
|
||||
}
|
||||
|
||||
// A request to read 0 bytes from a stream is a no-op.
|
||||
if(buffer_size(buffers) == 0)
|
||||
{
|
||||
lock.unlock();
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(h),
|
||||
ec, std::size_t{0}));
|
||||
return;
|
||||
}
|
||||
|
||||
// deliver bytes before eof
|
||||
if(buffer_size(in_->b.data()) > 0)
|
||||
{
|
||||
auto n = net::buffer_copy(
|
||||
buffers, in_->b.data(), in_->read_max);
|
||||
in_->b.consume(n);
|
||||
lock.unlock();
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(h),
|
||||
ec, n));
|
||||
return;
|
||||
}
|
||||
|
||||
// deliver error
|
||||
if(in_->code != status::ok)
|
||||
{
|
||||
lock.unlock();
|
||||
ec = net::error::eof;
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(h),
|
||||
ec, std::size_t{0}));
|
||||
return;
|
||||
}
|
||||
|
||||
// complete when bytes available or closed
|
||||
in_->op.reset(
|
||||
new read_op<
|
||||
ReadHandler,
|
||||
MutableBufferSequence>(
|
||||
std::move(h), *in_, buffers));
|
||||
}
|
||||
};
|
||||
|
||||
struct stream::run_write_op
|
||||
{
|
||||
template<
|
||||
class WriteHandler,
|
||||
class ConstBufferSequence>
|
||||
void
|
||||
operator()(
|
||||
WriteHandler&& h,
|
||||
std::shared_ptr<state> in_,
|
||||
std::weak_ptr<state> out_,
|
||||
ConstBufferSequence const& buffers)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<WriteHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"WriteHandler type requirements not met");
|
||||
|
||||
++in_->nwrite;
|
||||
|
||||
// test failure
|
||||
error_code ec;
|
||||
if(in_->fc && in_->fc->fail(ec))
|
||||
{
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(h),
|
||||
ec,
|
||||
std::size_t{0}));
|
||||
return;
|
||||
}
|
||||
|
||||
// A request to read 0 bytes from a stream is a no-op.
|
||||
if(buffer_size(buffers) == 0)
|
||||
{
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(h),
|
||||
ec, std::size_t{0}));
|
||||
return;
|
||||
}
|
||||
|
||||
// connection closed
|
||||
auto out = out_.lock();
|
||||
if(! out)
|
||||
{
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(h),
|
||||
net::error::connection_reset,
|
||||
std::size_t{0}));
|
||||
return;
|
||||
}
|
||||
|
||||
// copy buffers
|
||||
auto n = std::min<std::size_t>(
|
||||
buffer_size(buffers), in_->write_max);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(out->m);
|
||||
n = net::buffer_copy(out->b.prepare(n), buffers);
|
||||
out->b.commit(n);
|
||||
out->notify_read();
|
||||
}
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(h),
|
||||
error_code{},
|
||||
n));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
stream::
|
||||
@ -376,74 +547,13 @@ async_read_some(
|
||||
MutableBufferSequence>::value,
|
||||
"MutableBufferSequence type requirements not met");
|
||||
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
|
||||
++in_->nread;
|
||||
|
||||
std::unique_lock<std::mutex> lock(in_->m);
|
||||
if(in_->op != nullptr)
|
||||
throw std::logic_error(
|
||||
"in_->op != nullptr");
|
||||
|
||||
// test failure
|
||||
error_code ec;
|
||||
if(in_->fc && in_->fc->fail(ec))
|
||||
{
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(init.completion_handler),
|
||||
ec, std::size_t{0}));
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
// A request to read 0 bytes from a stream is a no-op.
|
||||
if(buffer_size(buffers) == 0)
|
||||
{
|
||||
lock.unlock();
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(init.completion_handler),
|
||||
ec, std::size_t{0}));
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
// deliver bytes before eof
|
||||
if(buffer_size(in_->b.data()) > 0)
|
||||
{
|
||||
auto n = net::buffer_copy(
|
||||
buffers, in_->b.data(), in_->read_max);
|
||||
in_->b.consume(n);
|
||||
lock.unlock();
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(init.completion_handler),
|
||||
ec, n));
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
// deliver error
|
||||
if(in_->code != status::ok)
|
||||
{
|
||||
lock.unlock();
|
||||
ec = net::error::eof;
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(init.completion_handler),
|
||||
ec, std::size_t{0}));
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
// complete when bytes available or closed
|
||||
in_->op.reset(new read_op<BOOST_ASIO_HANDLER_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t)),
|
||||
MutableBufferSequence>{*in_, buffers,
|
||||
std::move(init.completion_handler)});
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
ReadHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
run_read_op{},
|
||||
handler,
|
||||
in_,
|
||||
buffers);
|
||||
}
|
||||
|
||||
template<class ConstBufferSequence>
|
||||
@ -509,70 +619,22 @@ template<class ConstBufferSequence, class WriteHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
WriteHandler, void(error_code, std::size_t))
|
||||
stream::
|
||||
async_write_some(ConstBufferSequence const& buffers,
|
||||
async_write_some(
|
||||
ConstBufferSequence const& buffers,
|
||||
WriteHandler&& handler)
|
||||
{
|
||||
static_assert(net::is_const_buffer_sequence<
|
||||
ConstBufferSequence>::value,
|
||||
"ConstBufferSequence type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code, std::size_t));
|
||||
|
||||
++in_->nwrite;
|
||||
|
||||
// test failure
|
||||
error_code ec;
|
||||
if(in_->fc && in_->fc->fail(ec))
|
||||
{
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(init.completion_handler),
|
||||
ec,
|
||||
std::size_t{0}));
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
// A request to read 0 bytes from a stream is a no-op.
|
||||
if(buffer_size(buffers) == 0)
|
||||
{
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(init.completion_handler),
|
||||
ec, std::size_t{0}));
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
// connection closed
|
||||
auto out = out_.lock();
|
||||
if(! out)
|
||||
{
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(init.completion_handler),
|
||||
net::error::connection_reset,
|
||||
std::size_t{0}));
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
// copy buffers
|
||||
auto n = std::min<std::size_t>(
|
||||
buffer_size(buffers), in_->write_max);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(out->m);
|
||||
n = net::buffer_copy(out->b.prepare(n), buffers);
|
||||
out->b.commit(n);
|
||||
out->notify_read();
|
||||
}
|
||||
net::post(
|
||||
in_->ioc.get_executor(),
|
||||
beast::bind_front_handler(
|
||||
std::move(init.completion_handler),
|
||||
error_code{}, n));
|
||||
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
run_write_op{},
|
||||
handler,
|
||||
in_,
|
||||
out_,
|
||||
buffers);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -105,6 +105,9 @@ class stream
|
||||
template<class Handler, class Buffers>
|
||||
class read_op;
|
||||
|
||||
struct run_read_op;
|
||||
struct run_write_op;
|
||||
|
||||
enum class status
|
||||
{
|
||||
ok,
|
||||
|
@ -95,8 +95,7 @@ class buffered_read_stream
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
|
||||
template<class Buffers, class Handler>
|
||||
class read_some_op;
|
||||
struct ops;
|
||||
|
||||
DynamicBuffer buffer_;
|
||||
std::size_t capacity_ = 0;
|
||||
|
@ -26,6 +26,9 @@ static std::size_t constexpr default_max_stack_buffer = 16384;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
struct dynamic_read_ops
|
||||
{
|
||||
|
||||
// read into a dynamic buffer until the
|
||||
// condition is met or an error occurs
|
||||
template<
|
||||
@ -46,19 +49,19 @@ class read_op
|
||||
public:
|
||||
read_op(read_op&&) = default;
|
||||
|
||||
template<class Handler_>
|
||||
template<class Handler_, class Condition_>
|
||||
read_op(
|
||||
Handler_&& h,
|
||||
Stream& s,
|
||||
DynamicBuffer& b,
|
||||
Condition cond,
|
||||
Handler_&& h)
|
||||
Condition_&& cond)
|
||||
: async_op_base<Handler,
|
||||
beast::executor_type<Stream>>(
|
||||
std::forward<Handler_>(h),
|
||||
s.get_executor())
|
||||
, s_(s)
|
||||
, b_(b)
|
||||
, cond_(cond)
|
||||
, cond_(std::forward<Condition_>(cond))
|
||||
{
|
||||
(*this)({}, 0, false);
|
||||
}
|
||||
@ -100,16 +103,16 @@ public:
|
||||
// EXPERIMENTAL
|
||||
// optimized non-blocking read algorithm
|
||||
template<
|
||||
class Protocol,
|
||||
class Protocol, class Executor,
|
||||
class DynamicBuffer,
|
||||
class Condition,
|
||||
class Handler>
|
||||
class read_non_blocking_op
|
||||
: public net::coroutine
|
||||
, public async_op_base<Handler,
|
||||
beast::executor_type<net::basic_stream_socket<Protocol>>>
|
||||
, public async_op_base<Handler, Executor>
|
||||
{
|
||||
net::basic_stream_socket<Protocol>& s_;
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& s_;
|
||||
DynamicBuffer& b_;
|
||||
Condition cond_;
|
||||
std::size_t limit_;
|
||||
@ -119,18 +122,18 @@ public:
|
||||
read_non_blocking_op(read_non_blocking_op&&) = default;
|
||||
read_non_blocking_op(read_non_blocking_op const&) = delete;
|
||||
|
||||
template<class Handler_>
|
||||
template<class Handler_, class Condition_>
|
||||
read_non_blocking_op(
|
||||
net::basic_stream_socket<Protocol>& s,
|
||||
Handler_&& h,
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& s,
|
||||
DynamicBuffer& b,
|
||||
Condition cond,
|
||||
Handler_&& h)
|
||||
: async_op_base<Handler, beast::executor_type<
|
||||
net::basic_stream_socket<Protocol>>>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
Condition cond)
|
||||
: async_op_base<Handler, Executor>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
, s_(s)
|
||||
, b_(b)
|
||||
, cond_(cond)
|
||||
, cond_(std::forward<Condition_>(cond))
|
||||
{
|
||||
(*this)({}, false);
|
||||
}
|
||||
@ -198,92 +201,91 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<
|
||||
class AsyncReadStream,
|
||||
class DynamicBuffer,
|
||||
class CompletionCondition,
|
||||
class ReadHandler,
|
||||
class>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))
|
||||
async_read(
|
||||
AsyncReadStream& stream,
|
||||
DynamicBuffer& buffer,
|
||||
CompletionCondition cond,
|
||||
ReadHandler&& handler)
|
||||
struct run_read_op
|
||||
{
|
||||
static_assert(is_async_read_stream<AsyncReadStream>::value,
|
||||
"AsyncReadStream type requirements not met");
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
static_assert(
|
||||
detail::is_invocable<CompletionCondition,
|
||||
void(error_code&, std::size_t, DynamicBuffer&)>::value,
|
||||
"CompletionCondition type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
detail::read_op<
|
||||
AsyncReadStream,
|
||||
DynamicBuffer,
|
||||
CompletionCondition,
|
||||
BOOST_ASIO_HANDLER_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))>(
|
||||
stream, buffer, std::move(cond),
|
||||
std::move(init.completion_handler));
|
||||
return init.result.get();
|
||||
}
|
||||
template<
|
||||
class AsyncReadStream,
|
||||
class DynamicBuffer,
|
||||
class Condition,
|
||||
class ReadHandler>
|
||||
void
|
||||
operator()(
|
||||
ReadHandler&& h,
|
||||
AsyncReadStream& s,
|
||||
DynamicBuffer& b,
|
||||
Condition&& c)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
#ifdef BOOST_BEAST_ENABLE_NON_BLOCKING
|
||||
template<
|
||||
class Protocol,
|
||||
class DynamicBuffer,
|
||||
class CompletionCondition,
|
||||
class ReadHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))
|
||||
async_read(
|
||||
net::basic_stream_socket<Protocol>& socket,
|
||||
DynamicBuffer& buffer,
|
||||
CompletionCondition cond,
|
||||
ReadHandler&& handler)
|
||||
{
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
static_assert(
|
||||
detail::is_invocable<CompletionCondition,
|
||||
void(error_code&, std::size_t, DynamicBuffer&)>::value,
|
||||
"CompletionCondition type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
if(socket.non_blocking())
|
||||
{
|
||||
detail::read_non_blocking_op<
|
||||
Protocol,
|
||||
static_assert(
|
||||
beast::detail::is_invocable<ReadHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"ReadHandler type requirements not met");
|
||||
|
||||
read_op<
|
||||
AsyncReadStream,
|
||||
DynamicBuffer,
|
||||
CompletionCondition,
|
||||
BOOST_ASIO_HANDLER_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))>(
|
||||
socket, buffer, std::move(cond),
|
||||
std::move(init.completion_handler));
|
||||
typename std::decay<Condition>::type,
|
||||
typename std::decay<ReadHandler>::type>(
|
||||
std::forward<ReadHandler>(h),
|
||||
s,
|
||||
b,
|
||||
std::forward<Condition>(c));
|
||||
}
|
||||
else
|
||||
|
||||
#if BOOST_BEAST_ENABLE_NON_BLOCKING
|
||||
template<
|
||||
class Protocol, class Executor,
|
||||
class DynamicBuffer,
|
||||
class Condition,
|
||||
class ReadHandler>
|
||||
void
|
||||
operator()(
|
||||
net::basic_stream_socket<Protocol, Executor>& s,
|
||||
DynamicBuffer& b,
|
||||
Condition&& c,
|
||||
ReadHandler&& h)
|
||||
{
|
||||
detail::read_op<
|
||||
decltype(socket),
|
||||
DynamicBuffer,
|
||||
CompletionCondition,
|
||||
BOOST_ASIO_HANDLER_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))>(
|
||||
socket, buffer, std::move(cond),
|
||||
std::move(init.completion_handler));
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<ReadHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"ReadHandler type requirements not met");
|
||||
|
||||
if(s.non_blocking())
|
||||
{
|
||||
read_non_blocking_op<
|
||||
Protocol, Executor,
|
||||
DynamicBuffer,
|
||||
typename std::decay<Condition>::type,
|
||||
typename std::decay<ReadHandler>::type>(
|
||||
std::forward<ReadHandler>(h),
|
||||
s,
|
||||
b,
|
||||
std::forward<Condition>(c));
|
||||
}
|
||||
else
|
||||
{
|
||||
read_op<
|
||||
net::basic_stream_socket<Protocol, Executor>,
|
||||
DynamicBuffer,
|
||||
typename std::decay<Condition>::type,
|
||||
typename std::decay<ReadHandler>::type>(
|
||||
std::forward<ReadHandler>(h),
|
||||
s,
|
||||
b,
|
||||
std::forward<Condition>(c));
|
||||
}
|
||||
}
|
||||
return init.result.get();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -444,6 +446,39 @@ read(
|
||||
}
|
||||
#endif
|
||||
|
||||
template<
|
||||
class AsyncReadStream,
|
||||
class DynamicBuffer,
|
||||
class CompletionCondition,
|
||||
class ReadHandler,
|
||||
class>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))
|
||||
async_read(
|
||||
AsyncReadStream& stream,
|
||||
DynamicBuffer& buffer,
|
||||
CompletionCondition&& cond,
|
||||
ReadHandler&& handler)
|
||||
{
|
||||
static_assert(is_async_read_stream<AsyncReadStream>::value,
|
||||
"AsyncReadStream type requirements not met");
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
static_assert(
|
||||
detail::is_invocable<CompletionCondition,
|
||||
void(error_code&, std::size_t, DynamicBuffer&)>::value,
|
||||
"CompletionCondition type requirements not met");
|
||||
return net::async_initiate<
|
||||
ReadHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
typename dynamic_read_ops::run_read_op{},
|
||||
handler,
|
||||
stream,
|
||||
buffer,
|
||||
std::forward<CompletionCondition>(cond));
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
@ -235,7 +235,7 @@ BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
async_read(
|
||||
AsyncReadStream& stream,
|
||||
DynamicBuffer& buffer,
|
||||
CompletionCondition completion_condition,
|
||||
CompletionCondition&& completion_condition,
|
||||
ReadHandler&& handler);
|
||||
|
||||
} // detail
|
||||
|
@ -124,20 +124,6 @@ struct is_contiguous_container<T, E, void_t<
|
||||
>::type>>: std::true_type
|
||||
{};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* If this static assert goes off, it means that the completion
|
||||
handler you provided to an asynchronous initiating function did
|
||||
not have the right signature. Check the parameter types for your
|
||||
completion handler and make sure they match the list of types
|
||||
expected by the initiating function,
|
||||
*/
|
||||
#define BOOST_BEAST_HANDLER_INIT(type, sig) \
|
||||
static_assert(::boost::beast::detail::is_invocable< \
|
||||
BOOST_ASIO_HANDLER_TYPE(type, sig), sig>::value, \
|
||||
"CompletionHandler type requirements not met"); \
|
||||
::boost::beast::net::async_completion<type, sig> init{handler}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
@ -90,13 +90,13 @@ class flat_stream
|
||||
: private detail::flat_stream_base
|
||||
#endif
|
||||
{
|
||||
template<class> class write_op;
|
||||
|
||||
NextLayer stream_;
|
||||
flat_buffer buffer_;
|
||||
|
||||
BOOST_STATIC_ASSERT(has_get_executor<NextLayer>::value);
|
||||
|
||||
struct ops;
|
||||
|
||||
template<class ConstBufferSequence>
|
||||
std::size_t
|
||||
stack_write_some(
|
||||
|
@ -539,16 +539,17 @@ struct run_read_op
|
||||
operator()(
|
||||
ReadHandler&& h,
|
||||
basic_stream& s,
|
||||
Buffers const& b
|
||||
)
|
||||
Buffers const& b)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for a ReadHandler.
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
detail::is_invocable<ReadHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"ReadHandler type requirements not met");
|
||||
|
||||
transfer_op<
|
||||
true,
|
||||
Buffers,
|
||||
@ -568,11 +569,13 @@ struct run_write_op
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for a WriteHandler.
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
detail::is_invocable<WriteHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"WriteHandler type requirements not met");
|
||||
|
||||
transfer_op<
|
||||
false,
|
||||
Buffers,
|
||||
@ -592,11 +595,13 @@ struct run_connect_op
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for a ConnectHandler.
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
detail::is_invocable<ConnectHandler,
|
||||
void(error_code)>::value,
|
||||
"ConnectHandler type requirements not met");
|
||||
|
||||
connect_op<typename std::decay<ConnectHandler>::type>(
|
||||
std::forward<ConnectHandler>(h), s, ep);
|
||||
}
|
||||
@ -617,11 +622,13 @@ struct run_connect_range_op
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for a RangeConnectHandler.
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
detail::is_invocable<RangeConnectHandler,
|
||||
void(error_code, typename Protocol::endpoint)>::value,
|
||||
"RangeConnectHandler type requirements not met");
|
||||
|
||||
connect_op<typename std::decay<RangeConnectHandler>::type>(
|
||||
std::forward<RangeConnectHandler>(h), s, eps, cond);
|
||||
}
|
||||
@ -642,11 +649,13 @@ struct run_connect_iter_op
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for a IteratorConnectHandler.
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
detail::is_invocable<IteratorConnectHandler,
|
||||
void(error_code, Iterator)>::value,
|
||||
"IteratorConnectHandler type requirements not met");
|
||||
|
||||
connect_op<typename std::decay<IteratorConnectHandler>::type>(
|
||||
std::forward<IteratorConnectHandler>(h), s, begin, end, cond);
|
||||
}
|
||||
|
@ -22,23 +22,26 @@
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
|
||||
|
||||
template<class Stream, class DynamicBuffer>
|
||||
struct buffered_read_stream<Stream, DynamicBuffer>::ops
|
||||
{
|
||||
|
||||
template<class MutableBufferSequence, class Handler>
|
||||
class buffered_read_stream<
|
||||
Stream, DynamicBuffer>::read_some_op
|
||||
: public async_op_base<
|
||||
Handler, beast::executor_type<buffered_read_stream>>
|
||||
class read_op
|
||||
: public async_op_base<Handler,
|
||||
beast::executor_type<buffered_read_stream>>
|
||||
{
|
||||
buffered_read_stream& s_;
|
||||
MutableBufferSequence b_;
|
||||
int step_ = 0;
|
||||
|
||||
public:
|
||||
read_some_op(read_some_op&&) = default;
|
||||
read_some_op(read_some_op const&) = delete;
|
||||
read_op(read_op&&) = default;
|
||||
read_op(read_op const&) = delete;
|
||||
|
||||
template<class Handler_>
|
||||
read_some_op(
|
||||
read_op(
|
||||
Handler_&& h,
|
||||
buffered_read_stream& s,
|
||||
MutableBufferSequence const& b)
|
||||
@ -56,6 +59,7 @@ public:
|
||||
error_code ec,
|
||||
std::size_t bytes_transferred)
|
||||
{
|
||||
// VFALCO TODO Rewrite this using reenter/yield
|
||||
switch(step_)
|
||||
{
|
||||
case 0:
|
||||
@ -99,6 +103,35 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct run_read_op
|
||||
{
|
||||
template<class ReadHandler, class Buffers>
|
||||
void
|
||||
operator()(
|
||||
ReadHandler&& h,
|
||||
buffered_read_stream& s,
|
||||
Buffers const& b)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<ReadHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"ReadHandler type requirements not met");
|
||||
|
||||
read_op<
|
||||
Buffers,
|
||||
typename std::decay<ReadHandler>::type>(
|
||||
std::forward<ReadHandler>(h),
|
||||
s,
|
||||
b);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Stream, class DynamicBuffer>
|
||||
@ -198,12 +231,13 @@ async_read_some(
|
||||
if(buffer_.size() == 0 && capacity_ == 0)
|
||||
return next_layer_.async_read_some(buffers,
|
||||
std::forward<ReadHandler>(handler));
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
read_some_op<MutableBufferSequence, BOOST_ASIO_HANDLER_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))>(
|
||||
std::move(init.completion_handler), *this, buffers);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
ReadHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
typename ops::run_read_op{},
|
||||
handler,
|
||||
*this,
|
||||
buffers);
|
||||
}
|
||||
|
||||
} // beast
|
||||
|
@ -23,8 +23,11 @@ namespace boost {
|
||||
namespace beast {
|
||||
|
||||
template<class NextLayer>
|
||||
struct flat_stream<NextLayer>::ops
|
||||
{
|
||||
|
||||
template<class Handler>
|
||||
class flat_stream<NextLayer>::write_op
|
||||
class write_op
|
||||
: public async_op_base<Handler,
|
||||
beast::executor_type<flat_stream>>
|
||||
, public net::coroutine
|
||||
@ -34,9 +37,9 @@ public:
|
||||
class ConstBufferSequence,
|
||||
class Handler_>
|
||||
write_op(
|
||||
Handler_&& h,
|
||||
flat_stream<NextLayer>& s,
|
||||
ConstBufferSequence const& b,
|
||||
Handler_&& h)
|
||||
ConstBufferSequence const& b)
|
||||
: async_op_base<Handler,
|
||||
beast::executor_type<flat_stream>>(
|
||||
std::forward<Handler_>(h),
|
||||
@ -72,6 +75,34 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct run_write_op
|
||||
{
|
||||
template<class WriteHandler, class Buffers>
|
||||
void
|
||||
operator()(
|
||||
WriteHandler&& h,
|
||||
flat_stream& s,
|
||||
Buffers const& b)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<WriteHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"WriteHandler type requirements not met");
|
||||
|
||||
write_op<
|
||||
typename std::decay<WriteHandler>::type>(
|
||||
std::forward<WriteHandler>(h),
|
||||
s,
|
||||
b);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class NextLayer>
|
||||
@ -212,12 +243,13 @@ async_write_some(
|
||||
static_assert(net::is_const_buffer_sequence<
|
||||
ConstBufferSequence>::value,
|
||||
"ConstBufferSequence type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code, std::size_t));
|
||||
write_op<BOOST_ASIO_HANDLER_TYPE(
|
||||
WriteHandler, void(error_code, std::size_t))>(
|
||||
*this, buffers, std::move(init.completion_handler));
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
typename ops::run_write_op{},
|
||||
handler,
|
||||
*this,
|
||||
buffers);
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
|
@ -32,7 +32,7 @@ namespace beast {
|
||||
namespace http {
|
||||
|
||||
namespace detail {
|
||||
template<class, class, class, bool, class>
|
||||
template<class, class, bool, class, class>
|
||||
class write_some_win32_op;
|
||||
} // detail
|
||||
|
||||
@ -52,7 +52,7 @@ struct basic_file_body<file_win32>
|
||||
friend class reader;
|
||||
friend struct basic_file_body<file_win32>;
|
||||
|
||||
template<class, class, class, bool, class>
|
||||
template<class, class, bool, class, class>
|
||||
friend class detail::write_some_win32_op;
|
||||
template<
|
||||
class Protocol, class Executor,
|
||||
@ -102,7 +102,7 @@ struct basic_file_body<file_win32>
|
||||
|
||||
class writer
|
||||
{
|
||||
template<class, class, class, bool, class>
|
||||
template<class, class, bool, class, class>
|
||||
friend class detail::write_some_win32_op;
|
||||
template<
|
||||
class Protocol, class Executor,
|
||||
@ -328,7 +328,8 @@ public:
|
||||
|
||||
template<
|
||||
class Protocol, class Executor,
|
||||
class Handler, bool isRequest, class Fields>
|
||||
bool isRequest, class Fields,
|
||||
class Handler>
|
||||
class write_some_win32_op
|
||||
: public beast::async_op_base<Handler, Executor>
|
||||
{
|
||||
@ -433,6 +434,39 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct run_write_some_win32_op
|
||||
{
|
||||
template<
|
||||
class Protocol, class Executor,
|
||||
bool isRequest, class Fields,
|
||||
class WriteHandler>
|
||||
void
|
||||
operator()(
|
||||
WriteHandler&& h,
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& s,
|
||||
serializer<isRequest,
|
||||
basic_file_body<file_win32>, Fields>& sr)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<WriteHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"WriteHandler type requirements not met");
|
||||
|
||||
write_some_win32_op<
|
||||
Protocol, Executor,
|
||||
isRequest, Fields,
|
||||
typename std::decay<WriteHandler>::type>(
|
||||
std::forward<WriteHandler>(h),
|
||||
s,
|
||||
sr);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // detail
|
||||
@ -520,17 +554,14 @@ async_write_some(
|
||||
serializer<isRequest,
|
||||
basic_file_body<file_win32>, Fields>& sr,
|
||||
WriteHandler&& handler)
|
||||
{
|
||||
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code, std::size_t));
|
||||
detail::write_some_win32_op<
|
||||
Protocol, Executor,
|
||||
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
|
||||
void(error_code, std::size_t)),
|
||||
isRequest, Fields>{
|
||||
std::move(init.completion_handler), sock, sr}();
|
||||
return init.result.get();
|
||||
{
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
detail::run_write_some_win32_op{},
|
||||
handler,
|
||||
sock,
|
||||
sr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -179,10 +179,10 @@ class read_msg_op
|
||||
public:
|
||||
template<class Handler_>
|
||||
read_msg_op(
|
||||
Handler_&& h,
|
||||
Stream& s,
|
||||
DynamicBuffer& b,
|
||||
message_type& m,
|
||||
Handler_&& h)
|
||||
message_type& m)
|
||||
: stable_async_op_base<
|
||||
Handler, beast::executor_type<Stream>>(
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
@ -203,6 +203,42 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct run_read_msg_op
|
||||
{
|
||||
template<
|
||||
class ReadHandler,
|
||||
class AsyncReadStream,
|
||||
class DynamicBuffer,
|
||||
bool isRequest, class Body, class Allocator>
|
||||
void
|
||||
operator()(
|
||||
ReadHandler&& h,
|
||||
AsyncReadStream& s,
|
||||
DynamicBuffer& b,
|
||||
message<isRequest, Body,
|
||||
basic_fields<Allocator>>& m)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<ReadHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"ReadHandler type requirements not met");
|
||||
|
||||
read_msg_op<
|
||||
AsyncReadStream,
|
||||
DynamicBuffer,
|
||||
isRequest, Body, Allocator,
|
||||
typename std::decay<ReadHandler>::type>(
|
||||
std::forward<ReadHandler>(h),
|
||||
s,
|
||||
b,
|
||||
m);
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -266,19 +302,12 @@ async_read_some(
|
||||
basic_parser<isRequest, Derived>& parser,
|
||||
ReadHandler&& handler)
|
||||
{
|
||||
static_assert(
|
||||
is_async_read_stream<AsyncReadStream>::value,
|
||||
"AsyncReadStream type requirements not met");
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
beast::detail::async_read(stream, buffer,
|
||||
return beast::detail::async_read(
|
||||
stream,
|
||||
buffer,
|
||||
detail::read_some_condition<
|
||||
isRequest, Derived>{parser}, std::move(
|
||||
init.completion_handler));
|
||||
return init.result.get();
|
||||
isRequest, Derived>{parser},
|
||||
std::forward<ReadHandler>(handler));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -343,20 +372,13 @@ async_read_header(
|
||||
basic_parser<isRequest, Derived>& parser,
|
||||
ReadHandler&& handler)
|
||||
{
|
||||
static_assert(
|
||||
is_async_read_stream<AsyncReadStream>::value,
|
||||
"AsyncReadStream type requirements not met");
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
parser.eager(false);
|
||||
beast::detail::async_read(stream, buffer,
|
||||
return beast::detail::async_read(
|
||||
stream,
|
||||
buffer,
|
||||
detail::read_header_condition<
|
||||
isRequest, Derived>{parser}, std::move(
|
||||
init.completion_handler));
|
||||
return init.result.get();
|
||||
isRequest, Derived>{parser},
|
||||
std::forward<ReadHandler>(handler));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -427,14 +449,13 @@ async_read(
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
parser.eager(true);
|
||||
beast::detail::async_read(stream, buffer,
|
||||
return beast::detail::async_read(
|
||||
stream,
|
||||
buffer,
|
||||
detail::read_all_condition<
|
||||
isRequest, Derived>{parser}, std::move(
|
||||
init.completion_handler));
|
||||
return init.result.get();
|
||||
isRequest, Derived>{parser},
|
||||
std::forward<ReadHandler>(handler));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -521,17 +542,14 @@ async_read(
|
||||
"Body type requirements not met");
|
||||
static_assert(is_body_reader<Body>::value,
|
||||
"BodyReader type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
detail::read_msg_op<
|
||||
AsyncReadStream,
|
||||
DynamicBuffer,
|
||||
isRequest, Body, Allocator,
|
||||
BOOST_ASIO_HANDLER_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))>(
|
||||
stream, buffer, msg, std::move(
|
||||
init.completion_handler));
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
ReadHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
detail::run_read_msg_op{},
|
||||
handler,
|
||||
stream,
|
||||
buffer,
|
||||
msg);
|
||||
}
|
||||
|
||||
} // http
|
||||
|
@ -30,7 +30,8 @@ namespace http {
|
||||
namespace detail {
|
||||
|
||||
template<
|
||||
class Stream, class Handler,
|
||||
class Handler,
|
||||
class Stream,
|
||||
bool isRequest, class Body, class Fields>
|
||||
class write_some_op
|
||||
: public beast::async_op_base<
|
||||
@ -150,7 +151,9 @@ struct serializer_is_done
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<
|
||||
class Stream, class Handler, class Predicate,
|
||||
class Handler,
|
||||
class Stream,
|
||||
class Predicate,
|
||||
bool isRequest, class Body, class Fields>
|
||||
class write_op
|
||||
: public beast::async_op_base<
|
||||
@ -211,7 +214,8 @@ public:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<
|
||||
class Stream, class Handler,
|
||||
class Handler,
|
||||
class Stream,
|
||||
bool isRequest, class Body, class Fields>
|
||||
class write_msg_op
|
||||
: public beast::stable_async_op_base<
|
||||
@ -225,8 +229,8 @@ public:
|
||||
class Handler_,
|
||||
class... Args>
|
||||
write_msg_op(
|
||||
Stream& s,
|
||||
Handler_&& h,
|
||||
Stream& s,
|
||||
Args&&... args)
|
||||
: stable_async_op_base<
|
||||
Handler, beast::executor_type<Stream>>(
|
||||
@ -253,6 +257,138 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct run_write_some_op
|
||||
{
|
||||
template<
|
||||
class WriteHandler,
|
||||
class Stream,
|
||||
bool isRequest, class Body, class Fields>
|
||||
void
|
||||
operator()(
|
||||
WriteHandler&& h,
|
||||
Stream& s,
|
||||
serializer<isRequest, Body, Fields>& sr)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<WriteHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"WriteHandler type requirements not met");
|
||||
|
||||
write_some_op<
|
||||
typename std::decay<WriteHandler>::type,
|
||||
Stream,
|
||||
isRequest, Body, Fields>(
|
||||
std::forward<WriteHandler>(h),
|
||||
s,
|
||||
sr);
|
||||
}
|
||||
};
|
||||
|
||||
struct run_write_op
|
||||
{
|
||||
template<
|
||||
class WriteHandler,
|
||||
class Stream,
|
||||
class Predicate,
|
||||
bool isRequest, class Body, class Fields>
|
||||
void
|
||||
operator()(
|
||||
WriteHandler&& h,
|
||||
Stream& s,
|
||||
Predicate const&,
|
||||
serializer<isRequest, Body, Fields>& sr)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<WriteHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"WriteHandler type requirements not met");
|
||||
|
||||
write_op<
|
||||
typename std::decay<WriteHandler>::type,
|
||||
Stream,
|
||||
Predicate,
|
||||
isRequest, Body, Fields>(
|
||||
std::forward<WriteHandler>(h),
|
||||
s,
|
||||
sr);
|
||||
}
|
||||
};
|
||||
|
||||
struct run_write_msg_op
|
||||
{
|
||||
template<
|
||||
class WriteHandler,
|
||||
class Stream,
|
||||
bool isRequest, class Body, class Fields,
|
||||
class... Args>
|
||||
void
|
||||
operator()(
|
||||
WriteHandler&& h,
|
||||
Stream& s,
|
||||
message<isRequest, Body, Fields>& m,
|
||||
std::false_type,
|
||||
Args&&... args)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<WriteHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"WriteHandler type requirements not met");
|
||||
|
||||
write_msg_op<
|
||||
typename std::decay<WriteHandler>::type,
|
||||
Stream,
|
||||
isRequest, Body, Fields>(
|
||||
std::forward<WriteHandler>(h),
|
||||
s,
|
||||
m,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<
|
||||
class WriteHandler,
|
||||
class Stream,
|
||||
bool isRequest, class Body, class Fields,
|
||||
class... Args>
|
||||
void
|
||||
operator()(
|
||||
WriteHandler&& h,
|
||||
Stream& s,
|
||||
message<isRequest, Body, Fields> const& m,
|
||||
std::true_type,
|
||||
Args&&... args)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<WriteHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"WriteHandler type requirements not met");
|
||||
|
||||
write_msg_op<
|
||||
typename std::decay<WriteHandler>::type,
|
||||
Stream,
|
||||
isRequest, Body, Fields>(
|
||||
std::forward<WriteHandler>(h),
|
||||
s,
|
||||
m,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Stream>
|
||||
@ -341,15 +477,13 @@ async_write_some_impl(
|
||||
serializer<isRequest, Body, Fields>& sr,
|
||||
WriteHandler&& handler)
|
||||
{
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code, std::size_t));
|
||||
detail::write_some_op<
|
||||
AsyncWriteStream,
|
||||
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
|
||||
void(error_code, std::size_t)),
|
||||
isRequest, Body, Fields>(
|
||||
std::move(init.completion_handler), stream, sr);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
run_write_some_op{},
|
||||
handler,
|
||||
stream,
|
||||
sr);
|
||||
}
|
||||
|
||||
} // detail
|
||||
@ -498,16 +632,14 @@ async_write_header(
|
||||
static_assert(is_body_writer<Body>::value,
|
||||
"BodyWriter type requirements not met");
|
||||
sr.split(true);
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code, std::size_t));
|
||||
detail::write_op<
|
||||
AsyncWriteStream,
|
||||
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
|
||||
void(error_code, std::size_t)),
|
||||
detail::serializer_is_header_done,
|
||||
isRequest, Body, Fields>{
|
||||
std::move(init.completion_handler), stream, sr};
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
detail::run_write_op{},
|
||||
handler,
|
||||
stream,
|
||||
detail::serializer_is_header_done{},
|
||||
sr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -574,16 +706,14 @@ async_write(
|
||||
static_assert(is_body_writer<Body>::value,
|
||||
"BodyWriter type requirements not met");
|
||||
sr.split(false);
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code, std::size_t));
|
||||
detail::write_op<
|
||||
AsyncWriteStream,
|
||||
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
|
||||
void(error_code, std::size_t)),
|
||||
detail::serializer_is_done,
|
||||
isRequest, Body, Fields>{
|
||||
std::move(init.completion_handler), stream, sr};
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
detail::run_write_op{},
|
||||
handler,
|
||||
stream,
|
||||
detail::serializer_is_done{},
|
||||
sr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -698,15 +828,14 @@ async_write(
|
||||
"Body type requirements not met");
|
||||
static_assert(is_body_writer<Body>::value,
|
||||
"BodyWriter type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code, std::size_t));
|
||||
detail::write_msg_op<
|
||||
AsyncWriteStream,
|
||||
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
|
||||
void(error_code, std::size_t)),
|
||||
isRequest, Body, Fields>(stream,
|
||||
std::move(init.completion_handler), msg);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
detail::run_write_msg_op{},
|
||||
handler,
|
||||
stream,
|
||||
msg,
|
||||
std::false_type{});
|
||||
}
|
||||
|
||||
template<
|
||||
@ -729,15 +858,14 @@ async_write(
|
||||
"Body type requirements not met");
|
||||
static_assert(is_body_writer<Body>::value,
|
||||
"BodyWriter type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code, std::size_t));
|
||||
detail::write_msg_op<
|
||||
AsyncWriteStream,
|
||||
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
|
||||
void(error_code, std::size_t)),
|
||||
isRequest, Body, Fields>(stream,
|
||||
std::move(init.completion_handler), msg);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
detail::run_write_msg_op{},
|
||||
handler,
|
||||
stream,
|
||||
msg,
|
||||
std::true_type{});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -241,7 +241,7 @@ public:
|
||||
// read and respond to an upgrade request
|
||||
//
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
template<class Decorator, class Handler>
|
||||
template<class Handler, class Decorator>
|
||||
class stream<NextLayer, deflateSupported>::accept_op
|
||||
: public beast::stable_async_op_base<
|
||||
Handler, beast::executor_type<stream>>
|
||||
@ -256,8 +256,8 @@ public:
|
||||
accept_op(
|
||||
Handler_&& h,
|
||||
boost::shared_ptr<impl_type> const& sp,
|
||||
Buffers const& buffers,
|
||||
Decorator const& decorator)
|
||||
Decorator const& decorator,
|
||||
Buffers const& buffers)
|
||||
: stable_async_op_base<Handler,
|
||||
beast::executor_type<stream>>(
|
||||
std::forward<Handler_>(h),
|
||||
@ -325,6 +325,74 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
struct stream<NextLayer, deflateSupported>::
|
||||
run_response_op
|
||||
{
|
||||
template<
|
||||
class AcceptHandler,
|
||||
class Body, class Allocator,
|
||||
class Decorator>
|
||||
void
|
||||
operator()(
|
||||
AcceptHandler&& h,
|
||||
boost::shared_ptr<impl_type> const& sp,
|
||||
http::request<Body,
|
||||
http::basic_fields<Allocator>> const& m,
|
||||
Decorator const& d)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<AcceptHandler,
|
||||
void(error_code)>::value,
|
||||
"AcceptHandler type requirements not met");
|
||||
|
||||
response_op<
|
||||
typename std::decay<AcceptHandler>::type>(
|
||||
std::forward<AcceptHandler>(h),
|
||||
sp,
|
||||
m,
|
||||
d);
|
||||
}
|
||||
};
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
struct stream<NextLayer, deflateSupported>::
|
||||
run_accept_op
|
||||
{
|
||||
template<
|
||||
class AcceptHandler,
|
||||
class Decorator,
|
||||
class Buffers>
|
||||
void
|
||||
operator()(
|
||||
AcceptHandler&& h,
|
||||
boost::shared_ptr<impl_type> const& sp,
|
||||
Decorator const& d,
|
||||
Buffers const& b)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<AcceptHandler,
|
||||
void(error_code)>::value,
|
||||
"AcceptHandler type requirements not met");
|
||||
|
||||
accept_op<
|
||||
typename std::decay<AcceptHandler>::type,
|
||||
Decorator>(
|
||||
std::forward<AcceptHandler>(h),
|
||||
sp,
|
||||
d,
|
||||
b);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -488,17 +556,15 @@ async_accept(
|
||||
{
|
||||
static_assert(is_async_stream<next_layer_type>::value,
|
||||
"AsyncStream type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
AcceptHandler, void(error_code));
|
||||
impl_->reset();
|
||||
accept_op<
|
||||
decltype(&default_decorate_res),
|
||||
BOOST_ASIO_HANDLER_TYPE(
|
||||
AcceptHandler, void(error_code))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, net::const_buffer{},
|
||||
&default_decorate_res);;
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
AcceptHandler,
|
||||
void(error_code)>(
|
||||
run_accept_op{},
|
||||
handler,
|
||||
impl_,
|
||||
&default_decorate_res,
|
||||
net::const_buffer{});
|
||||
}
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -517,17 +583,15 @@ async_accept_ex(
|
||||
static_assert(detail::is_response_decorator<
|
||||
ResponseDecorator>::value,
|
||||
"ResponseDecorator requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
AcceptHandler, void(error_code));
|
||||
impl_->reset();
|
||||
accept_op<
|
||||
ResponseDecorator,
|
||||
BOOST_ASIO_HANDLER_TYPE(
|
||||
AcceptHandler, void(error_code))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, net::const_buffer{},
|
||||
decorator);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
AcceptHandler,
|
||||
void(error_code)>(
|
||||
run_accept_op{},
|
||||
handler,
|
||||
impl_,
|
||||
decorator,
|
||||
net::const_buffer{});
|
||||
}
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -548,16 +612,15 @@ async_accept(
|
||||
static_assert(net::is_const_buffer_sequence<
|
||||
ConstBufferSequence>::value,
|
||||
"ConstBufferSequence type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
AcceptHandler, void(error_code));
|
||||
impl_->reset();
|
||||
accept_op<
|
||||
decltype(&default_decorate_res),
|
||||
BOOST_ASIO_HANDLER_TYPE(
|
||||
AcceptHandler, void(error_code))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, buffers, &default_decorate_res);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
AcceptHandler,
|
||||
void(error_code)>(
|
||||
run_accept_op{},
|
||||
handler,
|
||||
impl_,
|
||||
&default_decorate_res,
|
||||
buffers);
|
||||
}
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -583,16 +646,15 @@ async_accept_ex(
|
||||
static_assert(detail::is_response_decorator<
|
||||
ResponseDecorator>::value,
|
||||
"ResponseDecorator requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
AcceptHandler, void(error_code));
|
||||
impl_->reset();
|
||||
accept_op<
|
||||
ResponseDecorator,
|
||||
BOOST_ASIO_HANDLER_TYPE(
|
||||
AcceptHandler, void(error_code))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, buffers, decorator);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
AcceptHandler,
|
||||
void(error_code)>(
|
||||
run_accept_op{},
|
||||
handler,
|
||||
impl_,
|
||||
decorator,
|
||||
buffers);
|
||||
}
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -608,15 +670,15 @@ async_accept(
|
||||
{
|
||||
static_assert(is_async_stream<next_layer_type>::value,
|
||||
"AsyncStream type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
AcceptHandler, void(error_code));
|
||||
impl_->reset();
|
||||
response_op<
|
||||
BOOST_ASIO_HANDLER_TYPE(
|
||||
AcceptHandler, void(error_code))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, req, &default_decorate_res);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
AcceptHandler,
|
||||
void(error_code)>(
|
||||
run_response_op{},
|
||||
handler,
|
||||
impl_,
|
||||
req,
|
||||
&default_decorate_res);
|
||||
}
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -637,15 +699,15 @@ async_accept_ex(
|
||||
static_assert(detail::is_response_decorator<
|
||||
ResponseDecorator>::value,
|
||||
"ResponseDecorator requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
AcceptHandler, void(error_code));
|
||||
impl_->reset();
|
||||
response_op<
|
||||
BOOST_ASIO_HANDLER_TYPE(
|
||||
AcceptHandler, void(error_code))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, req, decorator);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
AcceptHandler,
|
||||
void(error_code)>(
|
||||
run_response_op{},
|
||||
handler,
|
||||
impl_,
|
||||
req,
|
||||
decorator);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -230,6 +230,34 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
struct stream<NextLayer, deflateSupported>::
|
||||
run_close_op
|
||||
{
|
||||
template<class CloseHandler>
|
||||
void
|
||||
operator()(
|
||||
CloseHandler&& h,
|
||||
boost::shared_ptr<impl_type> const& sp,
|
||||
close_reason const& cr)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<CloseHandler,
|
||||
void(error_code)>::value,
|
||||
"CloseHandler type requirements not met");
|
||||
|
||||
close_op<
|
||||
typename std::decay<CloseHandler>::type>(
|
||||
std::forward<CloseHandler>(h),
|
||||
sp,
|
||||
cr);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -360,12 +388,13 @@ async_close(close_reason const& cr, CloseHandler&& handler)
|
||||
{
|
||||
static_assert(is_async_stream<next_layer_type>::value,
|
||||
"AsyncStream type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
CloseHandler, void(error_code));
|
||||
close_op<BOOST_ASIO_HANDLER_TYPE(
|
||||
CloseHandler, void(error_code))>(
|
||||
std::move(init.completion_handler), impl_, cr);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
CloseHandler,
|
||||
void(error_code)>(
|
||||
run_close_op{},
|
||||
handler,
|
||||
impl_,
|
||||
cr);
|
||||
}
|
||||
|
||||
} // websocket
|
||||
|
@ -74,6 +74,7 @@ public:
|
||||
d_.req = sp->build_request(
|
||||
key_, host, target, decorator);
|
||||
sp->reset(); // VFALCO I don't like this
|
||||
(*this)({}, 0, false);
|
||||
}
|
||||
|
||||
void
|
||||
@ -157,6 +158,37 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
struct stream<NextLayer, deflateSupported>::
|
||||
run_handshake_op
|
||||
{
|
||||
template<class HandshakeHandler, class Decorator>
|
||||
void operator()(
|
||||
HandshakeHandler&& h,
|
||||
boost::shared_ptr<impl_type> const& sp,
|
||||
response_type* r,
|
||||
string_view host, string_view target,
|
||||
Decorator const& d)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<HandshakeHandler,
|
||||
void(error_code)>::value,
|
||||
"HandshakeHandler type requirements not met");
|
||||
|
||||
handshake_op<
|
||||
typename std::decay<HandshakeHandler>::type>(
|
||||
std::forward<HandshakeHandler>(h),
|
||||
sp,
|
||||
r,
|
||||
host, target,
|
||||
d);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -241,14 +273,15 @@ async_handshake(string_view host,
|
||||
{
|
||||
static_assert(is_async_stream<next_layer_type>::value,
|
||||
"AsyncStream type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
HandshakeHandler, void(error_code));
|
||||
handshake_op<BOOST_ASIO_HANDLER_TYPE(
|
||||
HandshakeHandler, void(error_code))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, nullptr, host, target,
|
||||
&default_decorate_req)();
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
HandshakeHandler,
|
||||
void(error_code)>(
|
||||
run_handshake_op{},
|
||||
handler,
|
||||
impl_,
|
||||
nullptr,
|
||||
host, target,
|
||||
&default_decorate_req);
|
||||
}
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -263,14 +296,15 @@ async_handshake(response_type& res,
|
||||
{
|
||||
static_assert(is_async_stream<next_layer_type>::value,
|
||||
"AsyncStream type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
HandshakeHandler, void(error_code));
|
||||
handshake_op<BOOST_ASIO_HANDLER_TYPE(
|
||||
HandshakeHandler, void(error_code))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, &res, host, target,
|
||||
&default_decorate_req)();
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
HandshakeHandler,
|
||||
void(error_code)>(
|
||||
run_handshake_op{},
|
||||
handler,
|
||||
impl_,
|
||||
&res,
|
||||
host, target,
|
||||
&default_decorate_req);
|
||||
}
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -442,14 +476,15 @@ async_handshake_ex(string_view host,
|
||||
static_assert(detail::is_request_decorator<
|
||||
RequestDecorator>::value,
|
||||
"RequestDecorator requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
HandshakeHandler, void(error_code));
|
||||
handshake_op<BOOST_ASIO_HANDLER_TYPE(
|
||||
HandshakeHandler, void(error_code))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, nullptr, host, target,
|
||||
decorator)();
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
HandshakeHandler,
|
||||
void(error_code)>(
|
||||
run_handshake_op{},
|
||||
handler,
|
||||
impl_,
|
||||
nullptr,
|
||||
host, target,
|
||||
decorator);
|
||||
}
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -472,19 +507,17 @@ async_handshake_ex(response_type& res,
|
||||
static_assert(detail::is_request_decorator<
|
||||
RequestDecorator>::value,
|
||||
"RequestDecorator requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
HandshakeHandler, void(error_code));
|
||||
handshake_op<BOOST_ASIO_HANDLER_TYPE(
|
||||
HandshakeHandler, void(error_code))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, &res, host, target,
|
||||
decorator)();
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
HandshakeHandler,
|
||||
void(error_code)>(
|
||||
run_handshake_op{},
|
||||
handler,
|
||||
impl_,
|
||||
&res,
|
||||
host, target,
|
||||
decorator);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // websocket
|
||||
} // beast
|
||||
} // boost
|
||||
|
@ -200,6 +200,36 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
struct stream<NextLayer, deflateSupported>::
|
||||
run_ping_op
|
||||
{
|
||||
template<class WriteHandler>
|
||||
void
|
||||
operator()(
|
||||
WriteHandler&& h,
|
||||
boost::shared_ptr<impl_type> const& sp,
|
||||
detail::opcode op,
|
||||
ping_data const& p)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<WriteHandler,
|
||||
void(error_code)>::value,
|
||||
"WriteHandler type requirements not met");
|
||||
|
||||
ping_op<
|
||||
typename std::decay<WriteHandler>::type>(
|
||||
std::forward<WriteHandler>(h),
|
||||
sp,
|
||||
op,
|
||||
p);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -263,13 +293,14 @@ async_ping(ping_data const& payload, WriteHandler&& handler)
|
||||
{
|
||||
static_assert(is_async_stream<next_layer_type>::value,
|
||||
"AsyncStream type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code));
|
||||
ping_op<BOOST_ASIO_HANDLER_TYPE(
|
||||
WriteHandler, void(error_code))>(
|
||||
std::move(init.completion_handler), impl_,
|
||||
detail::opcode::ping, payload);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code)>(
|
||||
run_ping_op{},
|
||||
handler,
|
||||
impl_,
|
||||
detail::opcode::ping,
|
||||
payload);
|
||||
}
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -281,13 +312,14 @@ async_pong(ping_data const& payload, WriteHandler&& handler)
|
||||
{
|
||||
static_assert(is_async_stream<next_layer_type>::value,
|
||||
"AsyncStream type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code));
|
||||
ping_op<BOOST_ASIO_HANDLER_TYPE(
|
||||
WriteHandler, void(error_code))>(
|
||||
std::move(init.completion_handler), impl_,
|
||||
detail::opcode::pong, payload);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code)>(
|
||||
run_ping_op{},
|
||||
handler,
|
||||
impl_,
|
||||
detail::opcode::pong,
|
||||
payload);
|
||||
}
|
||||
|
||||
} // websocket
|
||||
|
@ -43,9 +43,7 @@ namespace websocket {
|
||||
Also reads and handles control frames.
|
||||
*/
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
template<
|
||||
class MutableBufferSequence,
|
||||
class Handler>
|
||||
template<class Handler, class MutableBufferSequence>
|
||||
class stream<NextLayer, deflateSupported>::read_some_op
|
||||
: public beast::async_op_base<
|
||||
Handler, beast::executor_type<stream>>
|
||||
@ -613,9 +611,7 @@ public:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
template<
|
||||
class DynamicBuffer,
|
||||
class Handler>
|
||||
template<class Handler, class DynamicBuffer>
|
||||
class stream<NextLayer, deflateSupported>::read_op
|
||||
: public beast::async_op_base<
|
||||
Handler, beast::executor_type<stream>>
|
||||
@ -674,7 +670,7 @@ public:
|
||||
|
||||
// VFALCO TODO use boost::beast::bind_continuation
|
||||
BOOST_ASIO_CORO_YIELD
|
||||
read_some_op<mutable_buffers_type, read_op>(
|
||||
read_some_op<read_op, mutable_buffers_type>(
|
||||
std::move(*this), sp, *mb);
|
||||
b_.commit(bytes_transferred);
|
||||
bytes_written_ += bytes_transferred;
|
||||
@ -689,6 +685,72 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
struct stream<NextLayer, deflateSupported>::
|
||||
run_read_some_op
|
||||
{
|
||||
template<
|
||||
class ReadHandler,
|
||||
class MutableBufferSequence>
|
||||
void
|
||||
operator()(
|
||||
ReadHandler&& h,
|
||||
boost::shared_ptr<impl_type> const& sp,
|
||||
MutableBufferSequence const& b)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<ReadHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"ReadHandler type requirements not met");
|
||||
|
||||
read_some_op<
|
||||
typename std::decay<ReadHandler>::type,
|
||||
MutableBufferSequence>(
|
||||
std::forward<ReadHandler>(h),
|
||||
sp,
|
||||
b);
|
||||
}
|
||||
};
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
struct stream<NextLayer, deflateSupported>::
|
||||
run_read_op
|
||||
{
|
||||
template<
|
||||
class ReadHandler,
|
||||
class DynamicBuffer>
|
||||
void
|
||||
operator()(
|
||||
ReadHandler&& h,
|
||||
boost::shared_ptr<impl_type> const& sp,
|
||||
DynamicBuffer& b,
|
||||
std::size_t limit,
|
||||
bool some)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<ReadHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"ReadHandler type requirements not met");
|
||||
|
||||
read_op<
|
||||
typename std::decay<ReadHandler>::type,
|
||||
DynamicBuffer>(
|
||||
std::forward<ReadHandler>(h),
|
||||
sp,
|
||||
b,
|
||||
limit,
|
||||
some);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -743,13 +805,15 @@ async_read(DynamicBuffer& buffer, ReadHandler&& handler)
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
read_op<DynamicBuffer, BOOST_ASIO_HANDLER_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, buffer, 0, false);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
ReadHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
run_read_op{},
|
||||
handler,
|
||||
impl_,
|
||||
buffer,
|
||||
0,
|
||||
false);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -819,13 +883,15 @@ async_read_some(
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
read_op<DynamicBuffer, BOOST_ASIO_HANDLER_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))>(
|
||||
std::move(init.completion_handler),
|
||||
impl_, buffer, limit, true);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
ReadHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
run_read_op{},
|
||||
handler,
|
||||
impl_,
|
||||
buffer,
|
||||
limit,
|
||||
true);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -1200,12 +1266,13 @@ async_read_some(
|
||||
static_assert(net::is_mutable_buffer_sequence<
|
||||
MutableBufferSequence>::value,
|
||||
"MutableBufferSequence type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
ReadHandler, void(error_code, std::size_t));
|
||||
read_some_op<MutableBufferSequence, BOOST_ASIO_HANDLER_TYPE(
|
||||
ReadHandler, void(error_code, std::size_t))>(
|
||||
std::move(init.completion_handler), impl_, buffers);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
ReadHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
run_read_some_op{},
|
||||
handler,
|
||||
impl_,
|
||||
buffers);
|
||||
}
|
||||
|
||||
} // websocket
|
||||
|
@ -37,7 +37,7 @@ namespace beast {
|
||||
namespace websocket {
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
template<class Buffers, class Handler>
|
||||
template<class Handler, class Buffers>
|
||||
class stream<NextLayer, deflateSupported>::write_some_op
|
||||
: public beast::async_op_base<
|
||||
Handler, beast::executor_type<stream>>
|
||||
@ -430,6 +430,39 @@ operator()(
|
||||
}
|
||||
}
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
struct stream<NextLayer, deflateSupported>::
|
||||
run_write_some_op
|
||||
{
|
||||
template<
|
||||
class WriteHandler,
|
||||
class ConstBufferSequence>
|
||||
void
|
||||
operator()(
|
||||
WriteHandler&& h,
|
||||
boost::shared_ptr<impl_type> const& sp,
|
||||
bool fin,
|
||||
ConstBufferSequence const& b)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<WriteHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"WriteHandler type requirements not met");
|
||||
|
||||
write_some_op<
|
||||
typename std::decay<WriteHandler>::type,
|
||||
ConstBufferSequence>(
|
||||
std::forward<WriteHandler>(h),
|
||||
sp,
|
||||
fin,
|
||||
b);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class NextLayer, bool deflateSupported>
|
||||
@ -676,12 +709,14 @@ async_write_some(bool fin,
|
||||
static_assert(net::is_const_buffer_sequence<
|
||||
ConstBufferSequence>::value,
|
||||
"ConstBufferSequence type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code, std::size_t));
|
||||
write_some_op<ConstBufferSequence, BOOST_ASIO_HANDLER_TYPE(
|
||||
WriteHandler, void(error_code, std::size_t))>(
|
||||
std::move(init.completion_handler), impl_, fin, bs);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
run_write_some_op{},
|
||||
handler,
|
||||
impl_,
|
||||
fin,
|
||||
bs);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -731,12 +766,14 @@ async_write(
|
||||
static_assert(net::is_const_buffer_sequence<
|
||||
ConstBufferSequence>::value,
|
||||
"ConstBufferSequence type requirements not met");
|
||||
BOOST_BEAST_HANDLER_INIT(
|
||||
WriteHandler, void(error_code, std::size_t));
|
||||
write_some_op<ConstBufferSequence, BOOST_ASIO_HANDLER_TYPE(
|
||||
WriteHandler, void(error_code, std::size_t))>(
|
||||
std::move(init.completion_handler), impl_, true, bs);
|
||||
return init.result.get();
|
||||
return net::async_initiate<
|
||||
WriteHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
run_write_some_op{},
|
||||
handler,
|
||||
impl_,
|
||||
true,
|
||||
bs);
|
||||
}
|
||||
|
||||
} // websocket
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <boost/beast/websocket/detail/hybi13.hpp>
|
||||
#include <boost/beast/websocket/detail/impl_base.hpp>
|
||||
#include <boost/beast/websocket/detail/pmd_extension.hpp>
|
||||
#include <boost/beast/core/stream_traits.hpp>
|
||||
#include <boost/beast/core/string.hpp>
|
||||
#include <boost/beast/core/detail/type_traits.hpp>
|
||||
#include <boost/beast/http/detail/type_traits.hpp>
|
||||
@ -127,6 +128,16 @@ class stream
|
||||
: private stream_base
|
||||
#endif
|
||||
{
|
||||
struct impl_type;
|
||||
|
||||
boost::shared_ptr<impl_type> impl_;
|
||||
|
||||
using time_point = typename
|
||||
std::chrono::steady_clock::time_point;
|
||||
|
||||
using control_cb_type =
|
||||
std::function<void(frame_type, string_view)>;
|
||||
|
||||
friend class close_test;
|
||||
friend class frame_test;
|
||||
friend class ping_test;
|
||||
@ -142,16 +153,6 @@ class stream
|
||||
static std::size_t constexpr max_control_frame_size = 2 + 8 + 4 + 125;
|
||||
static std::size_t constexpr tcp_frame_size = 1536;
|
||||
|
||||
using control_cb_type =
|
||||
std::function<void(frame_type, string_view)>;
|
||||
|
||||
struct impl_type;
|
||||
|
||||
boost::shared_ptr<impl_type> impl_;
|
||||
|
||||
using time_point = typename
|
||||
std::chrono::steady_clock::time_point;
|
||||
|
||||
static time_point never() noexcept
|
||||
{
|
||||
return (time_point::max)();
|
||||
@ -167,7 +168,8 @@ public:
|
||||
typename std::remove_reference<NextLayer>::type;
|
||||
|
||||
/// The type of the executor associated with the object.
|
||||
using executor_type = typename next_layer_type::executor_type;
|
||||
using executor_type =
|
||||
beast::executor_type<next_layer_type>;
|
||||
|
||||
/** Destructor
|
||||
|
||||
@ -2636,6 +2638,17 @@ private:
|
||||
template<class, class> class write_some_op;
|
||||
template<class, class> class write_op;
|
||||
|
||||
struct run_accept_op;
|
||||
struct run_close_op;
|
||||
struct run_handshake_op;
|
||||
struct run_ping_op;
|
||||
struct run_idle_ping_op;
|
||||
struct run_read_some_op;
|
||||
struct run_read_op;
|
||||
struct run_response_op;
|
||||
struct run_write_some_op;
|
||||
struct run_write_op;
|
||||
|
||||
static void default_decorate_req(request_type&) {}
|
||||
static void default_decorate_res(response_type&) {}
|
||||
|
||||
|
@ -211,33 +211,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
testAsioHandlerInvoke()
|
||||
{
|
||||
// make sure things compile, also can set a
|
||||
// breakpoint in asio_handler_invoke to make sure
|
||||
// it is instantiated.
|
||||
net::io_context ioc;
|
||||
net::strand<
|
||||
net::io_context::executor_type> s(
|
||||
ioc.get_executor());
|
||||
test::stream ts{ioc};
|
||||
buffered_read_stream<
|
||||
test::stream&, multi_buffer> brs(ts);
|
||||
brs.async_read_some(net::mutable_buffer{},
|
||||
net::bind_executor(
|
||||
s, copyable_handler{}));
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
testSpecialMembers();
|
||||
|
||||
yield_to([&](yield_context yield){
|
||||
testRead(yield);});
|
||||
yield_to([&](yield_context yield)
|
||||
{
|
||||
testRead(yield);
|
||||
});
|
||||
|
||||
testAsyncLoop();
|
||||
testAsioHandlerInvoke();
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user