Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:34

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_WEBSOCKET_IMPL_SSL_HPP
0011 #define BOOST_BEAST_WEBSOCKET_IMPL_SSL_HPP
0012 
0013 #include <utility>
0014 #include <boost/beast/websocket/teardown.hpp>
0015 #include <boost/asio/compose.hpp>
0016 #include <boost/asio/coroutine.hpp>
0017 
0018 namespace boost {
0019 namespace beast {
0020 
0021 /*
0022 
0023     See
0024     http://stackoverflow.com/questions/32046034/what-is-the-proper-way-to-securely-disconnect-an-asio-ssl-socket/32054476#32054476
0025 
0026     Behavior of ssl::stream regarding close_notify
0027 
0028     If the remote host calls async_shutdown then the
0029     local host's async_read will complete with eof.
0030 
0031     If both hosts call async_shutdown then the calls
0032     to async_shutdown will complete with eof.
0033 
0034 */
0035 
0036 template<class AsyncStream>
0037 void
0038 teardown(
0039     role_type role,
0040     boost::asio::ssl::stream<AsyncStream>& stream,
0041     error_code& ec)
0042 {
0043     stream.shutdown(ec);
0044     using boost::beast::websocket::teardown;
0045     error_code ec2;
0046     teardown(role, stream.next_layer(), ec ? ec2 : ec);
0047 }
0048 
0049 namespace detail {
0050 
0051 template<class AsyncStream>
0052 struct ssl_shutdown_op
0053     : boost::asio::coroutine
0054 {
0055     ssl_shutdown_op(
0056         boost::asio::ssl::stream<AsyncStream>& s,
0057         role_type role)
0058         : s_(s)
0059         , role_(role)
0060     {
0061     }
0062 
0063     template<class Self>
0064     void
0065     operator()(Self& self, error_code ec = {}, std::size_t = 0)
0066     {
0067         BOOST_ASIO_CORO_REENTER(*this)
0068         {
0069             self.reset_cancellation_state(net::enable_total_cancellation());
0070 
0071             BOOST_ASIO_CORO_YIELD
0072                 s_.async_shutdown(std::move(self));
0073             ec_ = ec;
0074 
0075             using boost::beast::websocket::async_teardown;
0076             BOOST_ASIO_CORO_YIELD
0077                 async_teardown(role_, s_.next_layer(), std::move(self));
0078             if (!ec_)
0079                 ec_ = ec;
0080 
0081             self.complete(ec_);
0082         }
0083     }
0084 
0085 private:
0086     boost::asio::ssl::stream<AsyncStream>& s_;
0087     role_type role_;
0088     error_code ec_;
0089 };
0090 
0091 } // detail
0092 
0093 template<
0094     class AsyncStream,
0095     class TeardownHandler>
0096 void
0097 async_teardown(
0098     role_type role,
0099     boost::asio::ssl::stream<AsyncStream>& stream,
0100     TeardownHandler&& handler)
0101 {
0102     return boost::asio::async_compose<TeardownHandler, void(error_code)>(
0103         detail::ssl_shutdown_op<AsyncStream>(stream, role),
0104         handler,
0105         stream);
0106 }
0107 
0108 } // beast
0109 } // boost
0110 
0111 #endif