summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/include/asio/ssl/stream.hpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asio/include/asio/ssl/stream.hpp')
-rw-r--r--3rdparty/asio/include/asio/ssl/stream.hpp407
1 files changed, 309 insertions, 98 deletions
diff --git a/3rdparty/asio/include/asio/ssl/stream.hpp b/3rdparty/asio/include/asio/ssl/stream.hpp
index bc259b59ca7..616be7b806f 100644
--- a/3rdparty/asio/include/asio/ssl/stream.hpp
+++ b/3rdparty/asio/include/asio/ssl/stream.hpp
@@ -2,7 +2,7 @@
// ssl/stream.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff 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)
@@ -20,6 +20,7 @@
#include "asio/async_result.hpp"
#include "asio/detail/buffer_sequence_adapter.hpp"
#include "asio/detail/handler_type_requirements.hpp"
+#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/ssl/context.hpp"
@@ -51,9 +52,9 @@ namespace ssl {
* @par Example
* To use the SSL stream template with an ip::tcp::socket, you would write:
* @code
- * asio::io_context io_context;
+ * asio::io_context my_context;
* asio::ssl::context ctx(asio::ssl::context::sslv23);
- * asio::ssl::stream<asio:ip::tcp::socket> sock(io_context, ctx);
+ * asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx);
* @endcode
*
* @par Concepts:
@@ -96,20 +97,50 @@ public:
template <typename Arg>
stream(Arg&& arg, context& ctx)
: next_layer_(ASIO_MOVE_CAST(Arg)(arg)),
- core_(ctx.native_handle(),
- next_layer_.lowest_layer().get_executor().context())
+ core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())
{
}
#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
template <typename Arg>
stream(Arg& arg, context& ctx)
: next_layer_(arg),
- core_(ctx.native_handle(),
- next_layer_.lowest_layer().get_executor().context())
+ core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())
{
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move-construct a stream from another.
+ /**
+ * @param other The other stream object from which the move will occur. Must
+ * have no outstanding asynchronous operations associated with it. Following
+ * the move, @c other has a valid but unspecified state where the only safe
+ * operation is destruction, or use as the target of a move assignment.
+ */
+ stream(stream&& other)
+ : next_layer_(ASIO_MOVE_CAST(Stream)(other.next_layer_)),
+ core_(ASIO_MOVE_CAST(detail::stream_core)(other.core_))
+ {
+ }
+
+ /// Move-assign a stream from another.
+ /**
+ * @param other The other stream object from which the move will occur. Must
+ * have no outstanding asynchronous operations associated with it. Following
+ * the move, @c other has a valid but unspecified state where the only safe
+ * operation is destruction, or use as the target of a move assignment.
+ */
+ stream& operator=(stream&& other)
+ {
+ if (this != &other)
+ {
+ next_layer_ = ASIO_MOVE_CAST(Stream)(other.next_layer_);
+ core_ = ASIO_MOVE_CAST(detail::stream_core)(other.core_);
+ }
+ return *this;
+ }
+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
/// Destructor.
/**
* @note A @c stream object must not be destroyed while there are pending
@@ -131,22 +162,6 @@ public:
return next_layer_.lowest_layer().get_executor();
}
-#if !defined(ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- asio::io_context& get_io_context()
- {
- return next_layer_.lowest_layer().get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- asio::io_context& get_io_service()
- {
- return next_layer_.lowest_layer().get_io_service();
- }
-#endif // !defined(ASIO_NO_DEPRECATED)
-
/// Get the underlying implementation in the native type.
/**
* This function may be used to obtain the underlying implementation of the
@@ -158,7 +173,7 @@ public:
* suitable for passing to functions such as @c SSL_get_verify_result and
* @c SSL_get_peer_certificate:
* @code
- * asio::ssl::stream<asio:ip::tcp::socket> sock(io_context, ctx);
+ * asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx);
*
* // ... establish connection and perform handshake ...
*
@@ -446,24 +461,31 @@ public:
* @code void handler(
* const asio::error_code& error // Result of operation.
* ); @endcode
+ *
+ * @par Per-Operation Cancellation
+ * This asynchronous operation supports cancellation for the following
+ * asio::cancellation_type values:
+ *
+ * @li @c cancellation_type::terminal
+ *
+ * @li @c cancellation_type::partial
+ *
+ * if they are also supported by the @c Stream type's @c async_read_some and
+ * @c async_write_some operations.
*/
- template <typename HandshakeHandler>
- ASIO_INITFN_RESULT_TYPE(HandshakeHandler,
+ template <
+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))
+ HandshakeHandler
+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+ ASIO_INITFN_AUTO_RESULT_TYPE(HandshakeHandler,
void (asio::error_code))
async_handshake(handshake_type type,
- ASIO_MOVE_ARG(HandshakeHandler) handler)
+ ASIO_MOVE_ARG(HandshakeHandler) handler
+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a HandshakeHandler.
- ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
-
- asio::async_completion<HandshakeHandler,
- void (asio::error_code)> init(handler);
-
- detail::async_io(next_layer_, core_,
- detail::handshake_op(type), init.completion_handler);
-
- return init.result.get();
+ return async_initiate<HandshakeHandler,
+ void (asio::error_code)>(
+ initiate_async_handshake(this), handler, type);
}
/// Start an asynchronous SSL handshake.
@@ -486,26 +508,31 @@ public:
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Amount of buffers used in handshake.
* ); @endcode
+ *
+ * @par Per-Operation Cancellation
+ * This asynchronous operation supports cancellation for the following
+ * asio::cancellation_type values:
+ *
+ * @li @c cancellation_type::terminal
+ *
+ * @li @c cancellation_type::partial
+ *
+ * if they are also supported by the @c Stream type's @c async_read_some and
+ * @c async_write_some operations.
*/
- template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
- ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler,
+ template <typename ConstBufferSequence,
+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+ std::size_t)) BufferedHandshakeHandler
+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+ ASIO_INITFN_AUTO_RESULT_TYPE(BufferedHandshakeHandler,
void (asio::error_code, std::size_t))
async_handshake(handshake_type type, const ConstBufferSequence& buffers,
- ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
+ ASIO_MOVE_ARG(BufferedHandshakeHandler) handler
+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a BufferedHandshakeHandler.
- ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK(
- BufferedHandshakeHandler, handler) type_check;
-
- asio::async_completion<BufferedHandshakeHandler,
- void (asio::error_code, std::size_t)> init(handler);
-
- detail::async_io(next_layer_, core_,
- detail::buffered_handshake_op<ConstBufferSequence>(type, buffers),
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<BufferedHandshakeHandler,
+ void (asio::error_code, std::size_t)>(
+ initiate_async_buffered_handshake(this), handler, type, buffers);
}
/// Shut down SSL on the stream.
@@ -546,23 +573,31 @@ public:
* @code void handler(
* const asio::error_code& error // Result of operation.
* ); @endcode
+ *
+ * @par Per-Operation Cancellation
+ * This asynchronous operation supports cancellation for the following
+ * asio::cancellation_type values:
+ *
+ * @li @c cancellation_type::terminal
+ *
+ * @li @c cancellation_type::partial
+ *
+ * if they are also supported by the @c Stream type's @c async_read_some and
+ * @c async_write_some operations.
*/
- template <typename ShutdownHandler>
- ASIO_INITFN_RESULT_TYPE(ShutdownHandler,
+ template <
+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))
+ ShutdownHandler
+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+ ASIO_INITFN_AUTO_RESULT_TYPE(ShutdownHandler,
void (asio::error_code))
- async_shutdown(ASIO_MOVE_ARG(ShutdownHandler) handler)
+ async_shutdown(
+ ASIO_MOVE_ARG(ShutdownHandler) handler
+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ShutdownHandler.
- ASIO_SHUTDOWN_HANDLER_CHECK(ShutdownHandler, handler) type_check;
-
- asio::async_completion<ShutdownHandler,
- void (asio::error_code)> init(handler);
-
- detail::async_io(next_layer_, core_, detail::shutdown_op(),
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<ShutdownHandler,
+ void (asio::error_code)>(
+ initiate_async_shutdown(this), handler);
}
/// Write some data to the stream.
@@ -634,26 +669,33 @@ public:
*
* @note The async_write_some operation may not transmit all of the data to
* the peer. Consider using the @ref async_write function if you need to
- * ensure that all data is written before the blocking operation completes.
+ * ensure that all data is written before the asynchronous operation
+ * completes.
+ *
+ * @par Per-Operation Cancellation
+ * This asynchronous operation supports cancellation for the following
+ * asio::cancellation_type values:
+ *
+ * @li @c cancellation_type::terminal
+ *
+ * @li @c cancellation_type::partial
+ *
+ * if they are also supported by the @c Stream type's @c async_read_some and
+ * @c async_write_some operations.
*/
- template <typename ConstBufferSequence, typename WriteHandler>
- ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ template <typename ConstBufferSequence,
+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+ std::size_t)) WriteHandler
+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+ ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (asio::error_code, std::size_t))
async_write_some(const ConstBufferSequence& buffers,
- ASIO_MOVE_ARG(WriteHandler) handler)
+ ASIO_MOVE_ARG(WriteHandler) handler
+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- asio::async_completion<WriteHandler,
- void (asio::error_code, std::size_t)> init(handler);
-
- detail::async_io(next_layer_, core_,
- detail::write_op<ConstBufferSequence>(buffers),
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<WriteHandler,
+ void (asio::error_code, std::size_t)>(
+ initiate_async_write_some(this), handler, buffers);
}
/// Read some data from the stream.
@@ -727,28 +769,197 @@ public:
* number of bytes. Consider using the @ref async_read function if you need to
* ensure that the requested amount of data is read before the asynchronous
* operation completes.
+ *
+ * @par Per-Operation Cancellation
+ * This asynchronous operation supports cancellation for the following
+ * asio::cancellation_type values:
+ *
+ * @li @c cancellation_type::terminal
+ *
+ * @li @c cancellation_type::partial
+ *
+ * if they are also supported by the @c Stream type's @c async_read_some and
+ * @c async_write_some operations.
*/
- template <typename MutableBufferSequence, typename ReadHandler>
- ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ template <typename MutableBufferSequence,
+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+ std::size_t)) ReadHandler
+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+ ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (asio::error_code, std::size_t))
async_read_some(const MutableBufferSequence& buffers,
- ASIO_MOVE_ARG(ReadHandler) handler)
+ ASIO_MOVE_ARG(ReadHandler) handler
+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+ return async_initiate<ReadHandler,
+ void (asio::error_code, std::size_t)>(
+ initiate_async_read_some(this), handler, buffers);
+ }
- asio::async_completion<ReadHandler,
- void (asio::error_code, std::size_t)> init(handler);
+private:
+ class initiate_async_handshake
+ {
+ public:
+ typedef typename stream::executor_type executor_type;
+
+ explicit initiate_async_handshake(stream* self)
+ : self_(self)
+ {
+ }
+
+ executor_type get_executor() const ASIO_NOEXCEPT
+ {
+ return self_->get_executor();
+ }
+
+ template <typename HandshakeHandler>
+ void operator()(ASIO_MOVE_ARG(HandshakeHandler) handler,
+ handshake_type type) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a HandshakeHandler.
+ ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
+
+ asio::detail::non_const_lvalue<HandshakeHandler> handler2(handler);
+ detail::async_io(self_->next_layer_, self_->core_,
+ detail::handshake_op(type), handler2.value);
+ }
+
+ private:
+ stream* self_;
+ };
- detail::async_io(next_layer_, core_,
- detail::read_op<MutableBufferSequence>(buffers),
- init.completion_handler);
+ class initiate_async_buffered_handshake
+ {
+ public:
+ typedef typename stream::executor_type executor_type;
+
+ explicit initiate_async_buffered_handshake(stream* self)
+ : self_(self)
+ {
+ }
+
+ executor_type get_executor() const ASIO_NOEXCEPT
+ {
+ return self_->get_executor();
+ }
+
+ template <typename BufferedHandshakeHandler, typename ConstBufferSequence>
+ void operator()(ASIO_MOVE_ARG(BufferedHandshakeHandler) handler,
+ handshake_type type, const ConstBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your
+ // handler does not meet the documented type requirements for a
+ // BufferedHandshakeHandler.
+ ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK(
+ BufferedHandshakeHandler, handler) type_check;
+
+ asio::detail::non_const_lvalue<
+ BufferedHandshakeHandler> handler2(handler);
+ detail::async_io(self_->next_layer_, self_->core_,
+ detail::buffered_handshake_op<ConstBufferSequence>(type, buffers),
+ handler2.value);
+ }
+
+ private:
+ stream* self_;
+ };
- return init.result.get();
- }
+ class initiate_async_shutdown
+ {
+ public:
+ typedef typename stream::executor_type executor_type;
+
+ explicit initiate_async_shutdown(stream* self)
+ : self_(self)
+ {
+ }
+
+ executor_type get_executor() const ASIO_NOEXCEPT
+ {
+ return self_->get_executor();
+ }
+
+ template <typename ShutdownHandler>
+ void operator()(ASIO_MOVE_ARG(ShutdownHandler) handler) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ShutdownHandler.
+ ASIO_HANDSHAKE_HANDLER_CHECK(ShutdownHandler, handler) type_check;
+
+ asio::detail::non_const_lvalue<ShutdownHandler> handler2(handler);
+ detail::async_io(self_->next_layer_, self_->core_,
+ detail::shutdown_op(), handler2.value);
+ }
+
+ private:
+ stream* self_;
+ };
+
+ class initiate_async_write_some
+ {
+ public:
+ typedef typename stream::executor_type executor_type;
+
+ explicit initiate_async_write_some(stream* self)
+ : self_(self)
+ {
+ }
+
+ executor_type get_executor() const ASIO_NOEXCEPT
+ {
+ return self_->get_executor();
+ }
+
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
+ const ConstBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ asio::detail::non_const_lvalue<WriteHandler> handler2(handler);
+ detail::async_io(self_->next_layer_, self_->core_,
+ detail::write_op<ConstBufferSequence>(buffers), handler2.value);
+ }
+
+ private:
+ stream* self_;
+ };
+
+ class initiate_async_read_some
+ {
+ public:
+ typedef typename stream::executor_type executor_type;
+
+ explicit initiate_async_read_some(stream* self)
+ : self_(self)
+ {
+ }
+
+ executor_type get_executor() const ASIO_NOEXCEPT
+ {
+ return self_->get_executor();
+ }
+
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
+ const MutableBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ asio::detail::non_const_lvalue<ReadHandler> handler2(handler);
+ detail::async_io(self_->next_layer_, self_->core_,
+ detail::read_op<MutableBufferSequence>(buffers), handler2.value);
+ }
+
+ private:
+ stream* self_;
+ };
-private:
Stream next_layer_;
detail::stream_core core_;
};