stream.hpp 25 KB

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