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
12 namespace 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 }
crow::SocketAdaptor::socket
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
crow::SocketAdaptor::raw_socket
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
crow::SocketAdaptor
A wrapper for the asio::ip::tcp::socket and asio::ssl::stream.
Definition: socket_adaptors.h:18