Crow  1.1
A C++ microframework for the web
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 (CROW_USE_BOOST && BOOST_VERSION >= 107000) || (ASIO_VERSION >= 101300)
22 #define GET_IO_SERVICE(s) ((asio::io_context&)(s).get_executor().context())
23 #else
24 #define GET_IO_SERVICE(s) ((s).get_io_service())
25 #endif
26 
27 namespace 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 
37  /// A wrapper for the asio::ip::tcp::socket and asio::ssl::stream
39  {
40  using context = void;
41  SocketAdaptor(asio::io_service& io_service, context*):
42  socket_(io_service)
43  {}
44 
45  asio::io_service& get_io_service()
46  {
47  return GET_IO_SERVICE(socket_);
48  }
49 
50  /// Get the TCP socket handling data trasfers, regardless of what layer is handling transfers on top of the socket.
51  tcp::socket& raw_socket()
52  {
53  return socket_;
54  }
55 
56  /// Get the object handling data transfers, this can be either a TCP socket or an SSL stream (if SSL is enabled).
57  tcp::socket& socket()
58  {
59  return socket_;
60  }
61 
62  tcp::endpoint remote_endpoint()
63  {
64  return socket_.remote_endpoint();
65  }
66 
67  bool is_open()
68  {
69  return socket_.is_open();
70  }
71 
72  void close()
73  {
74  error_code ec;
75  socket_.close(ec);
76  }
77 
78  void shutdown_readwrite()
79  {
80  error_code ec;
81  socket_.shutdown(asio::socket_base::shutdown_type::shutdown_both, ec);
82  }
83 
84  void shutdown_write()
85  {
86  error_code ec;
87  socket_.shutdown(asio::socket_base::shutdown_type::shutdown_send, ec);
88  }
89 
90  void shutdown_read()
91  {
92  error_code ec;
93  socket_.shutdown(asio::socket_base::shutdown_type::shutdown_receive, ec);
94  }
95 
96  template<typename F>
97  void start(F f)
98  {
99  f(error_code());
100  }
101 
102  tcp::socket socket_;
103  };
104 
105 #ifdef CROW_ENABLE_SSL
106  struct SSLAdaptor
107  {
108  using context = asio::ssl::context;
109  using ssl_socket_t = asio::ssl::stream<tcp::socket>;
110  SSLAdaptor(asio::io_service& io_service, context* ctx):
111  ssl_socket_(new ssl_socket_t(io_service, *ctx))
112  {}
113 
114  asio::ssl::stream<tcp::socket>& socket()
115  {
116  return *ssl_socket_;
117  }
118 
119  tcp::socket::lowest_layer_type&
120  raw_socket()
121  {
122  return ssl_socket_->lowest_layer();
123  }
124 
125  tcp::endpoint remote_endpoint()
126  {
127  return raw_socket().remote_endpoint();
128  }
129 
130  bool is_open()
131  {
132  return ssl_socket_ ? raw_socket().is_open() : false;
133  }
134 
135  void close()
136  {
137  if (is_open())
138  {
139  error_code ec;
140  raw_socket().close(ec);
141  }
142  }
143 
144  void shutdown_readwrite()
145  {
146  if (is_open())
147  {
148  error_code ec;
149  raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_both, ec);
150  }
151  }
152 
153  void shutdown_write()
154  {
155  if (is_open())
156  {
157  error_code ec;
158  raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_send, ec);
159  }
160  }
161 
162  void shutdown_read()
163  {
164  if (is_open())
165  {
166  error_code ec;
167  raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_receive, ec);
168  }
169  }
170 
171  asio::io_service& get_io_service()
172  {
173  return GET_IO_SERVICE(raw_socket());
174  }
175 
176  template<typename F>
177  void start(F f)
178  {
179  ssl_socket_->async_handshake(asio::ssl::stream_base::server,
180  [f](const error_code& ec) {
181  f(ec);
182  });
183  }
184 
185  std::unique_ptr<asio::ssl::stream<tcp::socket>> ssl_socket_;
186  };
187 #endif
188 } // namespace crow
The main namespace of the library. In this namespace is defined the most important classes and functi...
Definition: socket_adaptors.h:107
A wrapper for the asio::ip::tcp::socket and asio::ssl::stream.
Definition: socket_adaptors.h:39
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:51
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:57