diff --git a/CHANGELOG.md b/CHANGELOG.md
index f86b9fac..3ddbffea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
Version 170:
* Add flat_stream to experimental
+* Add ssl_stream to experimental
--------------------------------------------------------------------------------
diff --git a/doc/qbk/02_examples.qbk b/doc/qbk/02_examples.qbk
index 22d0fb14..55363bd9 100644
--- a/doc/qbk/02_examples.qbk
+++ b/doc/qbk/02_examples.qbk
@@ -234,13 +234,6 @@ listed here along with a description of their use:
Authority ("CA") so connecting to an example HTTP server using
a browser may generate security warnings.
]
-][
- [[source_file example/common/ssl_stream.hpp]]
- [
- The `ssl_stream` is a replacement for __ssl_stream__ which
- supports construction from a moved-from socket and is also
- itself move constructible.
- ]
]]
[endsect]
diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml
index 91c92c1a..66694d44 100644
--- a/doc/qbk/quickref.xml
+++ b/doc/qbk/quickref.xml
@@ -299,6 +299,7 @@
Classesflat_stream
+ ssl_stream
diff --git a/example/advanced/server-flex/CMakeLists.txt b/example/advanced/server-flex/CMakeLists.txt
index 21b5f9cb..981ce6b5 100644
--- a/example/advanced/server-flex/CMakeLists.txt
+++ b/example/advanced/server-flex/CMakeLists.txt
@@ -16,7 +16,6 @@ if (OPENSSL_FOUND)
${BOOST_BEAST_FILES}
${PROJECT_SOURCE_DIR}/example/common/detect_ssl.hpp
${PROJECT_SOURCE_DIR}/example/common/server_certificate.hpp
- ${PROJECT_SOURCE_DIR}/example/common/ssl_stream.hpp
Jamfile
advanced_server_flex.cpp
)
diff --git a/example/advanced/server-flex/advanced_server_flex.cpp b/example/advanced/server-flex/advanced_server_flex.cpp
index c9e56a24..75637079 100644
--- a/example/advanced/server-flex/advanced_server_flex.cpp
+++ b/example/advanced/server-flex/advanced_server_flex.cpp
@@ -15,12 +15,12 @@
#include "example/common/detect_ssl.hpp"
#include "example/common/server_certificate.hpp"
-#include "example/common/ssl_stream.hpp"
#include
#include
#include
#include
+#include
#include
#include
#include
@@ -545,7 +545,7 @@ class ssl_websocket_session
: public websocket_session
, public std::enable_shared_from_this
{
- websocket::stream> ws_;
+ websocket::stream> ws_;
boost::asio::strand<
boost::asio::io_context::executor_type> strand_;
bool eof_ = false;
@@ -553,7 +553,7 @@ class ssl_websocket_session
public:
// Create the http_session
explicit
- ssl_websocket_session(ssl_stream stream)
+ ssl_websocket_session(boost::beast::ssl_stream stream)
: websocket_session(
stream.get_executor().context())
, ws_(std::move(stream))
@@ -562,7 +562,7 @@ public:
}
// Called by the base class
- websocket::stream>&
+ websocket::stream>&
ws()
{
return ws_;
@@ -640,7 +640,7 @@ make_websocket_session(
template
void
make_websocket_session(
- ssl_stream stream,
+ boost::beast::ssl_stream stream,
http::request> req)
{
std::make_shared(
@@ -966,7 +966,7 @@ class ssl_http_session
: public http_session
, public std::enable_shared_from_this
{
- ssl_stream stream_;
+ boost::beast::ssl_stream stream_;
boost::asio::strand<
boost::asio::io_context::executor_type> strand_;
bool eof_ = false;
@@ -988,14 +988,14 @@ public:
}
// Called by the base class
- ssl_stream&
+ boost::beast::ssl_stream&
stream()
{
return stream_;
}
// Called by the base class
- ssl_stream
+ boost::beast::ssl_stream
release_stream()
{
return std::move(stream_);
diff --git a/include/boost/beast/experimental/core/ssl_stream.hpp b/include/boost/beast/experimental/core/ssl_stream.hpp
new file mode 100644
index 00000000..bc234c42
--- /dev/null
+++ b/include/boost/beast/experimental/core/ssl_stream.hpp
@@ -0,0 +1,728 @@
+//
+// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/beast
+//
+
+#ifndef BOOST_BEAST_CORE_SSL_STREAM_HPP
+#define BOOST_BEAST_CORE_SSL_STREAM_HPP
+
+// This include is necessary to work with `ssl::stream` and `boost::beast::websocket::stream`
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace boost {
+namespace beast {
+
+/** Provides stream-oriented functionality using OpenSSL
+
+ The stream class template provides asynchronous and blocking
+ stream-oriented functionality using SSL.
+
+ @par Thread Safety
+ @e Distinct @e objects: Safe.@n
+ @e Shared @e objects: Unsafe. The application must also ensure that all
+ asynchronous operations are performed within the same implicit or explicit
+ strand.
+
+ @par Example
+ To use this template with a `boost::asio::ip::tcp::socket`, you would write:
+ @code
+ boost::asio::io_context ioc;
+ boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23};
+ boost::beast::ssl_stream sock{ioc, ctx};
+ @endcode
+
+ In addition to providing an interface identical to `boost::asio::ssl::stream`,
+ the wrapper has the following additional properties:
+
+ @li Satisfies @b MoveConstructible
+
+ @li Satisfies @b MoveAssignable
+
+ @li Constructible from a moved socket.
+
+ @li Uses @ref flat_stream internally, as a performance work-around for a
+ limitation of `boost::asio::ssl::stream` when writing buffer sequences
+ having length greater than one.
+
+ @par Concepts:
+ @li AsyncReadStream
+ @li AsyncWriteStream
+ @li Stream
+ @li SyncReadStream
+ @li SyncWriteStream
+*/
+template
+class ssl_stream
+ : public boost::asio::ssl::stream_base
+{
+ using ssl_stream_type = boost::asio::ssl::stream;
+ using stream_type = boost::beast::flat_stream;
+
+ std::unique_ptr p_;
+ boost::asio::ssl::context* ctx_;
+
+public:
+ /// The native handle type of the SSL stream.
+ using native_handle_type =
+ typename ssl_stream_type::native_handle_type;
+
+ /// Structure for use with deprecated impl_type.
+ using impl_struct = typename ssl_stream_type::impl_struct;
+
+ /// The type of the next layer.
+ using next_layer_type = typename ssl_stream_type::next_layer_type;
+
+ /// The type of the lowest layer.
+ using lowest_layer_type = typename ssl_stream_type::lowest_layer_type;
+
+ /// The type of the executor associated with the object.
+ using executor_type = typename stream_type::executor_type;
+
+ /** Construct a stream.
+
+ This constructor creates a stream and initialises the underlying stream
+ object.
+
+ @param arg The argument to be passed to initialise the underlying stream.
+
+ @param ctx The SSL context to be used for the stream.
+ */
+ template
+ ssl_stream(
+ Arg&& arg,
+ boost::asio::ssl::context& ctx)
+ : p_(new stream_type{
+ std::forward(arg), ctx})
+ , ctx_(&ctx)
+ {
+ }
+
+ /// Move Constructor
+ ssl_stream(ssl_stream&& other)
+ : p_(std::move(other.p_))
+ , ctx_(other.ctx_)
+ {
+ }
+
+ /// Move Assignment
+ ssl_stream& operator=(ssl_stream&& other)
+ {
+ p_ = std::move(other.p_);
+ ctx_ = other.ctx_;
+ return *this;
+ }
+
+ /** Get the executor associated with the object.
+
+ This function may be used to obtain the executor object that the stream
+ uses to dispatch handlers for asynchronous operations.
+
+ @return A copy of the executor that stream will use to dispatch handlers.
+ */
+ executor_type
+ get_executor() noexcept
+ {
+ return p_->get_executor();
+ }
+
+ /** Get the underlying implementation in the native type.
+
+ This function may be used to obtain the underlying implementation of the
+ context. This is intended to allow access to context functionality that is
+ not otherwise provided.
+
+ @par Example
+ The native_handle() function returns a pointer of type @c SSL* that is
+ suitable for passing to functions such as @c SSL_get_verify_result and
+ @c SSL_get_peer_certificate:
+ @code
+ boost::beast::ssl_stream ss{ioc, ctx};
+
+ // ... establish connection and perform handshake ...
+
+ if (X509* cert = SSL_get_peer_certificate(ss.native_handle()))
+ {
+ if (SSL_get_verify_result(ss.native_handle()) == X509_V_OK)
+ {
+ // ...
+ }
+ }
+ @endcode
+ */
+ native_handle_type
+ native_handle()
+ {
+ return p_->next_layer().native_handle();
+ }
+
+ /** Get a reference to the next layer.
+
+ This function returns a reference to the next layer in a stack of stream
+ layers.
+
+ @note The next layer is the wrapped stream and not the @ref flat_stream
+ used in the implementation.
+
+ @return A reference to the next layer in the stack of stream layers.
+ Ownership is not transferred to the caller.
+ */
+ next_layer_type const&
+ next_layer() const
+ {
+ return p_->next_layer().next_layer();
+ }
+
+ /** Get a reference to the next layer.
+
+ This function returns a reference to the next layer in a stack of stream
+ layers.
+
+ @note The next layer is the wrapped stream and not the @ref flat_stream
+ used in the implementation.
+
+ @return A reference to the next layer in the stack of stream layers.
+ Ownership is not transferred to the caller.
+ */
+ next_layer_type&
+ next_layer()
+ {
+ return p_->next_layer().next_layer();
+ }
+
+ /** Get a reference to the lowest layer.
+
+ This function returns a reference to the lowest layer in a stack of stream
+ layers.
+
+ @return A reference to the lowest layer in the stack of stream layers.
+ Ownership is not transferred to the caller.
+ */
+ lowest_layer_type&
+ lowest_layer()
+ {
+ return p_->lowest_layer();
+ }
+
+ /** Get a reference to the lowest layer.
+
+ This function returns a reference to the lowest layer in a stack of stream
+ layers.
+
+ @return A reference to the lowest layer in the stack of stream layers.
+ Ownership is not transferred to the caller.
+ */
+ lowest_layer_type const&
+ lowest_layer() const
+ {
+ return p_->lowest_layer();
+ }
+
+ /** Set the peer verification mode.
+
+ This function may be used to configure the peer verification mode used by
+ the stream. The new mode will override the mode inherited from the context.
+
+ @param v A bitmask of peer verification modes.
+
+ @throws boost::system::system_error Thrown on failure.
+
+ @note Calls @c SSL_set_verify.
+ */
+ void
+ set_verify_mode(boost::asio::ssl::verify_mode v)
+ {
+ p_->next_layer().set_verify_mode(v);
+ }
+
+ /** Set the peer verification mode.
+
+ This function may be used to configure the peer verification mode used by
+ the stream. The new mode will override the mode inherited from the context.
+
+ @param v A bitmask of peer verification modes. See @ref verify_mode for
+ available values.
+
+ @param ec Set to indicate what error occurred, if any.
+
+ @note Calls @c SSL_set_verify.
+ */
+ boost::system::error_code
+ set_verify_mode(boost::asio::ssl::verify_mode v,
+ boost::system::error_code& ec)
+ {
+ return p_->next_layer().set_verify_mode(v, ec);
+ }
+
+ /** Set the peer verification depth.
+
+ This function may be used to configure the maximum verification depth
+ allowed by the stream.
+
+ @param depth Maximum depth for the certificate chain verification that
+ shall be allowed.
+
+ @throws boost::system::system_error Thrown on failure.
+
+ @note Calls @c SSL_set_verify_depth.
+ */
+ void
+ set_verify_depth(int depth)
+ {
+ p_->next_layer().set_verify_depth(depth);
+ }
+
+ /** Set the peer verification depth.
+
+ This function may be used to configure the maximum verification depth
+ allowed by the stream.
+
+ @param depth Maximum depth for the certificate chain verification that
+ shall be allowed.
+
+ @param ec Set to indicate what error occurred, if any.
+
+ @note Calls @c SSL_set_verify_depth.
+ */
+ boost::system::error_code
+ set_verify_depth(
+ int depth, boost::system::error_code& ec)
+ {
+ return p_->next_layer().set_verify_depth(depth, ec);
+ }
+
+ /** Set the callback used to verify peer certificates.
+
+ This function is used to specify a callback function that will be called
+ by the implementation when it needs to verify a peer certificate.
+
+ @param callback The function object to be used for verifying a certificate.
+ The function signature of the handler must be:
+ @code bool verify_callback(
+ bool preverified, // True if the certificate passed pre-verification.
+ verify_context& ctx // The peer certificate and other context.
+ ); @endcode
+ The return value of the callback is true if the certificate has passed
+ verification, false otherwise.
+
+ @throws boost::system::system_error Thrown on failure.
+
+ @note Calls @c SSL_set_verify.
+ */
+ template
+ void
+ set_verify_callback(VerifyCallback callback)
+ {
+ p_->next_layer().set_verify_callback(callback);
+ }
+
+ /** Set the callback used to verify peer certificates.
+
+ This function is used to specify a callback function that will be called
+ by the implementation when it needs to verify a peer certificate.
+
+ @param callback The function object to be used for verifying a certificate.
+ The function signature of the handler must be:
+ @code bool verify_callback(
+ bool preverified, // True if the certificate passed pre-verification.
+ boost::asio::verify_context& ctx // The peer certificate and other context.
+ ); @endcode
+ The return value of the callback is true if the certificate has passed
+ verification, false otherwise.
+
+ @param ec Set to indicate what error occurred, if any.
+
+ @note Calls @c SSL_set_verify.
+ */
+ template
+ boost::system::error_code
+ set_verify_callback(VerifyCallback callback,
+ boost::system::error_code& ec)
+ {
+ return p_->next_layer().set_verify_callback(callback, ec);
+ }
+
+ /** Perform SSL handshaking.
+
+ This function is used to perform SSL handshaking on the stream. The
+ function call will block until handshaking is complete or an error occurs.
+
+ @param type The type of handshaking to be performed, i.e. as a client or as
+ a server.
+
+ @throws boost::system::system_error Thrown on failure.
+ */
+ void
+ handshake(handshake_type type)
+ {
+ p_->next_layer().handshake(type);
+ }
+
+ /** Perform SSL handshaking.
+
+ This function is used to perform SSL handshaking on the stream. The
+ function call will block until handshaking is complete or an error occurs.
+
+ @param type The type of handshaking to be performed, i.e. as a client or as
+ a server.
+
+ @param ec Set to indicate what error occurred, if any.
+ */
+ boost::system::error_code
+ handshake(handshake_type type,
+ boost::system::error_code& ec)
+ {
+ return p_->next_layer().handshake(type, ec);
+ }
+
+ /** Perform SSL handshaking.
+
+ This function is used to perform SSL handshaking on the stream. The
+ function call will block until handshaking is complete or an error occurs.
+
+ @param type The type of handshaking to be performed, i.e. as a client or as
+ a server.
+
+ @param buffers The buffered data to be reused for the handshake.
+
+ @throws boost::system::system_error Thrown on failure.
+ */
+ template
+ void
+ handshake(
+ handshake_type type, ConstBufferSequence const& buffers)
+ {
+ p_->next_layer().handshake(type, buffers);
+ }
+
+ /** Perform SSL handshaking.
+
+ This function is used to perform SSL handshaking on the stream. The
+ function call will block until handshaking is complete or an error occurs.
+
+ @param type The type of handshaking to be performed, i.e. as a client or as
+ a server.
+
+ @param buffers The buffered data to be reused for the handshake.
+
+ @param ec Set to indicate what error occurred, if any.
+ */
+ template
+ boost::system::error_code
+ handshake(handshake_type type,
+ ConstBufferSequence const& buffers,
+ boost::system::error_code& ec)
+ {
+ return p_->next_layer().handshake(type, buffers, ec);
+ }
+
+ /** Start an asynchronous SSL handshake.
+
+ This function is used to asynchronously perform an SSL handshake on the
+ stream. This function call always returns immediately.
+
+ @param type The type of handshaking to be performed, i.e. as a client or as
+ a server.
+
+ @param handler The handler to be called when the handshake operation
+ completes. Copies will be made of the handler as required. The equivalent
+ function signature of the handler must be:
+ @code void handler(
+ const boost::system::error_code& error // Result of operation.
+ ); @endcode
+ */
+ template
+ BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler,
+ void(boost::system::error_code))
+ async_handshake(handshake_type type,
+ BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
+ {
+ return p_->next_layer().async_handshake(type,
+ BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
+ }
+
+ /** Start an asynchronous SSL handshake.
+
+ This function is used to asynchronously perform an SSL handshake on the
+ stream. This function call always returns immediately.
+
+ @param type The type of handshaking to be performed, i.e. as a client or as
+ a server.
+
+ @param buffers The buffered data to be reused for the handshake. Although
+ the buffers object may be copied as necessary, ownership of the underlying
+ buffers is retained by the caller, which must guarantee that they remain
+ valid until the handler is called.
+
+ @param handler The handler to be called when the handshake operation
+ completes. Copies will be made of the handler as required. The equivalent
+ function signature of the handler must be:
+ @code void handler(
+ const boost::system::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Amount of buffers used in handshake.
+ ); @endcode
+ */
+ template
+ BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler,
+ void (boost::system::error_code, std::size_t))
+ async_handshake(handshake_type type, ConstBufferSequence const& buffers,
+ BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
+ {
+ return p_->next_layer().async_handshake(type, buffers,
+ BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
+ }
+
+ /** Shut down SSL on the stream.
+
+ This function is used to shut down SSL on the stream. The function call
+ will block until SSL has been shut down or an error occurs.
+
+ @throws boost::system::system_error Thrown on failure.
+ */
+ void
+ shutdown()
+ {
+ p_->next_layer().shutdown();
+ }
+
+ /** Shut down SSL on the stream.
+
+ This function is used to shut down SSL on the stream. The function call
+ will block until SSL has been shut down or an error occurs.
+
+ @param ec Set to indicate what error occurred, if any.
+ */
+ boost::system::error_code
+ shutdown(boost::system::error_code& ec)
+ {
+ return p_->next_layer().shutdown(ec);
+ }
+
+ /** Asynchronously shut down SSL on the stream.
+
+ This function is used to asynchronously shut down SSL on the stream. This
+ function call always returns immediately.
+
+ @param handler The handler to be called when the handshake operation
+ completes. Copies will be made of the handler as required. The equivalent
+ function signature of the handler must be:
+ @code void handler(
+ const boost::system::error_code& error // Result of operation.
+ ); @endcode
+ */
+ template
+ BOOST_ASIO_INITFN_RESULT_TYPE(ShutdownHandler,
+ void (boost::system::error_code))
+ async_shutdown(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler)
+ {
+ return p_->next_layer().async_shutdown(
+ BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler));
+ }
+
+ /** Write some data to the stream.
+
+ This function is used to write data on the stream. The function call will
+ block until one or more bytes of data has been written successfully, or
+ until an error occurs.
+
+ @param buffers The data to be written.
+
+ @returns The number of bytes written.
+
+ @throws boost::system::system_error Thrown on failure.
+
+ @note The `write_some` operation may not transmit all of the data to the
+ peer. Consider using the `boost::asio::write` function if you need to
+ ensure that all data is written before the blocking operation completes.
+ */
+ template
+ std::size_t
+ write_some(ConstBufferSequence const& buffers)
+ {
+ return p_->write_some(buffers);
+ }
+
+ /** Write some data to the stream.
+
+ This function is used to write data on the stream. The function call will
+ block until one or more bytes of data has been written successfully, or
+ until an error occurs.
+
+ @param buffers The data to be written to the stream.
+
+ @param ec Set to indicate what error occurred, if any.
+
+ @returns The number of bytes written. Returns 0 if an error occurred.
+
+ @note The `write_some` operation may not transmit all of the data to the
+ peer. Consider using the `boost::asio::write` function if you need to
+ ensure that all data is written before the blocking operation completes.
+ */
+ template
+ std::size_t
+ write_some(ConstBufferSequence const& buffers,
+ boost::system::error_code& ec)
+ {
+ return p_->write_some(buffers, ec);
+ }
+
+ /** Start an asynchronous write.
+
+ This function is used to asynchronously write one or more bytes of data to
+ the stream. The function call always returns immediately.
+
+ @param buffers The data to be written to the stream. Although the buffers
+ object may be copied as necessary, ownership of the underlying buffers is
+ retained by the caller, which must guarantee that they remain valid until
+ the handler is called.
+
+ @param handler The handler to be called when the write operation completes.
+ Copies will be made of the handler as required. The equivalent function
+ signature of the handler must be:
+ @code void handler(
+ const boost::system::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes written.
+ ); @endcode
+
+ @note The `async_write_some` operation may not transmit all of the data to
+ the peer. Consider using the `boost::asio::async_write` function if you
+ need to ensure that all data is written before the asynchronous operation
+ completes.
+ */
+ template
+ BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t))
+ async_write_some(ConstBufferSequence const& buffers,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+ {
+ return p_->async_write_some(buffers,
+ BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+ }
+
+ /** Read some data from the stream.
+
+ This function is used to read data from the stream. The function call will
+ block until one or more bytes of data has been read successfully, or until
+ an error occurs.
+
+ @param buffers The buffers into which the data will be read.
+
+ @returns The number of bytes read.
+
+ @throws boost::system::system_error Thrown on failure.
+
+ @note The `read_some` operation may not read all of the requested number of
+ bytes. Consider using the `boost::asio::read` function if you need to ensure
+ that the requested amount of data is read before the blocking operation
+ completes.
+ */
+ template
+ std::size_t
+ read_some(MutableBufferSequence const& buffers)
+ {
+ return p_->read_some(buffers);
+ }
+
+ /** Read some data from the stream.
+
+ This function is used to read data from the stream. The function call will
+ block until one or more bytes of data has been read successfully, or until
+ an error occurs.
+
+ @param buffers The buffers into which the data will be read.
+
+ @param ec Set to indicate what error occurred, if any.
+
+ @returns The number of bytes read. Returns 0 if an error occurred.
+
+ @note The `read_some` operation may not read all of the requested number of
+ bytes. Consider using the `boost::asio::read` function if you need to ensure
+ that the requested amount of data is read before the blocking operation
+ completes.
+ */
+ template
+ std::size_t
+ read_some(MutableBufferSequence const& buffers,
+ boost::system::error_code& ec)
+ {
+ return p_->read_some(buffers, ec);
+ }
+
+ /** Start an asynchronous read.
+
+ This function is used to asynchronously read one or more bytes of data from
+ the stream. The function call always returns immediately.
+
+ @param buffers The buffers into which the data will be read. Although the
+ buffers object may be copied as necessary, ownership of the underlying
+ buffers is retained by the caller, which must guarantee that they remain
+ valid until the handler is called.
+
+ @param handler The handler to be called when the read operation completes.
+ Copies will be made of the handler as required. The equivalent function
+ signature of the handler must be:
+ @code void handler(
+ const boost::system::error_code& error, // Result of operation.
+ std::size_t bytes_transferred // Number of bytes read.
+ ); @endcode
+
+ @note The `async_read_some` operation may not read all of the requested
+ number of bytes. Consider using the `boost::asio::async_read` function
+ if you need to ensure that the requested amount of data is read before
+ the asynchronous operation completes.
+ */
+ template
+ BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void(boost::system::error_code, std::size_t))
+ async_read_some(MutableBufferSequence const& buffers,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ {
+ return p_->async_read_some(buffers,
+ BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+ }
+};
+
+// These hooks are used to inform boost::beast::websocket::stream on
+// how to tear down the connection as part of the WebSocket
+// protocol specifications
+#if ! BOOST_BEAST_DOXYGEN
+template
+void
+teardown(
+ boost::beast::websocket::role_type role,
+ ssl_stream& stream,
+ boost::system::error_code& ec)
+{
+ // Just forward it to the wrapped stream
+ using boost::beast::websocket::teardown;
+ teardown(role, stream.next_layer(), ec);
+}
+
+template
+void
+async_teardown(
+ boost::beast::websocket::role_type role,
+ ssl_stream& stream,
+ TeardownHandler&& handler)
+{
+ // Just forward it to the wrapped stream
+ using boost::beast::websocket::async_teardown;
+ async_teardown(role,
+ stream.next_layer(), std::forward(handler));
+}
+#endif
+
+} // beast
+} // boost
+
+#endif
diff --git a/test/beast/experimental/CMakeLists.txt b/test/beast/experimental/CMakeLists.txt
index ff0765aa..8180577a 100644
--- a/test/beast/experimental/CMakeLists.txt
+++ b/test/beast/experimental/CMakeLists.txt
@@ -18,6 +18,7 @@ add_executable (tests-beast-experimental
${TEST_MAIN}
Jamfile
flat_stream.cpp
+ ssl_stream.cpp
)
set_property(TARGET tests-beast-experimental PROPERTY FOLDER "tests")
diff --git a/test/beast/experimental/Jamfile b/test/beast/experimental/Jamfile
index c7ecbd7b..849265f5 100644
--- a/test/beast/experimental/Jamfile
+++ b/test/beast/experimental/Jamfile
@@ -9,6 +9,7 @@
local SOURCES =
flat_stream.cpp
+ ssl_stream.cpp
;
local RUN_TESTS ;
diff --git a/test/example/common/ssl_stream.cpp b/test/beast/experimental/ssl_stream.cpp
similarity index 87%
rename from test/example/common/ssl_stream.cpp
rename to test/beast/experimental/ssl_stream.cpp
index 75044048..4286539b 100644
--- a/test/example/common/ssl_stream.cpp
+++ b/test/beast/experimental/ssl_stream.cpp
@@ -10,6 +10,6 @@
#if BOOST_BEAST_USE_OPENSSL
// Test that header file is self-contained.
-#include "example/common/ssl_stream.hpp"
+#include
#endif
diff --git a/test/example/common/CMakeLists.txt b/test/example/common/CMakeLists.txt
index f020d313..7b320f08 100644
--- a/test/example/common/CMakeLists.txt
+++ b/test/example/common/CMakeLists.txt
@@ -23,7 +23,6 @@ add_executable (tests-example-common
root_certificates.cpp
server_certificate.cpp
session_alloc.cpp
- ssl_stream.cpp
)
set_property(TARGET tests-example-common PROPERTY FOLDER "tests")
\ No newline at end of file
diff --git a/test/example/common/Jamfile b/test/example/common/Jamfile
index 719deba0..76ba448e 100644
--- a/test/example/common/Jamfile
+++ b/test/example/common/Jamfile
@@ -12,7 +12,6 @@ local SOURCES =
root_certificates.cpp
server_certificate.cpp
session_alloc.cpp
- ssl_stream.cpp
;
local RUN_TESTS ;