Crow  1.1
A C++ microframework for the web
 
Loading...
Searching...
No Matches
socket_adaptors.h
1#pragma once
2
3#ifdef CROW_USE_BOOST
4#include <boost/asio.hpp>
5#include <boost/asio/version.hpp>
6#ifdef CROW_ENABLE_SSL
7#include <boost/asio/ssl.hpp>
8#endif
9#else
10#ifndef ASIO_STANDALONE
11#define ASIO_STANDALONE
12#endif
13#include <asio.hpp>
14#include <asio/version.hpp>
15#ifdef CROW_ENABLE_SSL
16#include <asio/ssl.hpp>
17#endif
18#endif
19#include "crow/settings.h"
20
21#if (defined(CROW_USE_BOOST) && BOOST_VERSION >= 107000) || (ASIO_VERSION >= 101008)
22#define GET_IO_CONTEXT(s) ((asio::io_context&)(s).get_executor().context())
23#else
24#define GET_IO_CONTEXT(s) ((s).get_io_service())
25#endif
26
27namespace crow
28{
29#ifdef CROW_USE_BOOST
30 namespace asio = boost::asio;
31 using error_code = boost::system::error_code;
32#else
33 using error_code = asio::error_code;
34#endif
35 using tcp = asio::ip::tcp;
36 using stream_protocol = asio::local::stream_protocol;
37
38 /// A wrapper for the asio::ip::tcp::socket and asio::ssl::stream
40 {
41 using context = void;
42 SocketAdaptor(asio::io_context& io_context, context*):
43 socket_(io_context)
44 {}
45
46 asio::io_context& get_io_context()
47 {
48 return GET_IO_CONTEXT(socket_);
49 }
50
51 /// Get the TCP socket handling data transfers, regardless of what layer is handling transfers on top of the socket.
52 tcp::socket& raw_socket()
53 {
54 return socket_;
55 }
56
57 /// Get the object handling data transfers, this can be either a TCP socket or an SSL stream (if SSL is enabled).
58 tcp::socket& socket()
59 {
60 return socket_;
61 }
62
63 tcp::endpoint remote_endpoint() const
64 {
65 return socket_.remote_endpoint();
66 }
67
68 std::string address() const
69 {
70 return socket_.remote_endpoint().address().to_string();
71 }
72
73 bool is_open() const
74 {
75 return socket_.is_open();
76 }
77
78 void close()
79 {
80 error_code ec;
81 socket_.close(ec);
82 }
83
84 void shutdown_readwrite()
85 {
86 error_code ec;
87 socket_.shutdown(asio::socket_base::shutdown_type::shutdown_both, ec);
88 }
89
90 void shutdown_write()
91 {
92 error_code ec;
93 socket_.shutdown(asio::socket_base::shutdown_type::shutdown_send, ec);
94 }
95
96 void shutdown_read()
97 {
98 error_code ec;
99 socket_.shutdown(asio::socket_base::shutdown_type::shutdown_receive, ec);
100 }
101
102 template<typename F>
103 void start(F f)
104 {
105 f(error_code());
106 }
107
108 tcp::socket socket_;
109 };
110
112 {
113 using context = void;
114 UnixSocketAdaptor(asio::io_context& io_context, context*):
115 socket_(io_context)
116 {
117 }
118
119 asio::io_context& get_io_context()
120 {
121 return GET_IO_CONTEXT(socket_);
122 }
123
124 stream_protocol::socket& raw_socket()
125 {
126 return socket_;
127 }
128
129 stream_protocol::socket& socket()
130 {
131 return socket_;
132 }
133
134 stream_protocol::endpoint remote_endpoint()
135 {
136 return socket_.local_endpoint();
137 }
138
139 std::string address() const
140 {
141 return "";
142 }
143
144 bool is_open()
145 {
146 return socket_.is_open();
147 }
148
149 void close()
150 {
151 error_code ec;
152 socket_.close(ec);
153 }
154
155 void shutdown_readwrite()
156 {
157 error_code ec;
158 socket_.shutdown(asio::socket_base::shutdown_type::shutdown_both, ec);
159 }
160
161 void shutdown_write()
162 {
163 error_code ec;
164 socket_.shutdown(asio::socket_base::shutdown_type::shutdown_send, ec);
165 }
166
167 void shutdown_read()
168 {
169 error_code ec;
170 socket_.shutdown(asio::socket_base::shutdown_type::shutdown_receive, ec);
171 }
172
173 template<typename F>
174 void start(F f)
175 {
176 f(error_code());
177 }
178
179 stream_protocol::socket socket_;
180 };
181
182#ifdef CROW_ENABLE_SSL
184 {
185 using context = asio::ssl::context;
186 using ssl_socket_t = asio::ssl::stream<tcp::socket>;
187 SSLAdaptor(asio::io_context& io_context, context* ctx):
188 ssl_socket_(new ssl_socket_t(io_context, *ctx))
189 {}
190
191 asio::ssl::stream<tcp::socket>& socket()
192 {
193 return *ssl_socket_;
194 }
195
196 tcp::socket::lowest_layer_type&
197 raw_socket()
198 {
199 return ssl_socket_->lowest_layer();
200 }
201
202 tcp::endpoint remote_endpoint()
203 {
204 return raw_socket().remote_endpoint();
205 }
206
207 std::string address() const
208 {
209 return ssl_socket_->lowest_layer().remote_endpoint().address().to_string();
210 }
211
212 bool is_open()
213 {
214 return ssl_socket_ ? raw_socket().is_open() : false;
215 }
216
217 void close()
218 {
219 if (is_open())
220 {
221 error_code ec;
222 raw_socket().close(ec);
223 }
224 }
225
226 void shutdown_readwrite()
227 {
228 if (is_open())
229 {
230 error_code ec;
231 raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_both, ec);
232 }
233 }
234
235 void shutdown_write()
236 {
237 if (is_open())
238 {
239 error_code ec;
240 raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_send, ec);
241 }
242 }
243
244 void shutdown_read()
245 {
246 if (is_open())
247 {
248 error_code ec;
249 raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_receive, ec);
250 }
251 }
252
253 asio::io_context& get_io_context()
254 {
255 return GET_IO_CONTEXT(raw_socket());
256 }
257
258 template<typename F>
259 void start(F f)
260 {
261 ssl_socket_->async_handshake(asio::ssl::stream_base::server,
262 [f](const error_code& ec) {
263 f(ec);
264 });
265 }
266
267 std::unique_ptr<asio::ssl::stream<tcp::socket>> ssl_socket_;
268 };
269#endif
270} // namespace crow
The main namespace of the library. In this namespace is defined the most important classes and functi...
Definition socket_adaptors.h:184
A wrapper for the asio::ip::tcp::socket and asio::ssl::stream.
Definition socket_adaptors.h:40
tcp::socket & socket()
Get the object handling data transfers, this can be either a TCP socket or an SSL stream (if SSL is e...
Definition socket_adaptors.h:58
tcp::socket & raw_socket()
Get the TCP socket handling data transfers, regardless of what layer is handling transfers on top of ...
Definition socket_adaptors.h:52
Definition socket_adaptors.h:112