diff --git a/doc/quickref.xml b/doc/quickref.xml
index d025b356..7662a357 100644
--- a/doc/quickref.xml
+++ b/doc/quickref.xml
@@ -85,6 +85,7 @@
ping_datastreamreason_string
+ teardown_tagOptions
diff --git a/doc/websocket.qbk b/doc/websocket.qbk
index da2808cc..ff9c235e 100644
--- a/doc/websocket.qbk
+++ b/doc/websocket.qbk
@@ -66,7 +66,7 @@ both Boost.Asio and the WebSocket protocol specification described in
-[section:creating Creating the socket]
+[section:creation Creation]
The interface to Beast's WebSocket implementation is a single template
class [link beast.ref.websocket__stream `beast::websocket::stream`] which
@@ -75,24 +75,40 @@ of [link beast.types.streams.SyncStream [*`SyncReadStream`]] if synchronous
operations are performed, or
[link beast.types.streams.AsyncStream [*`AsyncStream`]] if asynchronous
operations are performed, or both. Arguments supplied during construction are
-passed to next layer's constructor. Here we declare two websockets which have
-ownership of the next layer:
+passed to next layer's constructor. Here we declare a websocket stream over
+a TCP/IP socket with ownership of the socket:
```
boost::asio::io_service ios;
beast::websocket::stream ws(ios);
-
-boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
-beast::websocket::stream<
- boost::asio::ssl::stream> wss(ios, ctx);
```
+[heading Using SSL]
+
+To use WebSockets over SSL, choose an SSL stream for the next layer template
+argument when constructing the stream.
+```
+#include
+#include
+#include
+
+boost::asio::io_service ios;
+boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
+beast::websocket::stream ws(ios, ctx);
+```
+
+[note
+ When creating websocket stream objects using SSL, it is necessary
+ to include the file ``.
+]
+
+[heading Non-owning references]
+
For servers that can handshake in multiple protocols, it may be desired
to wrap an object that already exists. This socket can be moved in:
```
boost::asio::ip::tcp::socket&& sock;
...
- beast::websocket::stream<
- boost::asio::ip::tcp::socket> ws(std::move(sock));
+ beast::websocket::stream ws(std::move(sock));
```
Or, the wrapper can be constructed with a non-owning reference. In
@@ -108,8 +124,7 @@ The layer being wrapped can be accessed through the websocket's "next layer",
permitting callers to interact directly with its interface.
```
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
- beast::websocket::stream<
- boost::asio::ssl::stream> ws(ios, ctx);
+ beast::websocket::stream> ws(ios, ctx);
...
ws.next_layer().shutdown(); // ssl::stream shutdown
```
diff --git a/extras/beast/test/fail_stream.hpp b/extras/beast/test/fail_stream.hpp
index 1c3a34e2..47742d06 100644
--- a/extras/beast/test/fail_stream.hpp
+++ b/extras/beast/test/fail_stream.hpp
@@ -161,19 +161,21 @@ public:
friend
void
- teardown(fail_stream& stream,
- boost::system::error_code& ec)
+ teardown(websocket::teardown_tag,
+ fail_stream& stream,
+ boost::system::error_code& ec)
{
if(stream.pfc_->fail(ec))
return;
- websocket_helpers::call_teardown(stream.next_layer(), ec);
+ beast::websocket_helpers::call_teardown(stream.next_layer(), ec);
}
template
friend
void
- async_teardown(fail_stream& stream,
- TeardownHandler&& handler)
+ async_teardown(websocket::teardown_tag,
+ fail_stream& stream,
+ TeardownHandler&& handler)
{
error_code ec;
if(stream.pfc_->fail(ec))
@@ -182,7 +184,7 @@ public:
bind_handler(std::move(handler), ec));
return;
}
- websocket_helpers::call_async_teardown(
+ beast::websocket_helpers::call_async_teardown(
stream.next_layer(), std::forward(handler));
}
};
diff --git a/include/beast/websocket/impl/ssl.ipp b/include/beast/websocket/impl/ssl.ipp
index 681ecd34..a7cd3259 100644
--- a/include/beast/websocket/impl/ssl.ipp
+++ b/include/beast/websocket/impl/ssl.ipp
@@ -129,7 +129,7 @@ operator()(error_code ec, bool again)
template
void
-teardown(
+teardown(teardown_tag,
boost::asio::ssl::stream& stream,
error_code& ec)
{
@@ -138,7 +138,7 @@ teardown(
template
void
-async_teardown(
+async_teardown(teardown_tag,
boost::asio::ssl::stream& stream,
TeardownHandler&& handler)
{
diff --git a/include/beast/websocket/impl/teardown.ipp b/include/beast/websocket/impl/teardown.ipp
index fa7133b2..1d0389b0 100644
--- a/include/beast/websocket/impl/teardown.ipp
+++ b/include/beast/websocket/impl/teardown.ipp
@@ -128,7 +128,7 @@ operator()(error_code ec, std::size_t, bool again)
inline
void
-teardown(
+teardown(teardown_tag,
boost::asio::ip::tcp::socket& socket,
error_code& ec)
{
@@ -151,7 +151,7 @@ teardown(
template
inline
void
-async_teardown(
+async_teardown(teardown_tag,
boost::asio::ip::tcp::socket& socket,
TeardownHandler&& handler)
{
diff --git a/include/beast/websocket/ssl.hpp b/include/beast/websocket/ssl.hpp
index 5ed57222..ef94ed9a 100644
--- a/include/beast/websocket/ssl.hpp
+++ b/include/beast/websocket/ssl.hpp
@@ -31,7 +31,7 @@ namespace websocket {
*/
template
void
-teardown(
+teardown(teardown_tag,
boost::asio::ssl::stream& stream,
error_code& ec);
@@ -62,7 +62,7 @@ teardown(
template
inline
void
-async_teardown(
+async_teardown(teardown_tag,
boost::asio::ssl::stream& stream,
TeardownHandler&& handler);
diff --git a/include/beast/websocket/teardown.hpp b/include/beast/websocket/teardown.hpp
index ecb6dba3..95a54f5e 100644
--- a/include/beast/websocket/teardown.hpp
+++ b/include/beast/websocket/teardown.hpp
@@ -13,8 +13,17 @@
#include
namespace beast {
+
namespace websocket {
+/** Tag type used to find teardown and async_teardown overloads
+
+ Overloads of @ref teardown and @async_teardown for user defined
+ types must take a value of type @ref teardown_tag in the first
+ argument in order to be found by the implementation.
+*/
+struct teardown_tag {};
+
/** Tear down a connection.
This tears down a connection. The implementation will call
@@ -30,7 +39,19 @@ namespace websocket {
*/
template
void
-teardown(Socket& socket, error_code& ec) = delete;
+teardown(teardown_tag, Socket& socket, error_code& ec)
+{
+/*
+ If you are trying to use OpenSSL and this goes off, you need to
+ add an include for .
+
+ If you are creating an instance of beast::websocket::stream with your
+ own user defined type, you must provide an overload of teardown with
+ the corresponding signature (including the teardown_tag).
+*/
+ static_assert(sizeof(Socket)==-1,
+ "Unknown Socket type in teardown.");
+};
/** Start tearing down a connection.
@@ -49,7 +70,8 @@ teardown(Socket& socket, error_code& ec) = delete;
function signature of the handler must be:
@code void handler(
error_code const& error // result of operation
- ); @endcode
+ );
+ @endcode
Regardless of whether the asynchronous operation completes
immediately or not, the handler will not be invoked from within
this function. Invocation of the handler will be performed in a
@@ -58,57 +80,19 @@ teardown(Socket& socket, error_code& ec) = delete;
*/
template
void
-async_teardown(Socket& socket, TeardownHandler&& handler) = delete;
+async_teardown(teardown_tag, Socket& socket, TeardownHandler&& handler)
+{
+/*
+ If you are trying to use OpenSSL and this goes off, you need to
+ add an include for .
-//------------------------------------------------------------------------------
-
-/** Tear down a `boost::asio::ip::tcp::socket`.
-
- This tears down a connection. The implementation will call
- the overload of this function based on the `Stream` parameter
- used to consruct the socket. When `Stream` is a user defined
- type, and not a `boost::asio::ip::tcp::socket` or any
- `boost::asio::ssl::stream`, callers are responsible for
- providing a suitable overload of this function.
-
- @param socket The socket to tear down.
-
- @param ec Set to the error if any occurred.
+ If you are creating an instance of beast::websocket::stream with your
+ own user defined type, you must provide an overload of teardown with
+ the corresponding signature (including the teardown_tag).
*/
-void
-teardown(
- boost::asio::ip::tcp::socket& socket,
- error_code& ec);
-
-/** Start tearing down a `boost::asio::ip::tcp::socket`.
-
- This begins tearing down a connection asynchronously.
- The implementation will call the overload of this function
- based on the `Stream` parameter used to consruct the socket.
- When `Stream` is a user defined type, and not a
- `boost::asio::ip::tcp::socket` or any `boost::asio::ssl::stream`,
- callers are responsible for providing a suitable overload
- of this function.
-
- @param socket The socket to tear down.
-
- @param handler The handler to be called when the request completes.
- Copies will be made of the handler as required. The equivalent
- function signature of the handler must be:
- @code void handler(
- error_code const& error // result of operation
- ); @endcode
- Regardless of whether the asynchronous operation completes
- immediately or not, the handler will not be invoked from within
- this function. Invocation of the handler will be performed in a
- manner equivalent to using boost::asio::io_service::post().
-
-*/
-template
-void
-async_teardown(
- boost::asio::ip::tcp::socket& socket,
- TeardownHandler&& handler);
+ static_assert(sizeof(Socket)==-1,
+ "Unknown Socket type in async_teardown.");
+}
} // websocket
@@ -127,7 +111,7 @@ void
call_teardown(Socket& socket, error_code& ec)
{
using websocket::teardown;
- teardown(socket, ec);
+ teardown(websocket::teardown_tag{}, socket, ec);
}
template
@@ -136,12 +120,65 @@ void
call_async_teardown(Socket& socket, TeardownHandler&& handler)
{
using websocket::async_teardown;
- async_teardown(socket,
+ async_teardown(websocket::teardown_tag{}, socket,
std::forward(handler));
}
} // websocket_helpers
+//------------------------------------------------------------------------------
+
+namespace websocket {
+
+/** Tear down a `boost::asio::ip::tcp::socket`.
+
+ This tears down a connection. The implementation will call
+ the overload of this function based on the `Stream` parameter
+ used to consruct the socket. When `Stream` is a user defined
+ type, and not a `boost::asio::ip::tcp::socket` or any
+ `boost::asio::ssl::stream`, callers are responsible for
+ providing a suitable overload of this function.
+
+ @param socket The socket to tear down.
+
+ @param ec Set to the error if any occurred.
+*/
+void
+teardown(teardown_tag,
+ boost::asio::ip::tcp::socket& socket, error_code& ec);
+
+/** Start tearing down a `boost::asio::ip::tcp::socket`.
+
+ This begins tearing down a connection asynchronously.
+ The implementation will call the overload of this function
+ based on the `Stream` parameter used to consruct the socket.
+ When `Stream` is a user defined type, and not a
+ `boost::asio::ip::tcp::socket` or any `boost::asio::ssl::stream`,
+ callers are responsible for providing a suitable overload
+ of this function.
+
+ @param socket The socket to tear down.
+
+ @param handler The handler to be called when the request completes.
+ Copies will be made of the handler as required. The equivalent
+ function signature of the handler must be:
+ @code void handler(
+ error_code const& error // result of operation
+ );
+ @endcode
+ Regardless of whether the asynchronous operation completes
+ immediately or not, the handler will not be invoked from within
+ this function. Invocation of the handler will be performed in a
+ manner equivalent to using boost::asio::io_service::post().
+
+*/
+template
+void
+async_teardown(teardown_tag,
+ boost::asio::ip::tcp::socket& socket, TeardownHandler&& handler);
+
+} // websocket
+
} // beast
#include