forked from boostorg/beast
Fixes to support Asio changes (API Change):
This adjusts Beast's interfaces and implementation to match the changes in Boost.Asio.
This commit is contained in:
1 parent
ac24e58fb3
commit
6baa607295
58 files changed
+762
-723
No files matched your search
@@ -11,6 +11,7 @@
|
||||
#define BOOST_BEAST_TEST_TCP_HPP
|
||||
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/beast/core/detail/get_io_context.hpp>
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
#include <boost/beast/_experimental/test/handler.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
@@ -60,26 +61,28 @@ run_for(
|
||||
ioc.restart();
|
||||
}
|
||||
|
||||
/** Connect two TCP/IP sockets together.
|
||||
/** Connect two TCP sockets together.
|
||||
*/
|
||||
inline
|
||||
template<class Executor>
|
||||
bool
|
||||
connect(
|
||||
net::ip::tcp::socket& s1,
|
||||
net::ip::tcp::socket& s2)
|
||||
net::basic_stream_socket<net::ip::tcp, Executor>& s1,
|
||||
net::basic_stream_socket<net::ip::tcp, Executor>& s2)
|
||||
|
||||
{
|
||||
// Sockets must use the same I/O context
|
||||
BOOST_ASSERT(
|
||||
std::addressof(s1.get_executor().context()) ==
|
||||
std::addressof(s2.get_executor().context()));
|
||||
auto& ioc = s1.get_executor().context();
|
||||
s1 = net::ip::tcp::socket(ioc);
|
||||
s2 = net::ip::tcp::socket(ioc);
|
||||
auto ioc1 = beast::detail::get_io_context(s1);
|
||||
auto ioc2 = beast::detail::get_io_context(s2);
|
||||
if(! BEAST_EXPECT(ioc1 != nullptr))
|
||||
return false;
|
||||
if(! BEAST_EXPECT(ioc2 != nullptr))
|
||||
return false;
|
||||
if(! BEAST_EXPECT(ioc1 == ioc2))
|
||||
return false;
|
||||
auto& ioc = *ioc1;
|
||||
try
|
||||
{
|
||||
net::ip::tcp::acceptor a(
|
||||
s1.get_executor().context());
|
||||
net::basic_socket_acceptor<
|
||||
net::ip::tcp, Executor> a(s1.get_executor());
|
||||
auto ep = net::ip::tcp::endpoint(
|
||||
net::ip::make_address_v4("127.0.0.1"), 0);
|
||||
a.open(ep.protocol());
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/beast/core/detail/stream_base.hpp>
|
||||
#include <boost/beast/core/error.hpp>
|
||||
#include <boost/beast/core/stream_traits.hpp>
|
||||
#include <boost/beast/websocket/role.hpp> // VFALCO This is unfortunate
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/basic_stream_socket.hpp>
|
||||
@@ -21,7 +22,6 @@
|
||||
#include <boost/asio/is_executor.hpp>
|
||||
#include <boost/core/empty_value.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <chrono>
|
||||
@@ -42,14 +42,14 @@ namespace beast {
|
||||
/** A stream socket wrapper with timeouts and associated executor.
|
||||
|
||||
This stream wraps a `net::basic_stream_socket` to provide
|
||||
the following additional features:
|
||||
the following features:
|
||||
|
||||
@li Optional timeouts may be specified for each logical asynchronous
|
||||
operation performing any reading, writing, or connecting.
|
||||
|
||||
@li An <em>Executor</em> may be associated with the stream, which will
|
||||
be used to invoke any completion handlers which do not already have
|
||||
an associated executor. This achieves partial support for
|
||||
an associated executor. This achieves support for
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html">[P1322R0] Networking TS enhancement to enable custom I/O executors</a>.
|
||||
|
||||
Although the stream supports multiple concurrent outstanding asynchronous
|
||||
@@ -109,7 +109,7 @@ namespace beast {
|
||||
HTTP response with a different timeout.
|
||||
|
||||
@code
|
||||
void process_http_1 (tcp_stream<net::io_context::executor_type>& stream, net::yield_context yield)
|
||||
void process_http_1 (tcp_stream& stream, net::yield_context yield)
|
||||
{
|
||||
flat_buffer buffer;
|
||||
http::request<http::empty_body> req;
|
||||
@@ -133,7 +133,7 @@ namespace beast {
|
||||
applies to the entire combined operation of reading and writing:
|
||||
|
||||
@code
|
||||
void process_http_2 (tcp_stream<net::io_context::executor_type>& stream, net::yield_context yield)
|
||||
void process_http_2 (tcp_stream& stream, net::yield_context yield)
|
||||
{
|
||||
flat_buffer buffer;
|
||||
http::request<http::empty_body> req;
|
||||
@@ -155,7 +155,7 @@ namespace beast {
|
||||
thusly:
|
||||
|
||||
@code
|
||||
void do_ssl_handshake (net::ssl::stream<tcp_stream<net::io_context::executor_type>>& stream, net::yield_context yield)
|
||||
void do_ssl_handshake (net::ssl::stream<tcp_stream>& stream, net::yield_context yield)
|
||||
{
|
||||
// Require that the SSL handshake take no longer than 10 seconds
|
||||
stream.expires_after(std::chrono::seconds(10));
|
||||
@@ -176,7 +176,8 @@ namespace beast {
|
||||
|
||||
@tparam Executor A type meeting the requirements of <em>Executor</em> to
|
||||
be used for submitting all completion handlers which do not already have an
|
||||
associated executor.
|
||||
associated executor. If this type is omitted, the default of `net::executor`
|
||||
will be used.
|
||||
|
||||
@par Thread Safety
|
||||
<em>Distinct objects</em>: Safe.@n
|
||||
@@ -190,12 +191,33 @@ namespace beast {
|
||||
|
||||
@li <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html">[P1322R0] Networking TS enhancement to enable custom I/O executors</a>.
|
||||
*/
|
||||
template<class Protocol, class Executor>
|
||||
template<
|
||||
class Protocol,
|
||||
class Executor = net::executor>
|
||||
class basic_stream
|
||||
#if ! BOOST_BEAST_DOXYGEN
|
||||
: private detail::stream_base
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
/// The type of the underlying socket.
|
||||
using socket_type =
|
||||
net::basic_stream_socket<Protocol, Executor>;
|
||||
|
||||
/** The type of the executor associated with the stream.
|
||||
|
||||
This will be the type of executor used to invoke completion
|
||||
handlers which do not have an explicit associated executor.
|
||||
*/
|
||||
using executor_type = beast::executor_type<socket_type>;
|
||||
|
||||
/// The protocol type.
|
||||
using protocol_type = Protocol;
|
||||
|
||||
/// The endpoint type.
|
||||
using endpoint_type = typename Protocol::endpoint;
|
||||
|
||||
private:
|
||||
static_assert(net::is_executor<Executor>::value,
|
||||
"Executor requirements not met");
|
||||
|
||||
@@ -206,33 +228,26 @@ public:
|
||||
#endif
|
||||
struct impl_type
|
||||
: boost::enable_shared_from_this<impl_type>
|
||||
, boost::empty_value<Executor>
|
||||
{
|
||||
// must come first
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor> socket;
|
||||
|
||||
op_state read;
|
||||
op_state write;
|
||||
|
||||
net::basic_stream_socket<Protocol> socket;
|
||||
|
||||
impl_type(impl_type&&) = default;
|
||||
|
||||
template<class... Args>
|
||||
explicit
|
||||
impl_type(Executor const&, Args&&...);
|
||||
|
||||
template<class OtherProtocol>
|
||||
impl_type(net::basic_stream_socket<OtherProtocol>&& socket_,
|
||||
std::true_type);
|
||||
|
||||
template<class OtherProtocol>
|
||||
impl_type(net::basic_stream_socket<OtherProtocol>&& socket_,
|
||||
std::false_type);
|
||||
impl_type(Args&&...);
|
||||
|
||||
impl_type& operator=(impl_type&&) = delete;
|
||||
|
||||
Executor const&
|
||||
ex() const noexcept
|
||||
beast::executor_type<socket_type>
|
||||
ex() noexcept
|
||||
{
|
||||
return this->boost::empty_value<Executor>::get();
|
||||
return this->socket.get_executor();
|
||||
}
|
||||
|
||||
void reset(); // set timeouts to never
|
||||
@@ -248,13 +263,6 @@ private:
|
||||
// but the implementation is still waiting on a timer.
|
||||
boost::shared_ptr<impl_type> impl_;
|
||||
|
||||
// Restricted until P1322R0 is incorporated into Boost.Asio.
|
||||
static_assert(
|
||||
std::is_convertible<
|
||||
decltype(std::declval<Executor const&>().context()),
|
||||
net::io_context&>::value,
|
||||
"Only net::io_context is currently supported for executor_type::context()");
|
||||
|
||||
template<bool, class, class> class async_op;
|
||||
|
||||
template<class, class, class>
|
||||
@@ -287,22 +295,6 @@ private:
|
||||
#endif
|
||||
|
||||
public:
|
||||
/** The type of the executor associated with the stream.
|
||||
|
||||
This will be the type of executor used to invoke completion
|
||||
handlers which do not have an explicit associated executor.
|
||||
*/
|
||||
using executor_type = Executor;
|
||||
|
||||
/// The type of the underlying socket.
|
||||
using socket_type = net::basic_stream_socket<Protocol>;
|
||||
|
||||
/// The protocol type.
|
||||
using protocol_type = Protocol;
|
||||
|
||||
/// The endpoint type.
|
||||
using endpoint_type = typename Protocol::endpoint;
|
||||
|
||||
/** Destructor
|
||||
|
||||
This function destroys the stream, cancelling any outstanding
|
||||
@@ -311,106 +303,20 @@ public:
|
||||
*/
|
||||
~basic_stream();
|
||||
|
||||
/** Construct the stream from an execution context.
|
||||
/** Constructor
|
||||
|
||||
This constructor creates the stream from an execution context.
|
||||
The underlying socket needs to be open and connected or accepted
|
||||
before data can be sent or received on it.
|
||||
|
||||
@param ctx An object whose type meets the requirements of
|
||||
<em>ExecutionContext</em>, which the stream will use to dispatch
|
||||
handlers that do not have an explicit associated executor.
|
||||
Currently, the only supported type for `ctx` is `net::io_context`.
|
||||
This constructor creates the stream by forwarding all arguments
|
||||
to the underlying socket. The socket then needs to be open and
|
||||
connected or accepted before data can be sent or received on it.
|
||||
|
||||
@param args A list of parameters forwarded to the constructor of
|
||||
the underlying socket.
|
||||
|
||||
@note This function does not participate in overload resolution unless:
|
||||
|
||||
@li `std::is_convertible<ExecutionContext&, net::execution_context&>::value` is `true`, and
|
||||
|
||||
@li `std::is_constructible<executor_type, typename ExecutionContext::executor_type>::value` is `true`.
|
||||
|
||||
@see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html">[P1322R0] Networking TS enhancement to enable custom I/O executors</a>
|
||||
*/
|
||||
template<
|
||||
class ExecutionContext,
|
||||
class... Args
|
||||
#if ! BOOST_BEAST_DOXYGEN
|
||||
, class = typename std::enable_if<
|
||||
std::is_convertible<
|
||||
ExecutionContext&,
|
||||
net::execution_context&>::value &&
|
||||
std::is_constructible<
|
||||
executor_type,
|
||||
typename ExecutionContext::executor_type>::value
|
||||
>::type
|
||||
#endif
|
||||
>
|
||||
explicit
|
||||
basic_stream(ExecutionContext& ctx, Args&&... args);
|
||||
|
||||
/** Construct the stream from an executor.
|
||||
|
||||
This constructor creates the stream from an executor.
|
||||
The underlying socket needs to be open and connected or accepted
|
||||
before data can be sent or received on it.
|
||||
|
||||
@param ex The executor to use when dispatching handlers that do
|
||||
not have an explicit associated executor.
|
||||
Currently, only executors that return a `net::io_context&` from
|
||||
`ex.context()` are supported.
|
||||
|
||||
@param args A list of parameters forwarded to the constructor of
|
||||
the underlying socket.
|
||||
|
||||
@see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html">[P1322R0] Networking TS enhancement to enable custom I/O executors</a>
|
||||
*/
|
||||
template<class... Args>
|
||||
explicit
|
||||
basic_stream(
|
||||
executor_type const& ex, Args&&... args);
|
||||
basic_stream(Args&&... args);
|
||||
|
||||
/** Construct the stream from an existing socket.
|
||||
|
||||
This constructor creates the stream from an existing socket.
|
||||
The underlying socket needs to be open and connected or accepted
|
||||
before data can be sent or received on it.
|
||||
|
||||
@param socket The socket to construct from. Ownership of the
|
||||
socket will be transferred by move-construction.
|
||||
|
||||
@param args A list of parameters forwarded to the constructor of
|
||||
the underlying socket.
|
||||
|
||||
@note This function does not participate in overload resolution unless:
|
||||
|
||||
@li `OtherProtocol` is convertible to `Protocol`, and one of:
|
||||
|
||||
@li `executor_type` of the stream is constructible from the type of
|
||||
context returned by calling `socket.get_executor().context()`, or
|
||||
|
||||
@li `executor_type` of the stream is constructible from the type of
|
||||
executor returned by calling `socket.get_executor()`.
|
||||
*/
|
||||
template<
|
||||
class OtherProtocol
|
||||
#if ! BOOST_BEAST_DOXYGEN
|
||||
,class = typename std::enable_if<
|
||||
std::is_convertible<OtherProtocol, Protocol>::value && (
|
||||
std::is_constructible<Executor,
|
||||
decltype(std::declval<net::basic_stream_socket<
|
||||
Protocol>&>().get_executor().context())>::value ||
|
||||
std::is_constructible<Executor,
|
||||
decltype(std::declval<net::basic_stream_socket<
|
||||
Protocol>&>().get_executor())>::value)
|
||||
>::type
|
||||
#endif
|
||||
>
|
||||
explicit
|
||||
basic_stream(net::basic_stream_socket<OtherProtocol>&& socket);
|
||||
|
||||
/** Move constructor.
|
||||
/** Move constructor
|
||||
|
||||
@param other The other object from which the move will occur.
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/beast
|
||||
//
|
||||
|
||||
#ifndef BOOST_BEAST_DETAIL_GET_IO_CONTEXT_HPP
|
||||
#define BOOST_BEAST_DETAIL_GET_IO_CONTEXT_HPP
|
||||
|
||||
#include <boost/beast/core/stream_traits.hpp>
|
||||
#include <boost/asio/executor.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
net::io_context*
|
||||
get_io_context(net::io_context& ioc)
|
||||
{
|
||||
return std::addressof(ioc);
|
||||
}
|
||||
|
||||
inline
|
||||
net::io_context*
|
||||
get_io_context(net::io_context::executor_type const& ex)
|
||||
{
|
||||
return std::addressof(ex.context());
|
||||
}
|
||||
|
||||
inline
|
||||
net::io_context*
|
||||
get_io_context(net::strand<
|
||||
net::io_context::executor_type> const& ex)
|
||||
{
|
||||
return std::addressof(
|
||||
ex.get_inner_executor().context());
|
||||
}
|
||||
|
||||
template<class Executor>
|
||||
net::io_context*
|
||||
get_io_context(net::strand<Executor> const& ex)
|
||||
{
|
||||
return get_io_context(ex.get_inner_executor());
|
||||
}
|
||||
|
||||
template<
|
||||
class T,
|
||||
class = typename std::enable_if<
|
||||
std::is_same<T, net::executor>::value>::type>
|
||||
net::io_context*
|
||||
get_io_context(T const& ex)
|
||||
{
|
||||
auto p = ex.template target<typename
|
||||
net::io_context::executor_type>();
|
||||
if(! p)
|
||||
return nullptr;
|
||||
return std::addressof(p->context());
|
||||
}
|
||||
|
||||
inline
|
||||
net::io_context*
|
||||
get_io_context(...)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class T>
|
||||
net::io_context*
|
||||
get_io_context_impl(T& t, std::true_type)
|
||||
{
|
||||
return get_io_context(
|
||||
t.get_executor());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
net::io_context*
|
||||
get_io_context_impl(T const&, std::false_type)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Returns the io_context*, or nullptr, for any object.
|
||||
template<class T>
|
||||
net::io_context*
|
||||
get_io_context(T& t)
|
||||
{
|
||||
return get_io_context_impl(t,
|
||||
has_get_executor<T>{});
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <boost/core/exchange.hpp>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
@@ -48,9 +49,10 @@ struct stream_base
|
||||
bool pending = false; // if op is pending
|
||||
bool timeout = false; // if timed out
|
||||
|
||||
template<class... Args>
|
||||
explicit
|
||||
op_state(net::io_context& ioc)
|
||||
: timer(ioc)
|
||||
op_state(Args&&... args)
|
||||
: timer(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -32,44 +32,10 @@ template<class Protocol, class Executor>
|
||||
template<class... Args>
|
||||
basic_stream<Protocol, Executor>::
|
||||
impl_type::
|
||||
impl_type(
|
||||
Executor const& ex_,
|
||||
Args&&... args)
|
||||
: boost::empty_value<Executor>(
|
||||
boost::empty_init_t{}, ex_)
|
||||
, read(ex().context())
|
||||
, write(ex().context())
|
||||
, socket(std::forward<Args>(args)...)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
template<class Protocol, class Executor>
|
||||
template<class OtherProtocol>
|
||||
basic_stream<Protocol, Executor>::
|
||||
impl_type::
|
||||
impl_type(net::basic_stream_socket<OtherProtocol>&& socket_,
|
||||
std::true_type)
|
||||
: boost::empty_value<Executor>(
|
||||
boost::empty_init_t{}, socket_.get_executor())
|
||||
, read(ex().context())
|
||||
, write(ex().context())
|
||||
, socket(std::move(socket_))
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
template<class Protocol, class Executor>
|
||||
template<class OtherProtocol>
|
||||
basic_stream<Protocol, Executor>::
|
||||
impl_type::
|
||||
impl_type(net::basic_stream_socket<OtherProtocol>&& socket_,
|
||||
std::false_type)
|
||||
: boost::empty_value<Executor>(boost::empty_init_t{},
|
||||
socket_.get_executor().context())
|
||||
, read(ex().context())
|
||||
, write(ex().context())
|
||||
, socket(std::move(socket_))
|
||||
impl_type(Args&&... args)
|
||||
: socket(std::forward<Args>(args)...)
|
||||
, read(ex())
|
||||
, write(ex())
|
||||
{
|
||||
reset();
|
||||
}
|
||||
@@ -434,40 +400,12 @@ basic_stream<Protocol, Executor>::
|
||||
impl_->close();
|
||||
}
|
||||
|
||||
template<class Protocol, class Executor>
|
||||
template<class ExecutionContext, class... Args, class>
|
||||
basic_stream<Protocol, Executor>::
|
||||
basic_stream(ExecutionContext& ctx, Args&&... args)
|
||||
: impl_(boost::make_shared<impl_type>(
|
||||
ctx.get_executor(),
|
||||
ctx, std::forward<Args>(args)...))
|
||||
{
|
||||
// Restriction is necessary until Asio fully supports P1322R0
|
||||
static_assert(
|
||||
std::is_same<ExecutionContext, net::io_context>::value,
|
||||
"Only net::io_context is currently supported for ExecutionContext");
|
||||
}
|
||||
|
||||
template<class Protocol, class Executor>
|
||||
template<class... Args>
|
||||
basic_stream<Protocol, Executor>::
|
||||
basic_stream(
|
||||
executor_type const& ex, Args&&... args)
|
||||
basic_stream(Args&&... args)
|
||||
: impl_(boost::make_shared<impl_type>(
|
||||
ex,
|
||||
ex.context(), std::forward<Args>(args)...))
|
||||
{
|
||||
}
|
||||
|
||||
template<class Protocol, class Executor>
|
||||
template<class OtherProtocol, class>
|
||||
basic_stream<Protocol, Executor>::
|
||||
basic_stream(net::basic_stream_socket<OtherProtocol>&& socket)
|
||||
: impl_(boost::make_shared<impl_type>(
|
||||
std::move(socket),
|
||||
std::is_constructible<Executor,
|
||||
decltype(std::declval<net::basic_stream_socket<
|
||||
Protocol>&>().get_executor())>{}))
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -438,10 +438,10 @@ using is_async_stream = std::integral_constant<bool,
|
||||
|
||||
@see close_socket
|
||||
*/
|
||||
template<class Protocol BOOST_ASIO_SVC_TPARAM>
|
||||
template<class Protocol>
|
||||
void
|
||||
beast_close_socket(
|
||||
net::basic_socket<Protocol BOOST_ASIO_SVC_TPARAM>& sock)
|
||||
net::basic_socket<Protocol>& sock)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
sock.close(ec);
|
||||
|
||||
@@ -12,20 +12,17 @@
|
||||
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/beast/core/basic_stream.hpp>
|
||||
#include <boost/asio/executor.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
|
||||
/** A TCP/IP stream socket with timeouts, rate limits, and executor.
|
||||
|
||||
@tparam Executor The type of executor to use for all completion
|
||||
handlers which do not already have an associated executor.
|
||||
/** A TCP/IP stream socket with timeouts, rate limits, and polymorphic executor.
|
||||
|
||||
@see basic_stream
|
||||
*/
|
||||
template<class Executor>
|
||||
using tcp_stream = basic_stream<net::ip::tcp, Executor>;
|
||||
using tcp_stream = basic_stream<net::ip::tcp, net::executor>;
|
||||
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
@@ -30,6 +30,8 @@ using file_body = basic_file_body<file>;
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#ifndef BOOST_BEAST_NO_FILE_BODY_WIN32
|
||||
#include <boost/beast/http/impl/file_body_win32.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -32,7 +32,7 @@ namespace beast {
|
||||
namespace http {
|
||||
|
||||
namespace detail {
|
||||
template<class, class, bool, class>
|
||||
template<class, class, class, bool, 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, bool, class>
|
||||
template<class, class, class, bool, class>
|
||||
friend class detail::write_some_win32_op;
|
||||
template<
|
||||
class Protocol, bool isRequest, class Fields>
|
||||
@@ -101,7 +101,7 @@ struct basic_file_body<file_win32>
|
||||
|
||||
class writer
|
||||
{
|
||||
template<class, class, bool, class>
|
||||
template<class, class, class, bool, class>
|
||||
friend class detail::write_some_win32_op;
|
||||
template<
|
||||
class Protocol, bool isRequest, class Fields>
|
||||
@@ -276,7 +276,6 @@ reset(file_win32&& file, error_code& ec)
|
||||
namespace detail {
|
||||
|
||||
template<class Unsigned>
|
||||
inline
|
||||
boost::winapi::DWORD_
|
||||
lowPart(Unsigned n)
|
||||
{
|
||||
@@ -286,7 +285,6 @@ lowPart(Unsigned n)
|
||||
}
|
||||
|
||||
template<class Unsigned>
|
||||
inline
|
||||
boost::winapi::DWORD_
|
||||
highPart(Unsigned n, std::true_type)
|
||||
{
|
||||
@@ -296,7 +294,6 @@ highPart(Unsigned n, std::true_type)
|
||||
}
|
||||
|
||||
template<class Unsigned>
|
||||
inline
|
||||
boost::winapi::DWORD_
|
||||
highPart(Unsigned, std::false_type)
|
||||
{
|
||||
@@ -304,7 +301,6 @@ highPart(Unsigned, std::false_type)
|
||||
}
|
||||
|
||||
template<class Unsigned>
|
||||
inline
|
||||
boost::winapi::DWORD_
|
||||
highPart(Unsigned n)
|
||||
{
|
||||
@@ -329,14 +325,17 @@ public:
|
||||
#if BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR
|
||||
|
||||
template<
|
||||
class Protocol, class Handler,
|
||||
bool isRequest, class Fields>
|
||||
class Protocol, class Executor,
|
||||
class Handler, bool isRequest, class Fields>
|
||||
class write_some_win32_op
|
||||
: public beast::async_op_base<
|
||||
Handler, typename net::basic_stream_socket<
|
||||
Protocol>::executor_type>
|
||||
: public beast::async_op_base<Handler, Executor>
|
||||
{
|
||||
net::basic_stream_socket<Protocol>& sock_;
|
||||
static_assert(
|
||||
std::is_same<Executor, net::io_context::executor_type>::value,
|
||||
"Executor must be net::io_context::executor_type");
|
||||
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& sock_;
|
||||
serializer<isRequest,
|
||||
basic_file_body<file_win32>, Fields>& sr_;
|
||||
std::size_t bytes_transferred_ = 0;
|
||||
@@ -346,14 +345,14 @@ public:
|
||||
template<class Handler_>
|
||||
write_some_win32_op(
|
||||
Handler_&& h,
|
||||
net::basic_stream_socket<Protocol>& s,
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& s,
|
||||
serializer<isRequest,
|
||||
basic_file_body<file_win32>,Fields>& sr)
|
||||
: async_op_base<
|
||||
Handler, typename net::basic_stream_socket<
|
||||
Protocol>::executor_type>(
|
||||
std::forward<Handler_>(h),
|
||||
s.get_executor())
|
||||
Handler, Executor>(
|
||||
std::forward<Handler_>(h),
|
||||
s.get_executor())
|
||||
, sock_(s)
|
||||
, sr_(sr)
|
||||
{
|
||||
@@ -442,10 +441,13 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Protocol, bool isRequest, class Fields>
|
||||
template<
|
||||
class Protocol, class Executor,
|
||||
bool isRequest, class Fields>
|
||||
std::size_t
|
||||
write_some(
|
||||
net::basic_stream_socket<Protocol>& sock,
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& sock,
|
||||
serializer<isRequest,
|
||||
basic_file_body<file_win32>, Fields>& sr,
|
||||
error_code& ec)
|
||||
@@ -509,21 +511,23 @@ write_some(
|
||||
#if BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR
|
||||
|
||||
template<
|
||||
class Protocol,
|
||||
class Protocol, class Executor,
|
||||
bool isRequest, class Fields,
|
||||
class WriteHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
WriteHandler, void(error_code, std::size_t))
|
||||
async_write_some(
|
||||
net::basic_stream_socket<Protocol>& sock,
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& sock,
|
||||
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,
|
||||
Protocol, Executor,
|
||||
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
|
||||
void(error_code, std::size_t)),
|
||||
isRequest, Fields>{
|
||||
|
||||
@@ -19,7 +19,15 @@
|
||||
#include <boost/beast/core/static_string.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
// This is for <boost/endian/buffers.hpp>
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, > 0)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, > 0)
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -103,7 +103,7 @@ struct stream<NextLayer, deflateSupported>::impl_type
|
||||
template<class... Args>
|
||||
impl_type(Args&&... args)
|
||||
: stream(std::forward<Args>(args)...)
|
||||
, timer(stream.get_executor().context())
|
||||
, timer(stream.get_executor())
|
||||
{
|
||||
timeout_opt.handshake_timeout = none();
|
||||
timeout_opt.idle_timeout = none();
|
||||
|
||||
@@ -25,14 +25,18 @@ namespace websocket {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class Handler>
|
||||
template<
|
||||
class Protocol, class Executor,
|
||||
class Handler>
|
||||
class teardown_tcp_op
|
||||
: public beast::async_op_base<
|
||||
Handler, beast::executor_type<
|
||||
net::ip::tcp::socket>>
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>>>
|
||||
, public net::coroutine
|
||||
{
|
||||
using socket_type = net::ip::tcp::socket;
|
||||
using socket_type =
|
||||
net::basic_stream_socket<Protocol, Executor>;
|
||||
|
||||
socket_type& s_;
|
||||
role_type role_;
|
||||
@@ -46,8 +50,10 @@ public:
|
||||
role_type role)
|
||||
: async_op_base<Handler,
|
||||
beast::executor_type<
|
||||
net::ip::tcp::socket>>(
|
||||
std::forward<Handler_>(h), s.get_executor())
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>>>(
|
||||
std::forward<Handler_>(h),
|
||||
s.get_executor())
|
||||
, s_(s)
|
||||
, role_(role)
|
||||
{
|
||||
@@ -60,7 +66,6 @@ public:
|
||||
std::size_t bytes_transferred = 0,
|
||||
bool cont = true)
|
||||
{
|
||||
using tcp = net::ip::tcp;
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
nb_ = s_.non_blocking();
|
||||
@@ -68,7 +73,7 @@ public:
|
||||
if(ec)
|
||||
goto upcall;
|
||||
if(role_ == role_type::server)
|
||||
s_.shutdown(tcp::socket::shutdown_send, ec);
|
||||
s_.shutdown(net::socket_base::shutdown_send, ec);
|
||||
if(ec)
|
||||
goto upcall;
|
||||
for(;;)
|
||||
@@ -81,7 +86,7 @@ public:
|
||||
{
|
||||
BOOST_ASIO_CORO_YIELD
|
||||
s_.async_wait(
|
||||
net::ip::tcp::socket::wait_read,
|
||||
net::socket_base::wait_read,
|
||||
beast::detail::bind_continuation(std::move(*this)));
|
||||
continue;
|
||||
}
|
||||
@@ -100,7 +105,7 @@ public:
|
||||
}
|
||||
}
|
||||
if(role_ == role_type::client)
|
||||
s_.shutdown(tcp::socket::shutdown_send, ec);
|
||||
s_.shutdown(net::socket_base::shutdown_send, ec);
|
||||
if(ec)
|
||||
goto upcall;
|
||||
s_.close(ec);
|
||||
@@ -124,15 +129,17 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Protocol, class Executor>
|
||||
void
|
||||
teardown(
|
||||
role_type role,
|
||||
net::ip::tcp::socket& socket,
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& socket,
|
||||
error_code& ec)
|
||||
{
|
||||
if(role == role_type::server)
|
||||
socket.shutdown(
|
||||
net::ip::tcp::socket::shutdown_send, ec);
|
||||
net::socket_base::shutdown_send, ec);
|
||||
if(ec)
|
||||
return;
|
||||
for(;;)
|
||||
@@ -156,25 +163,32 @@ teardown(
|
||||
}
|
||||
if(role == role_type::client)
|
||||
socket.shutdown(
|
||||
net::ip::tcp::socket::shutdown_send, ec);
|
||||
net::socket_base::shutdown_send, ec);
|
||||
if(ec)
|
||||
return;
|
||||
socket.close(ec);
|
||||
}
|
||||
|
||||
template<class TeardownHandler>
|
||||
template<
|
||||
class Protocol, class Executor,
|
||||
class TeardownHandler>
|
||||
void
|
||||
async_teardown(
|
||||
role_type role,
|
||||
net::ip::tcp::socket& socket,
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& socket,
|
||||
TeardownHandler&& handler)
|
||||
{
|
||||
static_assert(beast::detail::is_invocable<
|
||||
TeardownHandler, void(error_code)>::value,
|
||||
"TeardownHandler requirements not met");
|
||||
detail::teardown_tcp_op<typename std::decay<
|
||||
TeardownHandler>::type>(std::forward<
|
||||
TeardownHandler>(handler), socket, role);
|
||||
detail::teardown_tcp_op<
|
||||
Protocol,
|
||||
Executor,
|
||||
typename std::decay<TeardownHandler>::type>(
|
||||
std::forward<TeardownHandler>(handler),
|
||||
socket,
|
||||
role);
|
||||
}
|
||||
|
||||
} // websocket
|
||||
|
||||
@@ -80,13 +80,12 @@ class frame_test;
|
||||
To declare the @ref stream object with a @ref tcp_stream in a
|
||||
multi-threaded asynchronous program using a strand, you may write:
|
||||
@code
|
||||
websocket::stream<tcp_stream<
|
||||
net::io_context::strand>> ws{net::io_context::strand(ioc)};
|
||||
websocket::stream<tcp_stream> ws{net::io_context::strand(ioc)};
|
||||
@endcode
|
||||
Alternatively, for a single-threaded or synchronous application
|
||||
you may write:
|
||||
@code
|
||||
websocket::stream<tcp_stream<net::io_context::executor_type>> ws(ioc);
|
||||
websocket::stream<tcp_stream> ws(ioc);
|
||||
@endcode
|
||||
|
||||
@tparam NextLayer The type representing the next layer, to which
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/beast/core/error.hpp>
|
||||
#include <boost/beast/websocket/role.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/basic_stream_socket.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
@@ -125,11 +125,12 @@ namespace websocket {
|
||||
|
||||
@param ec Set to the error if any occurred.
|
||||
*/
|
||||
BOOST_BEAST_DECL
|
||||
template<class Protocol, class Executor>
|
||||
void
|
||||
teardown(
|
||||
role_type role,
|
||||
net::ip::tcp::socket& socket,
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& socket,
|
||||
error_code& ec);
|
||||
|
||||
/** Start tearing down a `net::ip::tcp::socket`.
|
||||
@@ -159,11 +160,14 @@ teardown(
|
||||
manner equivalent to using net::io_context::post().
|
||||
|
||||
*/
|
||||
template<class TeardownHandler>
|
||||
template<
|
||||
class Protocol, class Executor,
|
||||
class TeardownHandler>
|
||||
void
|
||||
async_teardown(
|
||||
role_type role,
|
||||
net::ip::tcp::socket& socket,
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& socket,
|
||||
TeardownHandler&& handler);
|
||||
|
||||
} // websocket
|
||||
|
||||
Reference in new issue
Block a user