Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

756 lines
25KB

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