mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 04:47:29 +02:00
Add teardown_role for correct TIME_WAIT behavior (API Change):
* teardown_tag is replaced with teardown_role, a client/server flag used to determine whether the shutdown is performed before or after reading the EOF. This is in accordance with RFC6455 7.1.1: https://tools.ietf.org/html/rfc6455#section-7.1.1 Actions Required: * Modify signatures of teardown and async_teardown to use teardown_role instead of teardown_tag * Change calls to teardown and async_teardown to pass the correct role: client or server depending on context.
This commit is contained in:
@ -23,6 +23,8 @@ API Changes:
|
|||||||
|
|
||||||
* drain_buffer is removed
|
* drain_buffer is removed
|
||||||
|
|
||||||
|
* role_type replaces teardown_tag
|
||||||
|
|
||||||
Actions Required:
|
Actions Required:
|
||||||
|
|
||||||
* Remove calling code which drains the connection after
|
* Remove calling code which drains the connection after
|
||||||
@ -32,6 +34,12 @@ Actions Required:
|
|||||||
it is no longer necessary to manually drain the connection
|
it is no longer necessary to manually drain the connection
|
||||||
after closing.
|
after closing.
|
||||||
|
|
||||||
|
* Modify signatures of teardown and async_teardown to use
|
||||||
|
role_type instead of teardown_tag
|
||||||
|
|
||||||
|
* Change calls to teardown and async_teardown to pass the
|
||||||
|
correct role_type, client or server, depending on context.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Version 99:
|
Version 99:
|
||||||
|
@ -147,6 +147,7 @@
|
|||||||
<member><link linkend="beast.ref.boost__beast__websocket__close_code">close_code</link></member>
|
<member><link linkend="beast.ref.boost__beast__websocket__close_code">close_code</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__websocket__error">error</link></member>
|
<member><link linkend="beast.ref.boost__beast__websocket__error">error</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__websocket__frame_type">frame_type</link></member>
|
<member><link linkend="beast.ref.boost__beast__websocket__frame_type">frame_type</link></member>
|
||||||
|
<member><link linkend="beast.ref.boost__beast__websocket__role_type">role_type</link></member>
|
||||||
</simplelist>
|
</simplelist>
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
@ -294,14 +294,14 @@ public:
|
|||||||
template<class SyncStream>
|
template<class SyncStream>
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
teardown(boost::beast::websocket::teardown_tag,
|
teardown(boost::beast::websocket::role_type,
|
||||||
ssl_stream<SyncStream>& stream,
|
ssl_stream<SyncStream>& stream,
|
||||||
boost::system::error_code& ec);
|
boost::system::error_code& ec);
|
||||||
|
|
||||||
template<class AsyncStream, class TeardownHandler>
|
template<class AsyncStream, class TeardownHandler>
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
async_teardown(boost::beast::websocket::teardown_tag,
|
async_teardown(boost::beast::websocket::role_type,
|
||||||
ssl_stream<AsyncStream>& stream, TeardownHandler&& handler);
|
ssl_stream<AsyncStream>& stream, TeardownHandler&& handler);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -312,24 +312,27 @@ public:
|
|||||||
template<class SyncStream>
|
template<class SyncStream>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
teardown(boost::beast::websocket::teardown_tag,
|
teardown(
|
||||||
|
boost::beast::websocket::role_type role,
|
||||||
ssl_stream<SyncStream>& stream,
|
ssl_stream<SyncStream>& stream,
|
||||||
boost::system::error_code& ec)
|
boost::system::error_code& ec)
|
||||||
{
|
{
|
||||||
// Just forward it to the wrapped ssl::stream
|
// Just forward it to the wrapped ssl::stream
|
||||||
using boost::beast::websocket::teardown;
|
using boost::beast::websocket::teardown;
|
||||||
teardown(boost::beast::websocket::teardown_tag{}, *stream.p_, ec);
|
teardown(role, *stream.p_, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class AsyncStream, class TeardownHandler>
|
template<class AsyncStream, class TeardownHandler>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
async_teardown(boost::beast::websocket::teardown_tag,
|
async_teardown(
|
||||||
ssl_stream<AsyncStream>& stream, TeardownHandler&& handler)
|
boost::beast::websocket::role_type role,
|
||||||
|
ssl_stream<AsyncStream>& stream,
|
||||||
|
TeardownHandler&& handler)
|
||||||
{
|
{
|
||||||
// Just forward it to the wrapped ssl::stream
|
// Just forward it to the wrapped ssl::stream
|
||||||
using boost::beast::websocket::async_teardown;
|
using boost::beast::websocket::async_teardown;
|
||||||
async_teardown(boost::beast::websocket::teardown_tag{},
|
async_teardown(role,
|
||||||
*stream.p_, std::forward<TeardownHandler>(handler));
|
*stream.p_, std::forward<TeardownHandler>(handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,8 @@ operator()(error_code ec, std::size_t)
|
|||||||
go_teardown:
|
go_teardown:
|
||||||
BOOST_ASSERT(ws_.wr_block_ == tok_);
|
BOOST_ASSERT(ws_.wr_block_ == tok_);
|
||||||
step_ = do_teardown + 1;
|
step_ = do_teardown + 1;
|
||||||
websocket_helpers::call_async_teardown(
|
using beast::websocket::async_teardown;
|
||||||
|
async_teardown(ws_.role_,
|
||||||
ws_.stream_, std::move(*this));
|
ws_.stream_, std::move(*this));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -234,7 +235,8 @@ do_fail(
|
|||||||
if(failed_)
|
if(failed_)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
websocket_helpers::call_teardown(stream_, ec);
|
using beast::websocket::teardown;
|
||||||
|
teardown(role_, stream_, ec);
|
||||||
if(ec == boost::asio::error::eof)
|
if(ec == boost::asio::error::eof)
|
||||||
{
|
{
|
||||||
// Rationale:
|
// Rationale:
|
||||||
|
@ -33,20 +33,25 @@ Behavior of ssl::stream regarding close_
|
|||||||
|
|
||||||
template<class AsyncStream>
|
template<class AsyncStream>
|
||||||
void
|
void
|
||||||
teardown(teardown_tag,
|
teardown(
|
||||||
|
role_type,
|
||||||
boost::asio::ssl::stream<AsyncStream>& stream,
|
boost::asio::ssl::stream<AsyncStream>& stream,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
stream.shutdown(ec);
|
stream.shutdown(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class AsyncStream, class TeardownHandler>
|
template<
|
||||||
|
class AsyncStream,
|
||||||
|
class TeardownHandler>
|
||||||
void
|
void
|
||||||
async_teardown(teardown_tag,
|
async_teardown(
|
||||||
|
role_type,
|
||||||
boost::asio::ssl::stream<AsyncStream>& stream,
|
boost::asio::ssl::stream<AsyncStream>& stream,
|
||||||
TeardownHandler&& handler)
|
TeardownHandler&& handler)
|
||||||
{
|
{
|
||||||
stream.async_shutdown(std::forward<TeardownHandler>(handler));
|
stream.async_shutdown(
|
||||||
|
std::forward<TeardownHandler>(handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // websocket
|
} // websocket
|
||||||
|
@ -10,8 +10,7 @@
|
|||||||
#ifndef BOOST_BEAST_WEBSOCKET_IMPL_TEARDOWN_IPP
|
#ifndef BOOST_BEAST_WEBSOCKET_IMPL_TEARDOWN_IPP
|
||||||
#define BOOST_BEAST_WEBSOCKET_IMPL_TEARDOWN_IPP
|
#define BOOST_BEAST_WEBSOCKET_IMPL_TEARDOWN_IPP
|
||||||
|
|
||||||
#include <boost/beast/core/async_result.hpp>
|
#include <boost/beast/core/bind_handler.hpp>
|
||||||
#include <boost/beast/core/handler_ptr.hpp>
|
|
||||||
#include <boost/beast/core/type_traits.hpp>
|
#include <boost/beast/core/type_traits.hpp>
|
||||||
#include <boost/asio/handler_alloc_hook.hpp>
|
#include <boost/asio/handler_alloc_hook.hpp>
|
||||||
#include <boost/asio/handler_continuation_hook.hpp>
|
#include <boost/asio/handler_continuation_hook.hpp>
|
||||||
@ -30,35 +29,30 @@ class teardown_tcp_op
|
|||||||
using socket_type =
|
using socket_type =
|
||||||
boost::asio::ip::tcp::socket;
|
boost::asio::ip::tcp::socket;
|
||||||
|
|
||||||
struct data
|
Handler h_;
|
||||||
{
|
socket_type& s_;
|
||||||
bool cont;
|
role_type role_;
|
||||||
socket_type& socket;
|
int step_ = 0;
|
||||||
char buf[2048];
|
|
||||||
int state = 0;
|
|
||||||
|
|
||||||
data(Handler& handler, socket_type& socket_)
|
|
||||||
: socket(socket_)
|
|
||||||
{
|
|
||||||
using boost::asio::asio_handler_is_continuation;
|
|
||||||
cont = asio_handler_is_continuation(std::addressof(handler));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
handler_ptr<data, Handler> d_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
teardown_tcp_op(teardown_tcp_op&& other) = default;
|
||||||
|
teardown_tcp_op(teardown_tcp_op const& other) = default;
|
||||||
|
|
||||||
template<class DeducedHandler>
|
template<class DeducedHandler>
|
||||||
teardown_tcp_op(
|
teardown_tcp_op(
|
||||||
DeducedHandler&& h,
|
DeducedHandler&& h,
|
||||||
socket_type& socket)
|
socket_type& s,
|
||||||
: d_(std::forward<DeducedHandler>(h), socket)
|
role_type role)
|
||||||
|
: h_(std::forward<DeducedHandler>(h))
|
||||||
|
, s_(s)
|
||||||
|
, role_(role)
|
||||||
{
|
{
|
||||||
(*this)(error_code{}, 0, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
operator()(error_code ec, std::size_t, bool again = true);
|
operator()(
|
||||||
|
error_code ec = {},
|
||||||
|
std::size_t bytes_transferred = 0);
|
||||||
|
|
||||||
friend
|
friend
|
||||||
void* asio_handler_allocate(std::size_t size,
|
void* asio_handler_allocate(std::size_t size,
|
||||||
@ -66,7 +60,7 @@ public:
|
|||||||
{
|
{
|
||||||
using boost::asio::asio_handler_allocate;
|
using boost::asio::asio_handler_allocate;
|
||||||
return asio_handler_allocate(
|
return asio_handler_allocate(
|
||||||
size, std::addressof(op->d_.handler()));
|
size, std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend
|
friend
|
||||||
@ -75,13 +69,15 @@ public:
|
|||||||
{
|
{
|
||||||
using boost::asio::asio_handler_deallocate;
|
using boost::asio::asio_handler_deallocate;
|
||||||
asio_handler_deallocate(
|
asio_handler_deallocate(
|
||||||
p, size, std::addressof(op->d_.handler()));
|
p, size, std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend
|
friend
|
||||||
bool asio_handler_is_continuation(teardown_tcp_op* op)
|
bool asio_handler_is_continuation(teardown_tcp_op* op)
|
||||||
{
|
{
|
||||||
return op->d_->cont;
|
using boost::asio::asio_handler_is_continuation;
|
||||||
|
return op->step_ >= 3 ||
|
||||||
|
asio_handler_is_continuation(std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Function>
|
template<class Function>
|
||||||
@ -91,40 +87,58 @@ public:
|
|||||||
{
|
{
|
||||||
using boost::asio::asio_handler_invoke;
|
using boost::asio::asio_handler_invoke;
|
||||||
asio_handler_invoke(
|
asio_handler_invoke(
|
||||||
f, std::addressof(op->d_.handler()));
|
f, std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Handler>
|
template<class Handler>
|
||||||
void
|
void
|
||||||
teardown_tcp_op<Handler>::
|
teardown_tcp_op<Handler>::
|
||||||
operator()(error_code ec, std::size_t, bool again)
|
operator()(error_code ec, std::size_t)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer;
|
using boost::asio::buffer;
|
||||||
auto& d = *d_;
|
using tcp = boost::asio::ip::tcp;
|
||||||
d.cont = d.cont || again;
|
switch(step_)
|
||||||
while(! ec)
|
|
||||||
{
|
{
|
||||||
switch(d.state)
|
case 0:
|
||||||
|
s_.non_blocking(true, ec);
|
||||||
|
if(ec)
|
||||||
{
|
{
|
||||||
case 0:
|
step_ = 1;
|
||||||
d.state = 1;
|
return s_.get_io_service().post(
|
||||||
d.socket.shutdown(
|
bind_handler(std::move(*this), ec, 0));
|
||||||
boost::asio::ip::tcp::socket::shutdown_send, ec);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
d.socket.async_read_some(
|
|
||||||
buffer(d.buf), std::move(*this));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
step_ = 2;
|
||||||
|
if(role_ == role_type::server)
|
||||||
|
s_.shutdown(tcp::socket::shutdown_send, ec);
|
||||||
|
goto do_read;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
step_ = 3;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if(ec != boost::asio::error::would_block)
|
||||||
|
break;
|
||||||
|
{
|
||||||
|
char buf[2048];
|
||||||
|
s_.read_some(
|
||||||
|
boost::asio::buffer(buf), ec);
|
||||||
|
if(ec)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_read:
|
||||||
|
return s_.async_read_some(
|
||||||
|
boost::asio::null_buffers{},
|
||||||
|
std::move(*this));
|
||||||
}
|
}
|
||||||
if(ec == boost::asio::error::eof)
|
if(role_ == role_type::client)
|
||||||
{
|
s_.shutdown(tcp::socket::shutdown_send, ec);
|
||||||
d.socket.close(ec);
|
s_.close(ec);
|
||||||
ec = error_code{};
|
h_(ec);
|
||||||
}
|
|
||||||
d_.invoke(ec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
@ -133,13 +147,15 @@ operator()(error_code ec, std::size_t, bool again)
|
|||||||
|
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
teardown(teardown_tag,
|
teardown(
|
||||||
|
role_type role,
|
||||||
boost::asio::ip::tcp::socket& socket,
|
boost::asio::ip::tcp::socket& socket,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer;
|
using boost::asio::buffer;
|
||||||
socket.shutdown(
|
if(role == role_type::server)
|
||||||
boost::asio::ip::tcp::socket::shutdown_send, ec);
|
socket.shutdown(
|
||||||
|
boost::asio::ip::tcp::socket::shutdown_send, ec);
|
||||||
while(! ec)
|
while(! ec)
|
||||||
{
|
{
|
||||||
char buf[8192];
|
char buf[8192];
|
||||||
@ -148,24 +164,27 @@ teardown(teardown_tag,
|
|||||||
if(! n)
|
if(! n)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(ec == boost::asio::error::eof)
|
if(role == role_type::client)
|
||||||
ec = error_code{};
|
socket.shutdown(
|
||||||
|
boost::asio::ip::tcp::socket::shutdown_send, ec);
|
||||||
socket.close(ec);
|
socket.close(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TeardownHandler>
|
template<class TeardownHandler>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
async_teardown(teardown_tag,
|
async_teardown(
|
||||||
|
role_type role,
|
||||||
boost::asio::ip::tcp::socket& socket,
|
boost::asio::ip::tcp::socket& socket,
|
||||||
TeardownHandler&& handler)
|
TeardownHandler&& handler)
|
||||||
{
|
{
|
||||||
static_assert(beast::is_completion_handler<
|
static_assert(beast::is_completion_handler<
|
||||||
TeardownHandler, void(error_code)>::value,
|
TeardownHandler, void(error_code)>::value,
|
||||||
"TeardownHandler requirements not met");
|
"TeardownHandler requirements not met");
|
||||||
detail::teardown_tcp_op<typename std::decay<
|
detail::teardown_tcp_op<typename std::decay<
|
||||||
TeardownHandler>::type>{std::forward<
|
TeardownHandler>::type>{std::forward<
|
||||||
TeardownHandler>(handler), socket};
|
TeardownHandler>(handler), socket,
|
||||||
|
role}();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // websocket
|
} // websocket
|
||||||
|
59
include/boost/beast/websocket/role.hpp
Normal file
59
include/boost/beast/websocket/role.hpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
//
|
||||||
|
// 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_WEBSOCKET_ROLE_HPP
|
||||||
|
#define BOOST_BEAST_WEBSOCKET_ROLE_HPP
|
||||||
|
|
||||||
|
#include <boost/beast/config.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace beast {
|
||||||
|
namespace websocket {
|
||||||
|
|
||||||
|
/** The role of the websocket stream endpoint.
|
||||||
|
|
||||||
|
Whether the endpoint is a client or server affects the
|
||||||
|
behavior of the <em>Close the WebSocket Connection</em>
|
||||||
|
operation described in rfc6455 section 7.1.1.
|
||||||
|
The shutdown behavior depends on the type of the next
|
||||||
|
layer template parameter used to construct the @ref stream.
|
||||||
|
Other next layer types including user-defined types
|
||||||
|
may implement different role-based behavior when
|
||||||
|
performing the close operation.
|
||||||
|
|
||||||
|
The default implementation for @ref stream when the next
|
||||||
|
layer type is a `boost::asio::ip::tcp::socket` behaves
|
||||||
|
as follows:
|
||||||
|
|
||||||
|
@li In the client role, a TCP/IP shutdown is sent after
|
||||||
|
reading all remaining data on the connection.
|
||||||
|
|
||||||
|
@li In the server role, a TCP/IP shutdown is sent before
|
||||||
|
reading all remaining data on the connection.
|
||||||
|
|
||||||
|
When the next layer type is a `boost::asio::ssl::stream`,
|
||||||
|
the connection is closed by performing the SSL closing
|
||||||
|
handshake corresponding to the role type, client or server.
|
||||||
|
|
||||||
|
@see https://tools.ietf.org/html/rfc6455#section-7.1.1
|
||||||
|
*/
|
||||||
|
enum class role_type
|
||||||
|
{
|
||||||
|
/// The stream is operating as a client.
|
||||||
|
client,
|
||||||
|
|
||||||
|
/// The stream is operating as a server.
|
||||||
|
server
|
||||||
|
};
|
||||||
|
|
||||||
|
} // websocket
|
||||||
|
} // beast
|
||||||
|
} // boost
|
||||||
|
|
||||||
|
#endif
|
@ -28,15 +28,18 @@ namespace websocket {
|
|||||||
`boost::asio::ssl::stream`, callers are responsible for
|
`boost::asio::ssl::stream`, callers are responsible for
|
||||||
providing a suitable overload of this function.
|
providing a suitable overload of this function.
|
||||||
|
|
||||||
|
@param role The role of the local endpoint
|
||||||
|
|
||||||
@param stream The stream to tear down.
|
@param stream The stream to tear down.
|
||||||
|
|
||||||
@param ec Set to the error if any occurred.
|
@param ec Set to the error if any occurred.
|
||||||
*/
|
*/
|
||||||
template<class SyncStream>
|
template<class SyncStream>
|
||||||
void
|
void
|
||||||
teardown(teardown_tag,
|
teardown(
|
||||||
|
role_type role,
|
||||||
boost::asio::ssl::stream<SyncStream>& stream,
|
boost::asio::ssl::stream<SyncStream>& stream,
|
||||||
error_code& ec);
|
error_code& ec);
|
||||||
|
|
||||||
/** Start tearing down a `boost::asio::ssl::stream`.
|
/** Start tearing down a `boost::asio::ssl::stream`.
|
||||||
|
|
||||||
@ -48,6 +51,8 @@ teardown(teardown_tag,
|
|||||||
callers are responsible for providing a suitable overload
|
callers are responsible for providing a suitable overload
|
||||||
of this function.
|
of this function.
|
||||||
|
|
||||||
|
@param role The role of the local endpoint
|
||||||
|
|
||||||
@param stream The stream to tear down.
|
@param stream The stream to tear down.
|
||||||
|
|
||||||
@param handler The handler to be called when the request completes.
|
@param handler The handler to be called when the request completes.
|
||||||
@ -65,9 +70,10 @@ teardown(teardown_tag,
|
|||||||
template<class AsyncStream, class TeardownHandler>
|
template<class AsyncStream, class TeardownHandler>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
async_teardown(teardown_tag,
|
async_teardown(
|
||||||
|
role_type role,
|
||||||
boost::asio::ssl::stream<AsyncStream>& stream,
|
boost::asio::ssl::stream<AsyncStream>& stream,
|
||||||
TeardownHandler&& handler);
|
TeardownHandler&& handler);
|
||||||
|
|
||||||
} // websocket
|
} // websocket
|
||||||
} // beast
|
} // beast
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <boost/beast/config.hpp>
|
#include <boost/beast/config.hpp>
|
||||||
#include <boost/beast/websocket/error.hpp>
|
#include <boost/beast/websocket/error.hpp>
|
||||||
#include <boost/beast/websocket/option.hpp>
|
#include <boost/beast/websocket/option.hpp>
|
||||||
|
#include <boost/beast/websocket/role.hpp>
|
||||||
#include <boost/beast/websocket/rfc6455.hpp>
|
#include <boost/beast/websocket/rfc6455.hpp>
|
||||||
#include <boost/beast/websocket/detail/frame.hpp>
|
#include <boost/beast/websocket/detail/frame.hpp>
|
||||||
#include <boost/beast/websocket/detail/hybi13.hpp>
|
#include <boost/beast/websocket/detail/hybi13.hpp>
|
||||||
@ -145,16 +146,6 @@ class stream
|
|||||||
using control_cb_type =
|
using control_cb_type =
|
||||||
std::function<void(frame_type, string_view)>;
|
std::function<void(frame_type, string_view)>;
|
||||||
|
|
||||||
/// Identifies the role of a WebSockets stream.
|
|
||||||
enum class role_type
|
|
||||||
{
|
|
||||||
/// Stream is operating as a client.
|
|
||||||
client,
|
|
||||||
|
|
||||||
/// Stream is operating as a server.
|
|
||||||
server
|
|
||||||
};
|
|
||||||
|
|
||||||
// State information for the message being received
|
// State information for the message being received
|
||||||
//
|
//
|
||||||
struct rd_t
|
struct rd_t
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
#define BOOST_BEAST_WEBSOCKET_TEARDOWN_HPP
|
#define BOOST_BEAST_WEBSOCKET_TEARDOWN_HPP
|
||||||
|
|
||||||
#include <boost/beast/config.hpp>
|
#include <boost/beast/config.hpp>
|
||||||
#include <boost/beast/websocket/error.hpp>
|
#include <boost/beast/core/error.hpp>
|
||||||
|
#include <boost/beast/websocket/role.hpp>
|
||||||
#include <boost/asio/ip/tcp.hpp>
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
@ -19,15 +20,6 @@ namespace boost {
|
|||||||
namespace beast {
|
namespace beast {
|
||||||
namespace websocket {
|
namespace websocket {
|
||||||
|
|
||||||
/** Tag type used to find @ref beast::websocket::teardown and @ref beast::websocket::async_teardown overloads
|
|
||||||
|
|
||||||
Overloads of @ref beast::websocket::teardown and
|
|
||||||
@ref beast::websocket::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.
|
/** Tear down a connection.
|
||||||
|
|
||||||
This tears down a connection. The implementation will call
|
This tears down a connection. The implementation will call
|
||||||
@ -37,13 +29,18 @@ struct teardown_tag {};
|
|||||||
`boost::asio::ssl::stream`, callers are responsible for
|
`boost::asio::ssl::stream`, callers are responsible for
|
||||||
providing a suitable overload of this function.
|
providing a suitable overload of this function.
|
||||||
|
|
||||||
|
@param role The role of the local endpoint
|
||||||
|
|
||||||
@param socket The socket to tear down.
|
@param socket The socket to tear down.
|
||||||
|
|
||||||
@param ec Set to the error if any occurred.
|
@param ec Set to the error if any occurred.
|
||||||
*/
|
*/
|
||||||
template<class Socket>
|
template<class Socket>
|
||||||
void
|
void
|
||||||
teardown(teardown_tag, Socket& socket, error_code& ec)
|
teardown(
|
||||||
|
role_type role,
|
||||||
|
Socket& socket,
|
||||||
|
error_code& ec)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
If you are trying to use OpenSSL and this goes off, you need to
|
If you are trying to use OpenSSL and this goes off, you need to
|
||||||
@ -51,7 +48,7 @@ teardown(teardown_tag, Socket& socket, error_code& ec)
|
|||||||
|
|
||||||
If you are creating an instance of beast::websocket::stream with your
|
If you are creating an instance of beast::websocket::stream with your
|
||||||
own user defined type, you must provide an overload of teardown with
|
own user defined type, you must provide an overload of teardown with
|
||||||
the corresponding signature (including the teardown_tag).
|
the corresponding signature (including the role_type).
|
||||||
*/
|
*/
|
||||||
static_assert(sizeof(Socket)==-1,
|
static_assert(sizeof(Socket)==-1,
|
||||||
"Unknown Socket type in teardown.");
|
"Unknown Socket type in teardown.");
|
||||||
@ -67,6 +64,8 @@ teardown(teardown_tag, Socket& socket, error_code& ec)
|
|||||||
callers are responsible for providing a suitable overload
|
callers are responsible for providing a suitable overload
|
||||||
of this function.
|
of this function.
|
||||||
|
|
||||||
|
@param role The role of the local endpoint
|
||||||
|
|
||||||
@param socket The socket to tear down.
|
@param socket The socket to tear down.
|
||||||
|
|
||||||
@param handler The handler to be called when the request completes.
|
@param handler The handler to be called when the request completes.
|
||||||
@ -82,9 +81,14 @@ teardown(teardown_tag, Socket& socket, error_code& ec)
|
|||||||
manner equivalent to using boost::asio::io_service::post().
|
manner equivalent to using boost::asio::io_service::post().
|
||||||
|
|
||||||
*/
|
*/
|
||||||
template<class Socket, class TeardownHandler>
|
template<
|
||||||
|
class Socket,
|
||||||
|
class TeardownHandler>
|
||||||
void
|
void
|
||||||
async_teardown(teardown_tag, Socket& socket, TeardownHandler&& handler)
|
async_teardown(
|
||||||
|
role_type role,
|
||||||
|
Socket& socket,
|
||||||
|
TeardownHandler&& handler)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
If you are trying to use OpenSSL and this goes off, you need to
|
If you are trying to use OpenSSL and this goes off, you need to
|
||||||
@ -92,7 +96,7 @@ async_teardown(teardown_tag, Socket& socket, TeardownHandler&& handler)
|
|||||||
|
|
||||||
If you are creating an instance of beast::websocket::stream with your
|
If you are creating an instance of beast::websocket::stream with your
|
||||||
own user defined type, you must provide an overload of teardown with
|
own user defined type, you must provide an overload of teardown with
|
||||||
the corresponding signature (including the teardown_tag).
|
the corresponding signature (including the role_type).
|
||||||
*/
|
*/
|
||||||
static_assert(sizeof(Socket)==-1,
|
static_assert(sizeof(Socket)==-1,
|
||||||
"Unknown Socket type in async_teardown.");
|
"Unknown Socket type in async_teardown.");
|
||||||
@ -102,36 +106,6 @@ async_teardown(teardown_tag, Socket& socket, TeardownHandler&& handler)
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace websocket_helpers {
|
|
||||||
|
|
||||||
// Calls to teardown and async_teardown must be made from
|
|
||||||
// a namespace that does not contain any overloads of these
|
|
||||||
// functions. The websocket_helpers namespace is defined here
|
|
||||||
// for that purpose.
|
|
||||||
|
|
||||||
template<class Socket>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
call_teardown(Socket& socket, error_code& ec)
|
|
||||||
{
|
|
||||||
using websocket::teardown;
|
|
||||||
teardown(websocket::teardown_tag{}, socket, ec);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Socket, class TeardownHandler>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
call_async_teardown(Socket& socket, TeardownHandler&& handler)
|
|
||||||
{
|
|
||||||
using websocket::async_teardown;
|
|
||||||
async_teardown(websocket::teardown_tag{}, socket,
|
|
||||||
std::forward<TeardownHandler>(handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // websocket_helpers
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace websocket {
|
namespace websocket {
|
||||||
|
|
||||||
/** Tear down a `boost::asio::ip::tcp::socket`.
|
/** Tear down a `boost::asio::ip::tcp::socket`.
|
||||||
@ -143,13 +117,17 @@ namespace websocket {
|
|||||||
`boost::asio::ssl::stream`, callers are responsible for
|
`boost::asio::ssl::stream`, callers are responsible for
|
||||||
providing a suitable overload of this function.
|
providing a suitable overload of this function.
|
||||||
|
|
||||||
|
@param role The role of the local endpoint
|
||||||
|
|
||||||
@param socket The socket to tear down.
|
@param socket The socket to tear down.
|
||||||
|
|
||||||
@param ec Set to the error if any occurred.
|
@param ec Set to the error if any occurred.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
teardown(teardown_tag,
|
teardown(
|
||||||
boost::asio::ip::tcp::socket& socket, error_code& ec);
|
role_type role,
|
||||||
|
boost::asio::ip::tcp::socket& socket,
|
||||||
|
error_code& ec);
|
||||||
|
|
||||||
/** Start tearing down a `boost::asio::ip::tcp::socket`.
|
/** Start tearing down a `boost::asio::ip::tcp::socket`.
|
||||||
|
|
||||||
@ -161,6 +139,8 @@ teardown(teardown_tag,
|
|||||||
callers are responsible for providing a suitable overload
|
callers are responsible for providing a suitable overload
|
||||||
of this function.
|
of this function.
|
||||||
|
|
||||||
|
@param role The role of the local endpoint
|
||||||
|
|
||||||
@param socket The socket to tear down.
|
@param socket The socket to tear down.
|
||||||
|
|
||||||
@param handler The handler to be called when the request completes.
|
@param handler The handler to be called when the request completes.
|
||||||
@ -178,8 +158,10 @@ teardown(teardown_tag,
|
|||||||
*/
|
*/
|
||||||
template<class TeardownHandler>
|
template<class TeardownHandler>
|
||||||
void
|
void
|
||||||
async_teardown(teardown_tag,
|
async_teardown(
|
||||||
boost::asio::ip::tcp::socket& socket, TeardownHandler&& handler);
|
role_type role,
|
||||||
|
boost::asio::ip::tcp::socket& socket,
|
||||||
|
TeardownHandler&& handler);
|
||||||
|
|
||||||
} // websocket
|
} // websocket
|
||||||
} // beast
|
} // beast
|
||||||
|
@ -21,6 +21,7 @@ add_executable (tests-beast-websocket
|
|||||||
error.cpp
|
error.cpp
|
||||||
option.cpp
|
option.cpp
|
||||||
rfc6455.cpp
|
rfc6455.cpp
|
||||||
|
role.cpp
|
||||||
stream.cpp
|
stream.cpp
|
||||||
teardown.cpp
|
teardown.cpp
|
||||||
frame.cpp
|
frame.cpp
|
||||||
|
@ -15,6 +15,7 @@ local SOURCES =
|
|||||||
teardown.cpp
|
teardown.cpp
|
||||||
frame.cpp
|
frame.cpp
|
||||||
mask.cpp
|
mask.cpp
|
||||||
|
role.cpp
|
||||||
utf8_checker.cpp
|
utf8_checker.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
|
11
test/beast/websocket/role.cpp
Normal file
11
test/beast/websocket/role.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
|
||||||
|
// Test that header file is self-contained.
|
||||||
|
#include <boost/beast/websocket/role.hpp>
|
@ -161,21 +161,24 @@ public:
|
|||||||
|
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
teardown(websocket::teardown_tag,
|
teardown(
|
||||||
|
websocket::role_type role,
|
||||||
fail_stream<NextLayer>& stream,
|
fail_stream<NextLayer>& stream,
|
||||||
boost::system::error_code& ec)
|
boost::system::error_code& ec)
|
||||||
{
|
{
|
||||||
if(stream.pfc_->fail(ec))
|
if(stream.pfc_->fail(ec))
|
||||||
return;
|
return;
|
||||||
beast::websocket_helpers::call_teardown(stream.next_layer(), ec);
|
using beast::websocket::teardown;
|
||||||
|
teardown(role, stream.next_layer(), ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TeardownHandler>
|
template<class TeardownHandler>
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
async_teardown(websocket::teardown_tag,
|
async_teardown(
|
||||||
|
websocket::role_type role,
|
||||||
fail_stream<NextLayer>& stream,
|
fail_stream<NextLayer>& stream,
|
||||||
TeardownHandler&& handler)
|
TeardownHandler&& handler)
|
||||||
{
|
{
|
||||||
error_code ec;
|
error_code ec;
|
||||||
if(stream.pfc_->fail(ec))
|
if(stream.pfc_->fail(ec))
|
||||||
@ -184,8 +187,9 @@ public:
|
|||||||
bind_handler(std::move(handler), ec));
|
bind_handler(std::move(handler), ec));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
beast::websocket_helpers::call_async_teardown(
|
using beast::websocket::async_teardown;
|
||||||
stream.next_layer(), std::forward<TeardownHandler>(handler));
|
async_teardown(role, stream.next_layer(),
|
||||||
|
std::forward<TeardownHandler>(handler));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -197,13 +197,15 @@ public:
|
|||||||
|
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
teardown(websocket::teardown_tag,
|
teardown(
|
||||||
|
websocket::role_type role,
|
||||||
stream& s, boost::system::error_code& ec);
|
stream& s, boost::system::error_code& ec);
|
||||||
|
|
||||||
template<class TeardownHandler>
|
template<class TeardownHandler>
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
async_teardown(websocket::teardown_tag,
|
async_teardown(
|
||||||
|
websocket::role_type,
|
||||||
stream& s, TeardownHandler&& handler);
|
stream& s, TeardownHandler&& handler);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -229,8 +231,10 @@ public:
|
|||||||
|
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
teardown(websocket::teardown_tag,
|
teardown(
|
||||||
pipe::stream& s, boost::system::error_code& ec)
|
websocket::role_type,
|
||||||
|
pipe::stream& s,
|
||||||
|
boost::system::error_code& ec)
|
||||||
{
|
{
|
||||||
if(s.fc_)
|
if(s.fc_)
|
||||||
{
|
{
|
||||||
@ -247,7 +251,7 @@ teardown(websocket::teardown_tag,
|
|||||||
template<class TeardownHandler>
|
template<class TeardownHandler>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
async_teardown(websocket::teardown_tag,
|
async_teardown(websocket::role_type,
|
||||||
pipe::stream& s, TeardownHandler&& handler)
|
pipe::stream& s, TeardownHandler&& handler)
|
||||||
{
|
{
|
||||||
error_code ec;
|
error_code ec;
|
||||||
|
@ -440,13 +440,13 @@ public:
|
|||||||
|
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
teardown(websocket::teardown_tag,
|
teardown(websocket::role_type,
|
||||||
stream& s, boost::system::error_code& ec);
|
stream& s, boost::system::error_code& ec);
|
||||||
|
|
||||||
template<class TeardownHandler>
|
template<class TeardownHandler>
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
async_teardown(websocket::teardown_tag,
|
async_teardown(websocket::role_type role,
|
||||||
stream& s, TeardownHandler&& handler);
|
stream& s, TeardownHandler&& handler);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -654,7 +654,7 @@ async_write_some(ConstBufferSequence const& buffers,
|
|||||||
|
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
teardown(websocket::teardown_tag,
|
teardown(websocket::role_type,
|
||||||
stream& s, boost::system::error_code& ec)
|
stream& s, boost::system::error_code& ec)
|
||||||
{
|
{
|
||||||
if(s.in_.fc)
|
if(s.in_.fc)
|
||||||
@ -672,7 +672,7 @@ teardown(websocket::teardown_tag,
|
|||||||
template<class TeardownHandler>
|
template<class TeardownHandler>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
async_teardown(websocket::teardown_tag,
|
async_teardown(websocket::role_type,
|
||||||
stream& s, TeardownHandler&& handler)
|
stream& s, TeardownHandler&& handler)
|
||||||
{
|
{
|
||||||
error_code ec;
|
error_code ec;
|
||||||
|
@ -150,7 +150,7 @@ public:
|
|||||||
|
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
teardown(websocket::teardown_tag,
|
teardown(websocket::role_type,
|
||||||
string_iostream&,
|
string_iostream&,
|
||||||
boost::system::error_code& ec)
|
boost::system::error_code& ec)
|
||||||
{
|
{
|
||||||
@ -160,7 +160,7 @@ public:
|
|||||||
template<class TeardownHandler>
|
template<class TeardownHandler>
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
async_teardown(websocket::teardown_tag,
|
async_teardown(websocket::role_type,
|
||||||
string_iostream& stream,
|
string_iostream& stream,
|
||||||
TeardownHandler&& handler)
|
TeardownHandler&& handler)
|
||||||
{
|
{
|
||||||
|
@ -138,7 +138,7 @@ public:
|
|||||||
|
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
teardown(websocket::teardown_tag,
|
teardown(websocket::role_type,
|
||||||
string_istream&,
|
string_istream&,
|
||||||
boost::system::error_code& ec)
|
boost::system::error_code& ec)
|
||||||
{
|
{
|
||||||
@ -148,7 +148,7 @@ public:
|
|||||||
template<class TeardownHandler>
|
template<class TeardownHandler>
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
async_teardown(websocket::teardown_tag,
|
async_teardown(websocket::role_type,
|
||||||
string_istream& stream,
|
string_istream& stream,
|
||||||
TeardownHandler&& handler)
|
TeardownHandler&& handler)
|
||||||
{
|
{
|
||||||
|
@ -126,7 +126,7 @@ public:
|
|||||||
|
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
teardown(websocket::teardown_tag,
|
teardown(websocket::role_type,
|
||||||
string_ostream&,
|
string_ostream&,
|
||||||
boost::system::error_code& ec)
|
boost::system::error_code& ec)
|
||||||
{
|
{
|
||||||
@ -136,7 +136,7 @@ public:
|
|||||||
template<class TeardownHandler>
|
template<class TeardownHandler>
|
||||||
friend
|
friend
|
||||||
void
|
void
|
||||||
async_teardown(websocket::teardown_tag,
|
async_teardown(websocket::role_type,
|
||||||
string_ostream& stream,
|
string_ostream& stream,
|
||||||
TeardownHandler&& handler)
|
TeardownHandler&& handler)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user