]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/asio/include/boost/asio/ssl/stream.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / asio / include / boost / asio / ssl / stream.hpp
CommitLineData
7c673cae
FG
1//
2// ssl/stream.hpp
3// ~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
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)
9//
10
11#ifndef BOOST_ASIO_SSL_STREAM_HPP
12#define BOOST_ASIO_SSL_STREAM_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19
20#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
21# include <boost/asio/ssl/old/stream.hpp>
22#else // defined(BOOST_ASIO_ENABLE_OLD_SSL)
23# include <boost/asio/async_result.hpp>
24# include <boost/asio/detail/buffer_sequence_adapter.hpp>
25# include <boost/asio/detail/handler_type_requirements.hpp>
26# include <boost/asio/detail/noncopyable.hpp>
27# include <boost/asio/detail/type_traits.hpp>
28# include <boost/asio/ssl/context.hpp>
29# include <boost/asio/ssl/detail/buffered_handshake_op.hpp>
30# include <boost/asio/ssl/detail/handshake_op.hpp>
31# include <boost/asio/ssl/detail/io.hpp>
32# include <boost/asio/ssl/detail/read_op.hpp>
33# include <boost/asio/ssl/detail/shutdown_op.hpp>
34# include <boost/asio/ssl/detail/stream_core.hpp>
35# include <boost/asio/ssl/detail/write_op.hpp>
36# include <boost/asio/ssl/stream_base.hpp>
37#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
38
39#include <boost/asio/detail/push_options.hpp>
40
41namespace boost {
42namespace asio {
43namespace ssl {
44
45#if defined(BOOST_ASIO_ENABLE_OLD_SSL)
46
47using boost::asio::ssl::old::stream;
48
49#else // defined(BOOST_ASIO_ENABLE_OLD_SSL)
50
51/// Provides stream-oriented functionality using SSL.
52/**
53 * The stream class template provides asynchronous and blocking stream-oriented
54 * functionality using SSL.
55 *
56 * @par Thread Safety
57 * @e Distinct @e objects: Safe.@n
58 * @e Shared @e objects: Unsafe. The application must also ensure that all
59 * asynchronous operations are performed within the same implicit or explicit
60 * strand.
61 *
62 * @par Example
63 * To use the SSL stream template with an ip::tcp::socket, you would write:
64 * @code
65 * boost::asio::io_service io_service;
66 * boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
67 * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(io_service, ctx);
68 * @endcode
69 *
70 * @par Concepts:
71 * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
72 */
73template <typename Stream>
74class stream :
75 public stream_base,
76 private noncopyable
77{
78public:
79 /// The native handle type of the SSL stream.
80 typedef SSL* native_handle_type;
81
82 /// Structure for use with deprecated impl_type.
83 struct impl_struct
84 {
85 SSL* ssl;
86 };
87
88 /// (Deprecated: Use native_handle_type.) The underlying implementation type.
89 typedef impl_struct* impl_type;
90
91 /// The type of the next layer.
92 typedef typename remove_reference<Stream>::type next_layer_type;
93
94 /// The type of the lowest layer.
95 typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
96
97 /// Construct a stream.
98 /**
99 * This constructor creates a stream and initialises the underlying stream
100 * object.
101 *
102 * @param arg The argument to be passed to initialise the underlying stream.
103 *
104 * @param ctx The SSL context to be used for the stream.
105 */
106 template <typename Arg>
107 stream(Arg& arg, context& ctx)
108 : next_layer_(arg),
109 core_(ctx.native_handle(), next_layer_.lowest_layer().get_io_service())
110 {
111 backwards_compatible_impl_.ssl = core_.engine_.native_handle();
112 }
113
114 /// Destructor.
115 ~stream()
116 {
117 }
118
119 /// Get the io_service associated with the object.
120 /**
121 * This function may be used to obtain the io_service object that the stream
122 * uses to dispatch handlers for asynchronous operations.
123 *
124 * @return A reference to the io_service object that stream will use to
125 * dispatch handlers. Ownership is not transferred to the caller.
126 */
127 boost::asio::io_service& get_io_service()
128 {
129 return next_layer_.lowest_layer().get_io_service();
130 }
131
132 /// Get the underlying implementation in the native type.
133 /**
134 * This function may be used to obtain the underlying implementation of the
135 * context. This is intended to allow access to context functionality that is
136 * not otherwise provided.
137 *
138 * @par Example
139 * The native_handle() function returns a pointer of type @c SSL* that is
140 * suitable for passing to functions such as @c SSL_get_verify_result and
141 * @c SSL_get_peer_certificate:
142 * @code
143 * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(io_service, ctx);
144 *
145 * // ... establish connection and perform handshake ...
146 *
147 * if (X509* cert = SSL_get_peer_certificate(sock.native_handle()))
148 * {
149 * if (SSL_get_verify_result(sock.native_handle()) == X509_V_OK)
150 * {
151 * // ...
152 * }
153 * }
154 * @endcode
155 */
156 native_handle_type native_handle()
157 {
158 return core_.engine_.native_handle();
159 }
160
161 /// (Deprecated: Use native_handle().) Get the underlying implementation in
162 /// the native type.
163 /**
164 * This function may be used to obtain the underlying implementation of the
165 * context. This is intended to allow access to stream functionality that is
166 * not otherwise provided.
167 */
168 impl_type impl()
169 {
170 return &backwards_compatible_impl_;
171 }
172
173 /// Get a reference to the next layer.
174 /**
175 * This function returns a reference to the next layer in a stack of stream
176 * layers.
177 *
178 * @return A reference to the next layer in the stack of stream layers.
179 * Ownership is not transferred to the caller.
180 */
181 const next_layer_type& next_layer() const
182 {
183 return next_layer_;
184 }
185
186 /// Get a reference to the next layer.
187 /**
188 * This function returns a reference to the next layer in a stack of stream
189 * layers.
190 *
191 * @return A reference to the next layer in the stack of stream layers.
192 * Ownership is not transferred to the caller.
193 */
194 next_layer_type& next_layer()
195 {
196 return next_layer_;
197 }
198
199 /// Get a reference to the lowest layer.
200 /**
201 * This function returns a reference to the lowest layer in a stack of
202 * stream layers.
203 *
204 * @return A reference to the lowest layer in the stack of stream layers.
205 * Ownership is not transferred to the caller.
206 */
207 lowest_layer_type& lowest_layer()
208 {
209 return next_layer_.lowest_layer();
210 }
211
212 /// Get a reference to the lowest layer.
213 /**
214 * This function returns a reference to the lowest layer in a stack of
215 * stream layers.
216 *
217 * @return A reference to the lowest layer in the stack of stream layers.
218 * Ownership is not transferred to the caller.
219 */
220 const lowest_layer_type& lowest_layer() const
221 {
222 return next_layer_.lowest_layer();
223 }
224
225 /// Set the peer verification mode.
226 /**
227 * This function may be used to configure the peer verification mode used by
228 * the stream. The new mode will override the mode inherited from the context.
229 *
230 * @param v A bitmask of peer verification modes. See @ref verify_mode for
231 * available values.
232 *
233 * @throws boost::system::system_error Thrown on failure.
234 *
235 * @note Calls @c SSL_set_verify.
236 */
237 void set_verify_mode(verify_mode v)
238 {
239 boost::system::error_code ec;
240 set_verify_mode(v, ec);
241 boost::asio::detail::throw_error(ec, "set_verify_mode");
242 }
243
244 /// Set the peer verification mode.
245 /**
246 * This function may be used to configure the peer verification mode used by
247 * the stream. The new mode will override the mode inherited from the context.
248 *
249 * @param v A bitmask of peer verification modes. See @ref verify_mode for
250 * available values.
251 *
252 * @param ec Set to indicate what error occurred, if any.
253 *
254 * @note Calls @c SSL_set_verify.
255 */
256 boost::system::error_code set_verify_mode(
257 verify_mode v, boost::system::error_code& ec)
258 {
259 return core_.engine_.set_verify_mode(v, ec);
260 }
261
262 /// Set the peer verification depth.
263 /**
264 * This function may be used to configure the maximum verification depth
265 * allowed by the stream.
266 *
267 * @param depth Maximum depth for the certificate chain verification that
268 * shall be allowed.
269 *
270 * @throws boost::system::system_error Thrown on failure.
271 *
272 * @note Calls @c SSL_set_verify_depth.
273 */
274 void set_verify_depth(int depth)
275 {
276 boost::system::error_code ec;
277 set_verify_depth(depth, ec);
278 boost::asio::detail::throw_error(ec, "set_verify_depth");
279 }
280
281 /// Set the peer verification depth.
282 /**
283 * This function may be used to configure the maximum verification depth
284 * allowed by the stream.
285 *
286 * @param depth Maximum depth for the certificate chain verification that
287 * shall be allowed.
288 *
289 * @param ec Set to indicate what error occurred, if any.
290 *
291 * @note Calls @c SSL_set_verify_depth.
292 */
293 boost::system::error_code set_verify_depth(
294 int depth, boost::system::error_code& ec)
295 {
296 return core_.engine_.set_verify_depth(depth, ec);
297 }
298
299 /// Set the callback used to verify peer certificates.
300 /**
301 * This function is used to specify a callback function that will be called
302 * by the implementation when it needs to verify a peer certificate.
303 *
304 * @param callback The function object to be used for verifying a certificate.
305 * The function signature of the handler must be:
306 * @code bool verify_callback(
307 * bool preverified, // True if the certificate passed pre-verification.
308 * verify_context& ctx // The peer certificate and other context.
309 * ); @endcode
310 * The return value of the callback is true if the certificate has passed
311 * verification, false otherwise.
312 *
313 * @throws boost::system::system_error Thrown on failure.
314 *
315 * @note Calls @c SSL_set_verify.
316 */
317 template <typename VerifyCallback>
318 void set_verify_callback(VerifyCallback callback)
319 {
320 boost::system::error_code ec;
321 this->set_verify_callback(callback, ec);
322 boost::asio::detail::throw_error(ec, "set_verify_callback");
323 }
324
325 /// Set the callback used to verify peer certificates.
326 /**
327 * This function is used to specify a callback function that will be called
328 * by the implementation when it needs to verify a peer certificate.
329 *
330 * @param callback The function object to be used for verifying a certificate.
331 * The function signature of the handler must be:
332 * @code bool verify_callback(
333 * bool preverified, // True if the certificate passed pre-verification.
334 * verify_context& ctx // The peer certificate and other context.
335 * ); @endcode
336 * The return value of the callback is true if the certificate has passed
337 * verification, false otherwise.
338 *
339 * @param ec Set to indicate what error occurred, if any.
340 *
341 * @note Calls @c SSL_set_verify.
342 */
343 template <typename VerifyCallback>
344 boost::system::error_code set_verify_callback(VerifyCallback callback,
345 boost::system::error_code& ec)
346 {
347 return core_.engine_.set_verify_callback(
348 new detail::verify_callback<VerifyCallback>(callback), ec);
349 }
350
351 /// Perform SSL handshaking.
352 /**
353 * This function is used to perform SSL handshaking on the stream. The
354 * function call will block until handshaking is complete or an error occurs.
355 *
356 * @param type The type of handshaking to be performed, i.e. as a client or as
357 * a server.
358 *
359 * @throws boost::system::system_error Thrown on failure.
360 */
361 void handshake(handshake_type type)
362 {
363 boost::system::error_code ec;
364 handshake(type, ec);
365 boost::asio::detail::throw_error(ec, "handshake");
366 }
367
368 /// Perform SSL handshaking.
369 /**
370 * This function is used to perform SSL handshaking on the stream. The
371 * function call will block until handshaking is complete or an error occurs.
372 *
373 * @param type The type of handshaking to be performed, i.e. as a client or as
374 * a server.
375 *
376 * @param ec Set to indicate what error occurred, if any.
377 */
378 boost::system::error_code handshake(handshake_type type,
379 boost::system::error_code& ec)
380 {
381 detail::io(next_layer_, core_, detail::handshake_op(type), ec);
382 return ec;
383 }
384
385 /// Perform SSL handshaking.
386 /**
387 * This function is used to perform SSL handshaking on the stream. The
388 * function call will block until handshaking is complete or an error occurs.
389 *
390 * @param type The type of handshaking to be performed, i.e. as a client or as
391 * a server.
392 *
393 * @param buffers The buffered data to be reused for the handshake.
394 *
395 * @throws boost::system::system_error Thrown on failure.
396 */
397 template <typename ConstBufferSequence>
398 void handshake(handshake_type type, const ConstBufferSequence& buffers)
399 {
400 boost::system::error_code ec;
401 handshake(type, buffers, ec);
402 boost::asio::detail::throw_error(ec, "handshake");
403 }
404
405 /// Perform SSL handshaking.
406 /**
407 * This function is used to perform SSL handshaking on the stream. The
408 * function call will block until handshaking is complete or an error occurs.
409 *
410 * @param type The type of handshaking to be performed, i.e. as a client or as
411 * a server.
412 *
413 * @param buffers The buffered data to be reused for the handshake.
414 *
415 * @param ec Set to indicate what error occurred, if any.
416 */
417 template <typename ConstBufferSequence>
418 boost::system::error_code handshake(handshake_type type,
419 const ConstBufferSequence& buffers, boost::system::error_code& ec)
420 {
421 detail::io(next_layer_, core_,
422 detail::buffered_handshake_op<ConstBufferSequence>(type, buffers), ec);
423 return ec;
424 }
425
426 /// Start an asynchronous SSL handshake.
427 /**
428 * This function is used to asynchronously perform an SSL handshake on the
429 * stream. This function call always returns immediately.
430 *
431 * @param type The type of handshaking to be performed, i.e. as a client or as
432 * a server.
433 *
434 * @param handler The handler to be called when the handshake operation
435 * completes. Copies will be made of the handler as required. The equivalent
436 * function signature of the handler must be:
437 * @code void handler(
438 * const boost::system::error_code& error // Result of operation.
439 * ); @endcode
440 */
441 template <typename HandshakeHandler>
442 BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler,
443 void (boost::system::error_code))
444 async_handshake(handshake_type type,
445 BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
446 {
447 // If you get an error on the following line it means that your handler does
448 // not meet the documented type requirements for a HandshakeHandler.
449 BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
450
451 boost::asio::detail::async_result_init<
452 HandshakeHandler, void (boost::system::error_code)> init(
453 BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
454
455 detail::async_io(next_layer_, core_,
456 detail::handshake_op(type), init.handler);
457
458 return init.result.get();
459 }
460
461 /// Start an asynchronous SSL handshake.
462 /**
463 * This function is used to asynchronously perform an SSL handshake on the
464 * stream. This function call always returns immediately.
465 *
466 * @param type The type of handshaking to be performed, i.e. as a client or as
467 * a server.
468 *
469 * @param buffers The buffered data to be reused for the handshake. Although
470 * the buffers object may be copied as necessary, ownership of the underlying
471 * buffers is retained by the caller, which must guarantee that they remain
472 * valid until the handler is called.
473 *
474 * @param handler The handler to be called when the handshake operation
475 * completes. Copies will be made of the handler as required. The equivalent
476 * function signature of the handler must be:
477 * @code void handler(
478 * const boost::system::error_code& error, // Result of operation.
479 * std::size_t bytes_transferred // Amount of buffers used in handshake.
480 * ); @endcode
481 */
482 template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
483 BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler,
484 void (boost::system::error_code, std::size_t))
485 async_handshake(handshake_type type, const ConstBufferSequence& buffers,
486 BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
487 {
488 // If you get an error on the following line it means that your handler does
489 // not meet the documented type requirements for a BufferedHandshakeHandler.
490 BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK(
491 BufferedHandshakeHandler, handler) type_check;
492
493 boost::asio::detail::async_result_init<BufferedHandshakeHandler,
494 void (boost::system::error_code, std::size_t)> init(
495 BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
496
497 detail::async_io(next_layer_, core_,
498 detail::buffered_handshake_op<ConstBufferSequence>(type, buffers),
499 init.handler);
500
501 return init.result.get();
502 }
503
504 /// Shut down SSL on the stream.
505 /**
506 * This function is used to shut down SSL on the stream. The function call
507 * will block until SSL has been shut down or an error occurs.
508 *
509 * @throws boost::system::system_error Thrown on failure.
510 */
511 void shutdown()
512 {
513 boost::system::error_code ec;
514 shutdown(ec);
515 boost::asio::detail::throw_error(ec, "shutdown");
516 }
517
518 /// Shut down SSL on the stream.
519 /**
520 * This function is used to shut down SSL on the stream. The function call
521 * will block until SSL has been shut down or an error occurs.
522 *
523 * @param ec Set to indicate what error occurred, if any.
524 */
525 boost::system::error_code shutdown(boost::system::error_code& ec)
526 {
527 detail::io(next_layer_, core_, detail::shutdown_op(), ec);
528 return ec;
529 }
530
531 /// Asynchronously shut down SSL on the stream.
532 /**
533 * This function is used to asynchronously shut down SSL on the stream. This
534 * function call always returns immediately.
535 *
536 * @param handler The handler to be called when the handshake operation
537 * completes. Copies will be made of the handler as required. The equivalent
538 * function signature of the handler must be:
539 * @code void handler(
540 * const boost::system::error_code& error // Result of operation.
541 * ); @endcode
542 */
543 template <typename ShutdownHandler>
544 BOOST_ASIO_INITFN_RESULT_TYPE(ShutdownHandler,
545 void (boost::system::error_code))
546 async_shutdown(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler)
547 {
548 // If you get an error on the following line it means that your handler does
549 // not meet the documented type requirements for a ShutdownHandler.
550 BOOST_ASIO_SHUTDOWN_HANDLER_CHECK(ShutdownHandler, handler) type_check;
551
552 boost::asio::detail::async_result_init<
553 ShutdownHandler, void (boost::system::error_code)> init(
554 BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler));
555
556 detail::async_io(next_layer_, core_, detail::shutdown_op(), init.handler);
557
558 return init.result.get();
559 }
560
561 /// Write some data to the stream.
562 /**
563 * This function is used to write data on the stream. The function call will
564 * block until one or more bytes of data has been written successfully, or
565 * until an error occurs.
566 *
567 * @param buffers The data to be written.
568 *
569 * @returns The number of bytes written.
570 *
571 * @throws boost::system::system_error Thrown on failure.
572 *
573 * @note The write_some operation may not transmit all of the data to the
574 * peer. Consider using the @ref write function if you need to ensure that all
575 * data is written before the blocking operation completes.
576 */
577 template <typename ConstBufferSequence>
578 std::size_t write_some(const ConstBufferSequence& buffers)
579 {
580 boost::system::error_code ec;
581 std::size_t n = write_some(buffers, ec);
582 boost::asio::detail::throw_error(ec, "write_some");
583 return n;
584 }
585
586 /// Write some data to the stream.
587 /**
588 * This function is used to write data on the stream. The function call will
589 * block until one or more bytes of data has been written successfully, or
590 * until an error occurs.
591 *
592 * @param buffers The data to be written to the stream.
593 *
594 * @param ec Set to indicate what error occurred, if any.
595 *
596 * @returns The number of bytes written. Returns 0 if an error occurred.
597 *
598 * @note The write_some operation may not transmit all of the data to the
599 * peer. Consider using the @ref write function if you need to ensure that all
600 * data is written before the blocking operation completes.
601 */
602 template <typename ConstBufferSequence>
603 std::size_t write_some(const ConstBufferSequence& buffers,
604 boost::system::error_code& ec)
605 {
606 return detail::io(next_layer_, core_,
607 detail::write_op<ConstBufferSequence>(buffers), ec);
608 }
609
610 /// Start an asynchronous write.
611 /**
612 * This function is used to asynchronously write one or more bytes of data to
613 * the stream. The function call always returns immediately.
614 *
615 * @param buffers The data to be written to the stream. Although the buffers
616 * object may be copied as necessary, ownership of the underlying buffers is
617 * retained by the caller, which must guarantee that they remain valid until
618 * the handler is called.
619 *
620 * @param handler The handler to be called when the write operation completes.
621 * Copies will be made of the handler as required. The equivalent function
622 * signature of the handler must be:
623 * @code void handler(
624 * const boost::system::error_code& error, // Result of operation.
625 * std::size_t bytes_transferred // Number of bytes written.
626 * ); @endcode
627 *
628 * @note The async_write_some operation may not transmit all of the data to
629 * the peer. Consider using the @ref async_write function if you need to
630 * ensure that all data is written before the blocking operation completes.
631 */
632 template <typename ConstBufferSequence, typename WriteHandler>
633 BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
634 void (boost::system::error_code, std::size_t))
635 async_write_some(const ConstBufferSequence& buffers,
636 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
637 {
638 // If you get an error on the following line it means that your handler does
639 // not meet the documented type requirements for a WriteHandler.
640 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
641
642 boost::asio::detail::async_result_init<
643 WriteHandler, void (boost::system::error_code, std::size_t)> init(
644 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
645
646 detail::async_io(next_layer_, core_,
647 detail::write_op<ConstBufferSequence>(buffers), init.handler);
648
649 return init.result.get();
650 }
651
652 /// Read some data from the stream.
653 /**
654 * This function is used to read data from the stream. The function call will
655 * block until one or more bytes of data has been read successfully, or until
656 * an error occurs.
657 *
658 * @param buffers The buffers into which the data will be read.
659 *
660 * @returns The number of bytes read.
661 *
662 * @throws boost::system::system_error Thrown on failure.
663 *
664 * @note The read_some operation may not read all of the requested number of
665 * bytes. Consider using the @ref read function if you need to ensure that the
666 * requested amount of data is read before the blocking operation completes.
667 */
668 template <typename MutableBufferSequence>
669 std::size_t read_some(const MutableBufferSequence& buffers)
670 {
671 boost::system::error_code ec;
672 std::size_t n = read_some(buffers, ec);
673 boost::asio::detail::throw_error(ec, "read_some");
674 return n;
675 }
676
677 /// Read some data from the stream.
678 /**
679 * This function is used to read data from the stream. The function call will
680 * block until one or more bytes of data has been read successfully, or until
681 * an error occurs.
682 *
683 * @param buffers The buffers into which the data will be read.
684 *
685 * @param ec Set to indicate what error occurred, if any.
686 *
687 * @returns The number of bytes read. Returns 0 if an error occurred.
688 *
689 * @note The read_some operation may not read all of the requested number of
690 * bytes. Consider using the @ref read function if you need to ensure that the
691 * requested amount of data is read before the blocking operation completes.
692 */
693 template <typename MutableBufferSequence>
694 std::size_t read_some(const MutableBufferSequence& buffers,
695 boost::system::error_code& ec)
696 {
697 return detail::io(next_layer_, core_,
698 detail::read_op<MutableBufferSequence>(buffers), ec);
699 }
700
701 /// Start an asynchronous read.
702 /**
703 * This function is used to asynchronously read one or more bytes of data from
704 * the stream. The function call always returns immediately.
705 *
706 * @param buffers The buffers into which the data will be read. Although the
707 * buffers object may be copied as necessary, ownership of the underlying
708 * buffers is retained by the caller, which must guarantee that they remain
709 * valid until the handler is called.
710 *
711 * @param handler The handler to be called when the read operation completes.
712 * Copies will be made of the handler as required. The equivalent function
713 * signature of the handler must be:
714 * @code void handler(
715 * const boost::system::error_code& error, // Result of operation.
716 * std::size_t bytes_transferred // Number of bytes read.
717 * ); @endcode
718 *
719 * @note The async_read_some operation may not read all of the requested
720 * number of bytes. Consider using the @ref async_read function if you need to
721 * ensure that the requested amount of data is read before the asynchronous
722 * operation completes.
723 */
724 template <typename MutableBufferSequence, typename ReadHandler>
725 BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
726 void (boost::system::error_code, std::size_t))
727 async_read_some(const MutableBufferSequence& buffers,
728 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
729 {
730 // If you get an error on the following line it means that your handler does
731 // not meet the documented type requirements for a ReadHandler.
732 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
733
734 boost::asio::detail::async_result_init<
735 ReadHandler, void (boost::system::error_code, std::size_t)> init(
736 BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
737
738 detail::async_io(next_layer_, core_,
739 detail::read_op<MutableBufferSequence>(buffers), init.handler);
740
741 return init.result.get();
742 }
743
744private:
745 Stream next_layer_;
746 detail::stream_core core_;
747 impl_struct backwards_compatible_impl_;
748};
749
750#endif // defined(BOOST_ASIO_ENABLE_OLD_SSL)
751
752} // namespace ssl
753} // namespace asio
754} // namespace boost
755
756#include <boost/asio/detail/pop_options.hpp>
757
758#endif // BOOST_ASIO_SSL_STREAM_HPP