5 // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_ASIO_SSL_STREAM_HPP
12 #define BOOST_ASIO_SSL_STREAM_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
20 #include <boost/asio/async_result.hpp>
21 #include <boost/asio/detail/buffer_sequence_adapter.hpp>
22 #include <boost/asio/detail/handler_type_requirements.hpp>
23 #include <boost/asio/detail/non_const_lvalue.hpp>
24 #include <boost/asio/detail/noncopyable.hpp>
25 #include <boost/asio/detail/type_traits.hpp>
26 #include <boost/asio/ssl/context.hpp>
27 #include <boost/asio/ssl/detail/buffered_handshake_op.hpp>
28 #include <boost/asio/ssl/detail/handshake_op.hpp>
29 #include <boost/asio/ssl/detail/io.hpp>
30 #include <boost/asio/ssl/detail/read_op.hpp>
31 #include <boost/asio/ssl/detail/shutdown_op.hpp>
32 #include <boost/asio/ssl/detail/stream_core.hpp>
33 #include <boost/asio/ssl/detail/write_op.hpp>
34 #include <boost/asio/ssl/stream_base.hpp>
36 #include <boost/asio/detail/push_options.hpp>
42 /// Provides stream-oriented functionality using SSL.
44 * The stream class template provides asynchronous and blocking stream-oriented
45 * functionality using SSL.
48 * @e Distinct @e objects: Safe.@n
49 * @e Shared @e objects: Unsafe. The application must also ensure that all
50 * asynchronous operations are performed within the same implicit or explicit
54 * To use the SSL stream template with an ip::tcp::socket, you would write:
56 * boost::asio::io_context my_context;
57 * boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
58 * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx);
62 * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
64 template <typename Stream>
70 /// The native handle type of the SSL stream.
71 typedef SSL* native_handle_type;
73 /// Structure for use with deprecated impl_type.
79 /// The type of the next layer.
80 typedef typename remove_reference<Stream>::type next_layer_type;
82 /// The type of the lowest layer.
83 typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
85 /// The type of the executor associated with the object.
86 typedef typename lowest_layer_type::executor_type executor_type;
88 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
89 /// Construct a stream.
91 * This constructor creates a stream and initialises the underlying stream
94 * @param arg The argument to be passed to initialise the underlying stream.
96 * @param ctx The SSL context to be used for the stream.
98 template <typename Arg>
99 stream(Arg&& arg, context& ctx)
100 : next_layer_(BOOST_ASIO_MOVE_CAST(Arg)(arg)),
101 core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())
104 #else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
105 template <typename Arg>
106 stream(Arg& arg, context& ctx)
108 core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())
111 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
115 * @note A @c stream object must not be destroyed while there are pending
116 * asynchronous operations associated with it.
122 /// Get the executor associated with the object.
124 * This function may be used to obtain the executor object that the stream
125 * uses to dispatch handlers for asynchronous operations.
127 * @return A copy of the executor that stream will use to dispatch handlers.
129 executor_type get_executor() BOOST_ASIO_NOEXCEPT
131 return next_layer_.lowest_layer().get_executor();
134 /// Get the underlying implementation in the native type.
136 * This function may be used to obtain the underlying implementation of the
137 * context. This is intended to allow access to context functionality that is
138 * not otherwise provided.
141 * The native_handle() function returns a pointer of type @c SSL* that is
142 * suitable for passing to functions such as @c SSL_get_verify_result and
143 * @c SSL_get_peer_certificate:
145 * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx);
147 * // ... establish connection and perform handshake ...
149 * if (X509* cert = SSL_get_peer_certificate(sock.native_handle()))
151 * if (SSL_get_verify_result(sock.native_handle()) == X509_V_OK)
158 native_handle_type native_handle()
160 return core_.engine_.native_handle();
163 /// Get a reference to the next layer.
165 * This function returns a reference to the next layer in a stack of stream
168 * @return A reference to the next layer in the stack of stream layers.
169 * Ownership is not transferred to the caller.
171 const next_layer_type& next_layer() const
176 /// Get a reference to the next layer.
178 * This function returns a reference to the next layer in a stack of stream
181 * @return A reference to the next layer in the stack of stream layers.
182 * Ownership is not transferred to the caller.
184 next_layer_type& next_layer()
189 /// Get a reference to the lowest layer.
191 * This function returns a reference to the lowest layer in a stack of
194 * @return A reference to the lowest layer in the stack of stream layers.
195 * Ownership is not transferred to the caller.
197 lowest_layer_type& lowest_layer()
199 return next_layer_.lowest_layer();
202 /// Get a reference to the lowest layer.
204 * This function returns a reference to the lowest layer in a stack of
207 * @return A reference to the lowest layer in the stack of stream layers.
208 * Ownership is not transferred to the caller.
210 const lowest_layer_type& lowest_layer() const
212 return next_layer_.lowest_layer();
215 /// Set the peer verification mode.
217 * This function may be used to configure the peer verification mode used by
218 * the stream. The new mode will override the mode inherited from the context.
220 * @param v A bitmask of peer verification modes. See @ref verify_mode for
223 * @throws boost::system::system_error Thrown on failure.
225 * @note Calls @c SSL_set_verify.
227 void set_verify_mode(verify_mode v)
229 boost::system::error_code ec;
230 set_verify_mode(v, ec);
231 boost::asio::detail::throw_error(ec, "set_verify_mode");
234 /// Set the peer verification mode.
236 * This function may be used to configure the peer verification mode used by
237 * the stream. The new mode will override the mode inherited from the context.
239 * @param v A bitmask of peer verification modes. See @ref verify_mode for
242 * @param ec Set to indicate what error occurred, if any.
244 * @note Calls @c SSL_set_verify.
246 BOOST_ASIO_SYNC_OP_VOID set_verify_mode(
247 verify_mode v, boost::system::error_code& ec)
249 core_.engine_.set_verify_mode(v, ec);
250 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
253 /// Set the peer verification depth.
255 * This function may be used to configure the maximum verification depth
256 * allowed by the stream.
258 * @param depth Maximum depth for the certificate chain verification that
261 * @throws boost::system::system_error Thrown on failure.
263 * @note Calls @c SSL_set_verify_depth.
265 void set_verify_depth(int depth)
267 boost::system::error_code ec;
268 set_verify_depth(depth, ec);
269 boost::asio::detail::throw_error(ec, "set_verify_depth");
272 /// Set the peer verification depth.
274 * This function may be used to configure the maximum verification depth
275 * allowed by the stream.
277 * @param depth Maximum depth for the certificate chain verification that
280 * @param ec Set to indicate what error occurred, if any.
282 * @note Calls @c SSL_set_verify_depth.
284 BOOST_ASIO_SYNC_OP_VOID set_verify_depth(
285 int depth, boost::system::error_code& ec)
287 core_.engine_.set_verify_depth(depth, ec);
288 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
291 /// Set the callback used to verify peer certificates.
293 * This function is used to specify a callback function that will be called
294 * by the implementation when it needs to verify a peer certificate.
296 * @param callback The function object to be used for verifying a certificate.
297 * The function signature of the handler must be:
298 * @code bool verify_callback(
299 * bool preverified, // True if the certificate passed pre-verification.
300 * verify_context& ctx // The peer certificate and other context.
302 * The return value of the callback is true if the certificate has passed
303 * verification, false otherwise.
305 * @throws boost::system::system_error Thrown on failure.
307 * @note Calls @c SSL_set_verify.
309 template <typename VerifyCallback>
310 void set_verify_callback(VerifyCallback callback)
312 boost::system::error_code ec;
313 this->set_verify_callback(callback, ec);
314 boost::asio::detail::throw_error(ec, "set_verify_callback");
317 /// Set the callback used to verify peer certificates.
319 * This function is used to specify a callback function that will be called
320 * by the implementation when it needs to verify a peer certificate.
322 * @param callback The function object to be used for verifying a certificate.
323 * The function signature of the handler must be:
324 * @code bool verify_callback(
325 * bool preverified, // True if the certificate passed pre-verification.
326 * verify_context& ctx // The peer certificate and other context.
328 * The return value of the callback is true if the certificate has passed
329 * verification, false otherwise.
331 * @param ec Set to indicate what error occurred, if any.
333 * @note Calls @c SSL_set_verify.
335 template <typename VerifyCallback>
336 BOOST_ASIO_SYNC_OP_VOID set_verify_callback(VerifyCallback callback,
337 boost::system::error_code& ec)
339 core_.engine_.set_verify_callback(
340 new detail::verify_callback<VerifyCallback>(callback), ec);
341 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
344 /// Perform SSL handshaking.
346 * This function is used to perform SSL handshaking on the stream. The
347 * function call will block until handshaking is complete or an error occurs.
349 * @param type The type of handshaking to be performed, i.e. as a client or as
352 * @throws boost::system::system_error Thrown on failure.
354 void handshake(handshake_type type)
356 boost::system::error_code ec;
358 boost::asio::detail::throw_error(ec, "handshake");
361 /// Perform SSL handshaking.
363 * This function is used to perform SSL handshaking on the stream. The
364 * function call will block until handshaking is complete or an error occurs.
366 * @param type The type of handshaking to be performed, i.e. as a client or as
369 * @param ec Set to indicate what error occurred, if any.
371 BOOST_ASIO_SYNC_OP_VOID handshake(handshake_type type,
372 boost::system::error_code& ec)
374 detail::io(next_layer_, core_, detail::handshake_op(type), ec);
375 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
378 /// Perform SSL handshaking.
380 * This function is used to perform SSL handshaking on the stream. The
381 * function call will block until handshaking is complete or an error occurs.
383 * @param type The type of handshaking to be performed, i.e. as a client or as
386 * @param buffers The buffered data to be reused for the handshake.
388 * @throws boost::system::system_error Thrown on failure.
390 template <typename ConstBufferSequence>
391 void handshake(handshake_type type, const ConstBufferSequence& buffers)
393 boost::system::error_code ec;
394 handshake(type, buffers, ec);
395 boost::asio::detail::throw_error(ec, "handshake");
398 /// Perform SSL handshaking.
400 * This function is used to perform SSL handshaking on the stream. The
401 * function call will block until handshaking is complete or an error occurs.
403 * @param type The type of handshaking to be performed, i.e. as a client or as
406 * @param buffers The buffered data to be reused for the handshake.
408 * @param ec Set to indicate what error occurred, if any.
410 template <typename ConstBufferSequence>
411 BOOST_ASIO_SYNC_OP_VOID handshake(handshake_type type,
412 const ConstBufferSequence& buffers, boost::system::error_code& ec)
414 detail::io(next_layer_, core_,
415 detail::buffered_handshake_op<ConstBufferSequence>(type, buffers), ec);
416 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
419 /// Start an asynchronous SSL handshake.
421 * This function is used to asynchronously perform an SSL handshake on the
422 * stream. This function call always returns immediately.
424 * @param type The type of handshaking to be performed, i.e. as a client or as
427 * @param handler The handler to be called when the handshake operation
428 * completes. Copies will be made of the handler as required. The equivalent
429 * function signature of the handler must be:
430 * @code void handler(
431 * const boost::system::error_code& error // Result of operation.
435 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
437 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
438 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(HandshakeHandler,
439 void (boost::system::error_code))
440 async_handshake(handshake_type type,
441 BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler
442 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
444 return async_initiate<HandshakeHandler,
445 void (boost::system::error_code)>(
446 initiate_async_handshake(this), handler, type);
449 /// Start an asynchronous SSL handshake.
451 * This function is used to asynchronously perform an SSL handshake on the
452 * stream. This function call always returns immediately.
454 * @param type The type of handshaking to be performed, i.e. as a client or as
457 * @param buffers The buffered data to be reused for the handshake. Although
458 * the buffers object may be copied as necessary, ownership of the underlying
459 * buffers is retained by the caller, which must guarantee that they remain
460 * valid until the handler is called.
462 * @param handler The handler to be called when the handshake operation
463 * completes. Copies will be made of the handler as required. The equivalent
464 * function signature of the handler must be:
465 * @code void handler(
466 * const boost::system::error_code& error, // Result of operation.
467 * std::size_t bytes_transferred // Amount of buffers used in handshake.
470 template <typename ConstBufferSequence,
471 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
472 std::size_t)) BufferedHandshakeHandler
473 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
474 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(BufferedHandshakeHandler,
475 void (boost::system::error_code, std::size_t))
476 async_handshake(handshake_type type, const ConstBufferSequence& buffers,
477 BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler
478 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
480 return async_initiate<BufferedHandshakeHandler,
481 void (boost::system::error_code, std::size_t)>(
482 initiate_async_buffered_handshake(this), handler, type, buffers);
485 /// Shut down SSL on the stream.
487 * This function is used to shut down SSL on the stream. The function call
488 * will block until SSL has been shut down or an error occurs.
490 * @throws boost::system::system_error Thrown on failure.
494 boost::system::error_code ec;
496 boost::asio::detail::throw_error(ec, "shutdown");
499 /// Shut down SSL on the stream.
501 * This function is used to shut down SSL on the stream. The function call
502 * will block until SSL has been shut down or an error occurs.
504 * @param ec Set to indicate what error occurred, if any.
506 BOOST_ASIO_SYNC_OP_VOID shutdown(boost::system::error_code& ec)
508 detail::io(next_layer_, core_, detail::shutdown_op(), ec);
509 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
512 /// Asynchronously shut down SSL on the stream.
514 * This function is used to asynchronously shut down SSL on the stream. This
515 * function call always returns immediately.
517 * @param handler The handler to be called when the handshake operation
518 * completes. Copies will be made of the handler as required. The equivalent
519 * function signature of the handler must be:
520 * @code void handler(
521 * const boost::system::error_code& error // Result of operation.
525 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
527 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
528 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ShutdownHandler,
529 void (boost::system::error_code))
531 BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler
532 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
534 return async_initiate<ShutdownHandler,
535 void (boost::system::error_code)>(
536 initiate_async_shutdown(this), handler);
539 /// Write some data to the stream.
541 * This function is used to write data on the stream. The function call will
542 * block until one or more bytes of data has been written successfully, or
543 * until an error occurs.
545 * @param buffers The data to be written.
547 * @returns The number of bytes written.
549 * @throws boost::system::system_error Thrown on failure.
551 * @note The write_some operation may not transmit all of the data to the
552 * peer. Consider using the @ref write function if you need to ensure that all
553 * data is written before the blocking operation completes.
555 template <typename ConstBufferSequence>
556 std::size_t write_some(const ConstBufferSequence& buffers)
558 boost::system::error_code ec;
559 std::size_t n = write_some(buffers, ec);
560 boost::asio::detail::throw_error(ec, "write_some");
564 /// Write some data to the stream.
566 * This function is used to write data on the stream. The function call will
567 * block until one or more bytes of data has been written successfully, or
568 * until an error occurs.
570 * @param buffers The data to be written to the stream.
572 * @param ec Set to indicate what error occurred, if any.
574 * @returns The number of bytes written. Returns 0 if an error occurred.
576 * @note The write_some operation may not transmit all of the data to the
577 * peer. Consider using the @ref write function if you need to ensure that all
578 * data is written before the blocking operation completes.
580 template <typename ConstBufferSequence>
581 std::size_t write_some(const ConstBufferSequence& buffers,
582 boost::system::error_code& ec)
584 return detail::io(next_layer_, core_,
585 detail::write_op<ConstBufferSequence>(buffers), ec);
588 /// Start an asynchronous write.
590 * This function is used to asynchronously write one or more bytes of data to
591 * the stream. The function call always returns immediately.
593 * @param buffers The data to be written to the stream. Although the buffers
594 * object may be copied as necessary, ownership of the underlying buffers is
595 * retained by the caller, which must guarantee that they remain valid until
596 * the handler is called.
598 * @param handler The handler to be called when the write operation completes.
599 * Copies will be made of the handler as required. The equivalent function
600 * signature of the handler must be:
601 * @code void handler(
602 * const boost::system::error_code& error, // Result of operation.
603 * std::size_t bytes_transferred // Number of bytes written.
606 * @note The async_write_some operation may not transmit all of the data to
607 * the peer. Consider using the @ref async_write function if you need to
608 * ensure that all data is written before the asynchronous operation
611 template <typename ConstBufferSequence,
612 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
613 std::size_t)) WriteHandler
614 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
615 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
616 void (boost::system::error_code, std::size_t))
617 async_write_some(const ConstBufferSequence& buffers,
618 BOOST_ASIO_MOVE_ARG(WriteHandler) handler
619 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
621 return async_initiate<WriteHandler,
622 void (boost::system::error_code, std::size_t)>(
623 initiate_async_write_some(this), handler, buffers);
626 /// Read some data from the stream.
628 * This function is used to read data from the stream. The function call will
629 * block until one or more bytes of data has been read successfully, or until
632 * @param buffers The buffers into which the data will be read.
634 * @returns The number of bytes read.
636 * @throws boost::system::system_error Thrown on failure.
638 * @note The read_some operation may not read all of the requested number of
639 * bytes. Consider using the @ref read function if you need to ensure that the
640 * requested amount of data is read before the blocking operation completes.
642 template <typename MutableBufferSequence>
643 std::size_t read_some(const MutableBufferSequence& buffers)
645 boost::system::error_code ec;
646 std::size_t n = read_some(buffers, ec);
647 boost::asio::detail::throw_error(ec, "read_some");
651 /// Read some data from the stream.
653 * This function is used to read data from the stream. The function call will
654 * block until one or more bytes of data has been read successfully, or until
657 * @param buffers The buffers into which the data will be read.
659 * @param ec Set to indicate what error occurred, if any.
661 * @returns The number of bytes read. Returns 0 if an error occurred.
663 * @note The read_some operation may not read all of the requested number of
664 * bytes. Consider using the @ref read function if you need to ensure that the
665 * requested amount of data is read before the blocking operation completes.
667 template <typename MutableBufferSequence>
668 std::size_t read_some(const MutableBufferSequence& buffers,
669 boost::system::error_code& ec)
671 return detail::io(next_layer_, core_,
672 detail::read_op<MutableBufferSequence>(buffers), ec);
675 /// Start an asynchronous read.
677 * This function is used to asynchronously read one or more bytes of data from
678 * the stream. The function call always returns immediately.
680 * @param buffers The buffers into which the data will be read. Although the
681 * buffers object may be copied as necessary, ownership of the underlying
682 * buffers is retained by the caller, which must guarantee that they remain
683 * valid until the handler is called.
685 * @param handler The handler to be called when the read operation completes.
686 * Copies will be made of the handler as required. The equivalent function
687 * signature of the handler must be:
688 * @code void handler(
689 * const boost::system::error_code& error, // Result of operation.
690 * std::size_t bytes_transferred // Number of bytes read.
693 * @note The async_read_some operation may not read all of the requested
694 * number of bytes. Consider using the @ref async_read function if you need to
695 * ensure that the requested amount of data is read before the asynchronous
696 * operation completes.
698 template <typename MutableBufferSequence,
699 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
700 std::size_t)) ReadHandler
701 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
702 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
703 void (boost::system::error_code, std::size_t))
704 async_read_some(const MutableBufferSequence& buffers,
705 BOOST_ASIO_MOVE_ARG(ReadHandler) handler
706 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
708 return async_initiate<ReadHandler,
709 void (boost::system::error_code, std::size_t)>(
710 initiate_async_read_some(this), handler, buffers);
714 class initiate_async_handshake
717 typedef typename stream::executor_type executor_type;
719 explicit initiate_async_handshake(stream* self)
724 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
726 return self_->get_executor();
729 template <typename HandshakeHandler>
730 void operator()(BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler,
731 handshake_type type) const
733 // If you get an error on the following line it means that your handler
734 // does not meet the documented type requirements for a HandshakeHandler.
735 BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
737 boost::asio::detail::non_const_lvalue<HandshakeHandler> handler2(handler);
738 detail::async_io(self_->next_layer_, self_->core_,
739 detail::handshake_op(type), handler2.value);
746 class initiate_async_buffered_handshake
749 typedef typename stream::executor_type executor_type;
751 explicit initiate_async_buffered_handshake(stream* self)
756 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
758 return self_->get_executor();
761 template <typename BufferedHandshakeHandler, typename ConstBufferSequence>
762 void operator()(BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler,
763 handshake_type type, const ConstBufferSequence& buffers) const
765 // If you get an error on the following line it means that your
766 // handler does not meet the documented type requirements for a
767 // BufferedHandshakeHandler.
768 BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK(
769 BufferedHandshakeHandler, handler) type_check;
771 boost::asio::detail::non_const_lvalue<
772 BufferedHandshakeHandler> handler2(handler);
773 detail::async_io(self_->next_layer_, self_->core_,
774 detail::buffered_handshake_op<ConstBufferSequence>(type, buffers),
782 class initiate_async_shutdown
785 typedef typename stream::executor_type executor_type;
787 explicit initiate_async_shutdown(stream* self)
792 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
794 return self_->get_executor();
797 template <typename ShutdownHandler>
798 void operator()(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler) const
800 // If you get an error on the following line it means that your handler
801 // does not meet the documented type requirements for a ShutdownHandler.
802 BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(ShutdownHandler, handler) type_check;
804 boost::asio::detail::non_const_lvalue<ShutdownHandler> handler2(handler);
805 detail::async_io(self_->next_layer_, self_->core_,
806 detail::shutdown_op(), handler2.value);
813 class initiate_async_write_some
816 typedef typename stream::executor_type executor_type;
818 explicit initiate_async_write_some(stream* self)
823 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
825 return self_->get_executor();
828 template <typename WriteHandler, typename ConstBufferSequence>
829 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
830 const ConstBufferSequence& buffers) const
832 // If you get an error on the following line it means that your handler
833 // does not meet the documented type requirements for a WriteHandler.
834 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
836 boost::asio::detail::non_const_lvalue<WriteHandler> handler2(handler);
837 detail::async_io(self_->next_layer_, self_->core_,
838 detail::write_op<ConstBufferSequence>(buffers), handler2.value);
845 class initiate_async_read_some
848 typedef typename stream::executor_type executor_type;
850 explicit initiate_async_read_some(stream* self)
855 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
857 return self_->get_executor();
860 template <typename ReadHandler, typename MutableBufferSequence>
861 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
862 const MutableBufferSequence& buffers) const
864 // If you get an error on the following line it means that your handler
865 // does not meet the documented type requirements for a ReadHandler.
866 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
868 boost::asio::detail::non_const_lvalue<ReadHandler> handler2(handler);
869 detail::async_io(self_->next_layer_, self_->core_,
870 detail::read_op<MutableBufferSequence>(buffers), handler2.value);
878 detail::stream_core core_;
885 #include <boost/asio/detail/pop_options.hpp>
887 #endif // BOOST_ASIO_SSL_STREAM_HPP