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