]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/example/common/ssl_stream.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / beast / example / common / ssl_stream.hpp
1 //
2 // Copyright (c) 2016-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 // Official repository: https://github.com/boostorg/beast
8 //
9
10 #ifndef BOOST_BEAST_EXAMPLE_COMMON_SSL_STREAM_HPP
11 #define BOOST_BEAST_EXAMPLE_COMMON_SSL_STREAM_HPP
12
13 // This include is necessary to work with `ssl::stream` and `boost::beast::websocket::stream`
14 #include <boost/beast/websocket/ssl.hpp>
15
16 #include <boost/asio/ip/tcp.hpp>
17 #include <boost/asio/ssl/stream.hpp>
18 #include <cstddef>
19 #include <memory>
20 #include <type_traits>
21 #include <utility>
22
23 /** C++11 enabled SSL socket wrapper
24
25 This wrapper provides an interface identical to `boost::asio::ssl::stream`,
26 with the following additional properties:
27
28 @li Satisfies @b MoveConstructible
29
30 @li Satisfies @b MoveAssignable
31
32 @li Constructible from a moved socket.
33 */
34 template<class NextLayer>
35 class ssl_stream
36 : public boost::asio::ssl::stream_base
37 {
38 // only works for boost::asio::ip::tcp::socket
39 // for now because of the move limitations
40 static_assert(std::is_same<NextLayer, boost::asio::ip::tcp::socket>::value,
41 "NextLayer requirements not met");
42
43 using stream_type = boost::asio::ssl::stream<NextLayer>;
44
45 std::unique_ptr<stream_type> p_;
46 boost::asio::ssl::context* ctx_;
47
48 public:
49 /// The native handle type of the SSL stream.
50 using native_handle_type = typename stream_type::native_handle_type;
51
52 /// Structure for use with deprecated impl_type.
53 using impl_struct = typename stream_type::impl_struct;
54
55 /// The type of the next layer.
56 using next_layer_type = typename stream_type::next_layer_type;
57
58 /// The type of the lowest layer.
59 using lowest_layer_type = typename stream_type::lowest_layer_type;
60
61 /// The type of the executor associated with the object.
62 using executor_type = typename stream_type::executor_type;
63
64 ssl_stream(
65 boost::asio::ip::tcp::socket socket,
66 boost::asio::ssl::context& ctx)
67 : p_(new stream_type{
68 socket.get_executor().context(), ctx})
69 , ctx_(&ctx)
70 {
71 p_->next_layer() = std::move(socket);
72 }
73
74 ssl_stream(ssl_stream&& other)
75 : p_(new stream_type(
76 other.get_executor().context(), *other.ctx_))
77 , ctx_(other.ctx_)
78 {
79 using std::swap;
80 swap(p_, other.p_);
81 }
82
83 ssl_stream& operator=(ssl_stream&& other)
84 {
85 std::unique_ptr<stream_type> p(new stream_type{
86 other.get_executor().context(), other.ctx_});
87 using std::swap;
88 swap(p_, p);
89 swap(p_, other.p_);
90 ctx_ = other.ctx_;
91 return *this;
92 }
93
94 executor_type
95 get_executor() noexcept
96 {
97 return p_->get_executor();
98 }
99
100 native_handle_type
101 native_handle()
102 {
103 return p_->native_handle();
104 }
105
106 next_layer_type const&
107 next_layer() const
108 {
109 return p_->next_layer();
110 }
111
112 next_layer_type&
113 next_layer()
114 {
115 return p_->next_layer();
116 }
117
118 lowest_layer_type&
119 lowest_layer()
120 {
121 return p_->lowest_layer();
122 }
123
124 lowest_layer_type const&
125 lowest_layer() const
126 {
127 return p_->lowest_layer();
128 }
129
130 void
131 set_verify_mode(boost::asio::ssl::verify_mode v)
132 {
133 p_->set_verify_mode(v);
134 }
135
136 boost::system::error_code
137 set_verify_mode(boost::asio::ssl::verify_mode v,
138 boost::system::error_code& ec)
139 {
140 return p_->set_verify_mode(v, ec);
141 }
142
143 void
144 set_verify_depth(int depth)
145 {
146 p_->set_verify_depth(depth);
147 }
148
149 boost::system::error_code
150 set_verify_depth(
151 int depth, boost::system::error_code& ec)
152 {
153 return p_->set_verify_depth(depth, ec);
154 }
155
156 template<class VerifyCallback>
157 void
158 set_verify_callback(VerifyCallback callback)
159 {
160 p_->set_verify_callback(callback);
161 }
162
163 template<class VerifyCallback>
164 boost::system::error_code
165 set_verify_callback(VerifyCallback callback,
166 boost::system::error_code& ec)
167 {
168 return p_->set_verify_callback(callback, ec);
169 }
170
171 void
172 handshake(handshake_type type)
173 {
174 p_->handshake(type);
175 }
176
177 boost::system::error_code
178 handshake(handshake_type type,
179 boost::system::error_code& ec)
180 {
181 return p_->handshake(type, ec);
182 }
183
184 template<class ConstBufferSequence>
185 void
186 handshake(
187 handshake_type type, ConstBufferSequence const& buffers)
188 {
189 p_->handshake(type, buffers);
190 }
191
192 template<class ConstBufferSequence>
193 boost::system::error_code
194 handshake(handshake_type type,
195 ConstBufferSequence const& buffers,
196 boost::system::error_code& ec)
197 {
198 return p_->handshake(type, buffers, ec);
199 }
200
201 template<class HandshakeHandler>
202 BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler,
203 void(boost::system::error_code))
204 async_handshake(handshake_type type,
205 BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
206 {
207 return p_->async_handshake(type,
208 BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
209 }
210
211 template<class ConstBufferSequence, class BufferedHandshakeHandler>
212 BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler,
213 void (boost::system::error_code, std::size_t))
214 async_handshake(handshake_type type, ConstBufferSequence const& buffers,
215 BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
216 {
217 return p_->async_handshake(type, buffers,
218 BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
219 }
220
221 void
222 shutdown()
223 {
224 p_->shutdown();
225 }
226
227 boost::system::error_code
228 shutdown(boost::system::error_code& ec)
229 {
230 return p_->shutdown(ec);
231 }
232
233 template<class ShutdownHandler>
234 BOOST_ASIO_INITFN_RESULT_TYPE(ShutdownHandler,
235 void (boost::system::error_code))
236 async_shutdown(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler)
237 {
238 return p_->async_shutdown(
239 BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler));
240 }
241
242 template<class ConstBufferSequence>
243 std::size_t
244 write_some(ConstBufferSequence const& buffers)
245 {
246 return p_->write_some(buffers);
247 }
248
249 template<class ConstBufferSequence>
250 std::size_t
251 write_some(ConstBufferSequence const& buffers,
252 boost::system::error_code& ec)
253 {
254 return p_->write_some(buffers, ec);
255 }
256
257 template<class ConstBufferSequence, class WriteHandler>
258 BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
259 void (boost::system::error_code, std::size_t))
260 async_write_some(ConstBufferSequence const& buffers,
261 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
262 {
263 return p_->async_write_some(buffers,
264 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
265 }
266
267 template<class MutableBufferSequence>
268 std::size_t
269 read_some(MutableBufferSequence const& buffers)
270 {
271 return p_->read_some(buffers);
272 }
273
274 template<class MutableBufferSequence>
275 std::size_t
276 read_some(MutableBufferSequence const& buffers,
277 boost::system::error_code& ec)
278 {
279 return p_->read_some(buffers, ec);
280 }
281
282 template<class MutableBufferSequence, class ReadHandler>
283 BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
284 void(boost::system::error_code, std::size_t))
285 async_read_some(MutableBufferSequence const& buffers,
286 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
287 {
288 return p_->async_read_some(buffers,
289 BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
290 }
291
292 template<class SyncStream>
293 friend
294 void
295 teardown(boost::beast::websocket::role_type,
296 ssl_stream<SyncStream>& stream,
297 boost::system::error_code& ec);
298
299 template<class AsyncStream, class TeardownHandler>
300 friend
301 void
302 async_teardown(boost::beast::websocket::role_type,
303 ssl_stream<AsyncStream>& stream, TeardownHandler&& handler);
304 };
305
306 // These hooks are used to inform boost::beast::websocket::stream on
307 // how to tear down the connection as part of the WebSocket
308 // protocol specifications
309
310 template<class SyncStream>
311 inline
312 void
313 teardown(
314 boost::beast::websocket::role_type role,
315 ssl_stream<SyncStream>& stream,
316 boost::system::error_code& ec)
317 {
318 // Just forward it to the wrapped ssl::stream
319 using boost::beast::websocket::teardown;
320 teardown(role, *stream.p_, ec);
321 }
322
323 template<class AsyncStream, class TeardownHandler>
324 inline
325 void
326 async_teardown(
327 boost::beast::websocket::role_type role,
328 ssl_stream<AsyncStream>& stream,
329 TeardownHandler&& handler)
330 {
331 // Just forward it to the wrapped ssl::stream
332 using boost::beast::websocket::async_teardown;
333 async_teardown(role,
334 *stream.p_, std::forward<TeardownHandler>(handler));
335 }
336
337 #endif