2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // Official repository: https://github.com/boostorg/beast
10 #ifndef BOOST_BEAST_WEBSOCKET_IMPL_TEARDOWN_HPP
11 #define BOOST_BEAST_WEBSOCKET_IMPL_TEARDOWN_HPP
13 #include <boost/beast/core/async_base.hpp>
14 #include <boost/beast/core/bind_handler.hpp>
15 #include <boost/beast/core/stream_traits.hpp>
16 #include <boost/beast/core/detail/bind_continuation.hpp>
17 #include <boost/beast/core/detail/is_invocable.hpp>
18 #include <boost/asio/coroutine.hpp>
19 #include <boost/asio/post.hpp>
29 class Protocol, class Executor,
32 : public beast::async_base<
33 Handler, beast::executor_type<
34 net::basic_stream_socket<
36 , public asio::coroutine
39 net::basic_stream_socket<Protocol, Executor>;
46 template<class Handler_>
53 net::basic_stream_socket<
54 Protocol, Executor>>>(
55 std::forward<Handler_>(h),
61 (*this)({}, 0, false);
67 std::size_t bytes_transferred = 0,
70 BOOST_ASIO_CORO_REENTER(*this)
72 nb_ = s_.non_blocking();
73 s_.non_blocking(true, ec);
76 if(role_ == role_type::server)
77 s_.shutdown(net::socket_base::shutdown_send, ec);
84 s_.read_some(net::buffer(buf), ec);
86 if(ec == net::error::would_block)
90 BOOST_ASIO_HANDLER_LOCATION((
92 "websocket::tcp::async_teardown"
96 net::socket_base::wait_read,
97 beast::detail::bind_continuation(std::move(*this)));
103 if(ec != net::error::eof)
108 if(bytes_transferred == 0)
111 // https://github.com/boostorg/beast/issues/1373
115 if(role_ == role_type::client)
116 s_.shutdown(net::socket_base::shutdown_send, ec);
123 BOOST_ASIO_CORO_YIELD
125 BOOST_ASIO_HANDLER_LOCATION((
127 "websocket::tcp::async_teardown"
130 net::post(bind_front_handler(
131 std::move(*this), ec));
136 s_.non_blocking(nb_, ignored);
138 this->complete_now(ec);
145 //------------------------------------------------------------------------------
147 template<class Protocol, class Executor>
151 net::basic_stream_socket<
152 Protocol, Executor>& socket,
155 if(role == role_type::server)
157 net::socket_base::shutdown_send, ec);
163 auto const bytes_transferred =
164 socket.read_some(net::buffer(buf), ec);
167 if(ec != net::error::eof)
172 if(bytes_transferred == 0)
175 // https://github.com/boostorg/beast/issues/1373
179 if(role == role_type::client)
181 net::socket_base::shutdown_send, ec);
188 class Protocol, class Executor,
189 class TeardownHandler>
193 net::basic_stream_socket<
194 Protocol, Executor>& socket,
195 TeardownHandler&& handler)
197 static_assert(beast::detail::is_invocable<
198 TeardownHandler, void(error_code)>::value,
199 "TeardownHandler type requirements not met");
200 detail::teardown_tcp_op<
203 typename std::decay<TeardownHandler>::type>(
204 std::forward<TeardownHandler>(handler),