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