Crow  0.3
A C++ microframework for the web
socket_adaptors.h
1#pragma once
2#include <boost/asio.hpp>
3#ifdef CROW_ENABLE_SSL
4#include <boost/asio/ssl.hpp>
5#endif
6#include "crow/settings.h"
7#if BOOST_VERSION >= 107000
8#define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context())
9#else
10#define GET_IO_SERVICE(s) ((s).get_io_service())
11#endif
12namespace crow
13{
14 using namespace boost;
15 using tcp = asio::ip::tcp;
16
17 ///A wrapper for the asio::ip::tcp::socket and asio::ssl::stream
19 {
20 using context = void;
21 SocketAdaptor(boost::asio::io_service& io_service, context*)
22 : socket_(io_service)
23 {
24 }
25
26 boost::asio::io_service& get_io_service()
27 {
28 return GET_IO_SERVICE(socket_);
29 }
30
31 /// Get the TCP socket handling data trasfers, regardless of what layer is handling transfers on top of the socket.
32 tcp::socket& raw_socket()
33 {
34 return socket_;
35 }
36
37 /// Get the object handling data transfers, this can be either a TCP socket or an SSL stream (if SSL is enabled).
38 tcp::socket& socket()
39 {
40 return socket_;
41 }
42
43 tcp::endpoint remote_endpoint()
44 {
45 return socket_.remote_endpoint();
46 }
47
48 bool is_open()
49 {
50 return socket_.is_open();
51 }
52
53 void close()
54 {
55 boost::system::error_code ec;
56 socket_.close(ec);
57 }
58
59 void shutdown_readwrite()
60 {
61 boost::system::error_code ec;
62 socket_.shutdown(boost::asio::socket_base::shutdown_type::shutdown_both, ec);
63 }
64
65 void shutdown_write()
66 {
67 boost::system::error_code ec;
68 socket_.shutdown(boost::asio::socket_base::shutdown_type::shutdown_send, ec);
69 }
70
71 void shutdown_read()
72 {
73 boost::system::error_code ec;
74 socket_.shutdown(boost::asio::socket_base::shutdown_type::shutdown_receive, ec);
75 }
76
77 template <typename F>
78 void start(F f)
79 {
80 f(boost::system::error_code());
81 }
82
83 tcp::socket socket_;
84 };
85
86#ifdef CROW_ENABLE_SSL
87 struct SSLAdaptor
88 {
89 using context = boost::asio::ssl::context;
90 using ssl_socket_t = boost::asio::ssl::stream<tcp::socket>;
91 SSLAdaptor(boost::asio::io_service& io_service, context* ctx)
92 : ssl_socket_(new ssl_socket_t(io_service, *ctx))
93 {
94 }
95
96 boost::asio::ssl::stream<tcp::socket>& socket()
97 {
98 return *ssl_socket_;
99 }
100
101 tcp::socket::lowest_layer_type&
102 raw_socket()
103 {
104 return ssl_socket_->lowest_layer();
105 }
106
107 tcp::endpoint remote_endpoint()
108 {
109 return raw_socket().remote_endpoint();
110 }
111
112 bool is_open()
113 {
114 return ssl_socket_ ? raw_socket().is_open() : false;
115 }
116
117 void close()
118 {
119 if (is_open())
120 {
121 boost::system::error_code ec;
122 raw_socket().close(ec);
123 }
124 }
125
126 void shutdown_readwrite()
127 {
128 if (is_open())
129 {
130 boost::system::error_code ec;
131 raw_socket().shutdown(boost::asio::socket_base::shutdown_type::shutdown_both, ec);
132 }
133 }
134
135 void shutdown_write()
136 {
137 if (is_open())
138 {
139 boost::system::error_code ec;
140 raw_socket().shutdown(boost::asio::socket_base::shutdown_type::shutdown_send, ec);
141 }
142 }
143
144 void shutdown_read()
145 {
146 if (is_open())
147 {
148 boost::system::error_code ec;
149 raw_socket().shutdown(boost::asio::socket_base::shutdown_type::shutdown_receive, ec);
150 }
151 }
152
153 boost::asio::io_service& get_io_service()
154 {
155 return GET_IO_SERVICE(raw_socket());
156 }
157
158 template <typename F>
159 void start(F f)
160 {
161 ssl_socket_->async_handshake(boost::asio::ssl::stream_base::server,
162 [f](const boost::system::error_code& ec) {
163 f(ec);
164 });
165 }
166
167 std::unique_ptr<boost::asio::ssl::stream<tcp::socket>> ssl_socket_;
168 };
169#endif
170}
A wrapper for the asio::ip::tcp::socket and asio::ssl::stream.
Definition: socket_adaptors.h:19
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:38
tcp::socket & raw_socket()
Get the TCP socket handling data trasfers, regardless of what layer is handling transfers on top of t...
Definition: socket_adaptors.h:32