]> git.proxmox.com Git - ceph.git/blame - ceph/src/Beast/include/beast/websocket/impl/ssl.ipp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / include / beast / websocket / impl / ssl.ipp
CommitLineData
7c673cae
FG
1//
2// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3//
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)
6//
7
8#ifndef BEAST_WEBSOCKET_IMPL_SSL_IPP_INCLUDED
9#define BEAST_WEBSOCKET_IMPL_SSL_IPP_INCLUDED
10
11#include <beast/core/async_completion.hpp>
12#include <beast/core/handler_helpers.hpp>
13#include <beast/core/handler_concepts.hpp>
14#include <beast/core/handler_ptr.hpp>
15
16namespace beast {
17namespace websocket {
18
19namespace detail {
20
21/*
22
23See
24http://stackoverflow.com/questions/32046034/what-is-the-proper-way-to-securely-disconnect-an-asio-ssl-socket/32054476#32054476
25
26Behavior of ssl::stream regarding close_
27
28 If the remote host calls async_shutdown then the
29 local host's async_read will complete with eof.
30
31 If both hosts call async_shutdown then the calls
32 to async_shutdown will complete with eof.
33
34*/
35template<class AsyncStream, class Handler>
36class teardown_ssl_op
37{
38 using stream_type =
39 boost::asio::ssl::stream<AsyncStream>;
40
41 struct data
42 {
43 bool cont;
44 stream_type& stream;
45 int state = 0;
46
47 data(Handler& handler, stream_type& stream_)
48 : cont(beast_asio_helpers::
49 is_continuation(handler))
50 , stream(stream_)
51 {
52 }
53 };
54
55 handler_ptr<data, Handler> d_;
56
57public:
58 template<class DeducedHandler>
59 explicit
60 teardown_ssl_op(
61 DeducedHandler&& h, stream_type& stream)
62 : d_(std::forward<DeducedHandler>(h), stream)
63 {
64 (*this)(error_code{}, false);
65 }
66
67 void
68 operator()(error_code ec, bool again = true);
69
70 friend
71 void* asio_handler_allocate(std::size_t size,
72 teardown_ssl_op* op)
73 {
74 return beast_asio_helpers::
75 allocate(size, op->d_.handler());
76 }
77
78 friend
79 void asio_handler_deallocate(void* p,
80 std::size_t size, teardown_ssl_op* op)
81 {
82 return beast_asio_helpers::
83 deallocate(p, size, op->d_.handler());
84 }
85
86 friend
87 bool asio_handler_is_continuation(
88 teardown_ssl_op* op)
89 {
90 return op->d_->cont;
91 }
92
93 template<class Function>
94 friend
95 void asio_handler_invoke(Function&& f,
96 teardown_ssl_op* op)
97 {
98 return beast_asio_helpers::
99 invoke(f, op->d_.handler());
100 }
101};
102
103template<class AsyncStream, class Handler>
104void
105teardown_ssl_op<AsyncStream, Handler>::
106operator()(error_code ec, bool again)
107{
108 auto& d = *d_;
109 d.cont = d.cont || again;
110 while(!ec && d.state != 99)
111 {
112 switch(d.state)
113 {
114 case 0:
115 d.state = 99;
116 d.stream.async_shutdown(*this);
117 return;
118 }
119 }
120 d_.invoke(ec);
121}
122
123} // detail
124
125//------------------------------------------------------------------------------
126
127template<class AsyncStream>
128void
129teardown(teardown_tag,
130 boost::asio::ssl::stream<AsyncStream>& stream,
131 error_code& ec)
132{
133 stream.shutdown(ec);
134}
135
136template<class AsyncStream, class TeardownHandler>
137void
138async_teardown(teardown_tag,
139 boost::asio::ssl::stream<AsyncStream>& stream,
140 TeardownHandler&& handler)
141{
142 static_assert(beast::is_CompletionHandler<
143 TeardownHandler, void(error_code)>::value,
144 "TeardownHandler requirements not met");
145 detail::teardown_ssl_op<AsyncStream, typename std::decay<
146 TeardownHandler>::type>{std::forward<TeardownHandler>(
147 handler), stream};
148}
149
150} // websocket
151} // beast
152
153#endif