RESTinio
Loading...
Searching...
No Matches
connection_state_listener.hpp
Go to the documentation of this file.
1/*
2 * RESTinio
3 */
4
5/*!
6 * @file
7 * @brief Stuff related to connection state listeners.
8 *
9 * @since v.0.5.1
10 */
11
12#pragma once
13
14#include <restinio/compiler_features.hpp>
15#include <restinio/common_types.hpp>
16#include <restinio/tls_fwd.hpp>
17
18#include <variant>
19
20namespace restinio
21{
22
24{
25
26/*!
27 * @brief Type of object that tells that new connection has been accepted.
28 *
29 * If a new connection is a TLS-connection then is_tls_connection()
30 * returns `true` and the information about TLS-socket can be inspected
31 * via try_inspect_tls(), inspect_tls_or_throw() and
32 * inspect_tls_or_default() methods.
33 *
34 * @since v.0.6.0
35 */
36class accepted_t final
37{
38 /*!
39 * \brief An optional pointer to TLS-related connection.
40 *
41 * Will be nullptr for non-TLS connections.
42 *
43 * \since
44 * v.0.6.0
45 */
47
48public:
50 tls_socket_t * tls_socket )
51 : m_tls_socket{ tls_socket }
52 {}
53
54 /*!
55 * @brief Checks if the accepted connection is a TLS-connection.
56 *
57 * \retval true if the accepted connection is a TLS-connection.
58 * \retval false if the accepted connection doesn't use TLS.
59 */
60 [[nodiscard]]
61 bool
62 is_tls_connection() const noexcept { return nullptr != m_tls_socket; }
63
64 /*!
65 * @brief Calls the specified lambda-function if the accepted
66 * connection is a TLS-connection.
67 *
68 * Do nothing if the accepted connection doens't use TLS.
69 *
70 * Lambda function should accept one argument of a type
71 * restinio::connection_state::tls_accessor_t (by value of by const
72 * reference).
73 *
74 * Usage example:
75 * \code
76 * class my_cause_visitor_t {
77 * void operator()(const restinio::connection_state::accepted_t & cause) const {
78 * ... // Some application-logic.
79 * cause.try_inspect_tls([&](const restinio::connection_state::tls_accessor_t & tls_info) {
80 * ... // Some application-specific work with TLS-params.
81 * });
82 * ...
83 * }
84 * ...
85 * };
86 * void some_state_listener_t::state_changed(
87 * const restinio::connection_state::notice_t & notice) {
88 * ...
89 * std::visit(my_cause_visitor_t{...}, notice.cause());
90 * }
91 * \endcode
92 */
93 template< typename Lambda >
94 void
95 try_inspect_tls( Lambda && lambda ) const;
96
97 /*!
98 * @brief Calls the specified lambda-function if the accepted
99 * connection is a TLS-connection.
100 *
101 * Throws an instance of exception_t if the accepted connection doens't use
102 * TLS.
103 *
104 * Lambda function should accept one argument of a type
105 * restinio::connection_state::tls_accessor_t (by value of by const
106 * reference).
107 *
108 * \return the value returned by \a lambda.
109 *
110 * Usage example:
111 * \code
112 * class my_cause_visitor_t {
113 * void operator()(const restinio::connection_state::accepted_t & cause) const {
114 * ... // Some application-logic.
115 * cause.inspect_tls_or_throw([&](const restinio::connection_state::tls_accessor_t & tls_info) {
116 * ... // Some application-specific work with TLS-params.
117 * });
118 * ...
119 * }
120 * ...
121 * };
122 * void some_state_listener_t::state_changed(
123 * const restinio::connection_state::notice_t & notice) {
124 * ...
125 * std::visit(my_cause_visitor_t{...}, notice.cause());
126 * }
127 * \endcode
128 */
129 template< typename Lambda >
130 decltype(auto)
131 inspect_tls_or_throw( Lambda && lambda ) const;
132
133 /*!
134 * @brief Calls the specified lambda-function if the accepted
135 * connection is a TLS-connection.
136 *
137 * Returns the value of \a default_value if the accepted connection doens't
138 * use TLS.
139 *
140 * Lambda function should accept one argument of a type
141 * restinio::connection_state::tls_accessor_t (by value of by const
142 * reference).
143 *
144 * \return the value returned by \a lambda if it is TLS-connection or
145 * \a default_value otherwise. Note that \a lambda can return a value
146 * of a different type and in that case the returned value will be used
147 * for constructing of a new value of type \a T.
148 *
149 * Usage example:
150 * \code
151 * class my_cause_visitor_t {
152 * void operator()(const restinio::connection_state::accepted_t & cause) const {
153 * ... // Some application-logic.
154 * auto user_name = cause.inspect_tls_or_default(
155 * [&](const restinio::connection_state::tls_accessor_t & tls_info) {
156 * ... // Some application-specific work with TLS-params.
157 * },
158 * std::string{"unknown-user"});
159 * ...
160 * }
161 * ...
162 * };
163 * void some_state_listener_t::state_changed(
164 * const restinio::connection_state::notice_t & notice) {
165 * ...
166 * std::visit(my_cause_visitor_t{...}, notice.cause());
167 * }
168 * \endcode
169 */
170 template< typename Lambda, typename T >
171 T
172 inspect_tls_or_default( Lambda && lambda, T && default_value ) const;
173};
174
175/*!
176 * @brief Type of object that tells that the connection has been closed.
177 *
178 * @note
179 * This type is empty now, but it can be extended in some of future versions.
180 *
181 * @since v.0.6.0
182 */
183class closed_t final
184{
185};
186
187/*!
188 * @brief Type of object that tells that the connection has been upgraded
189 * to WebSocket.
190 *
191 * @note
192 * This type is empty now, but it can be extended in some of future versions.
193 *
194 * @since v.0.6.0
195 */
196class upgraded_to_websocket_t final
197{
198};
199
200/*!
201 * @brief A type for the representation of the current state of a connection.
202 *
203 * Please note that in C++17 and above it is just a `std::variant` and
204 * all tools from the C++ standard library (like `std::holds_alternative`,
205 * `std::get`, `std::get_if`, `std::visit`) can be used.
206 *
207 * @since v.0.6.0
208 */
209using cause_t = std::variant< accepted_t, closed_t, upgraded_to_websocket_t >;
210
211/*!
212 * @brief An object with info about connection to be passed to state listener.
213 *
214 * That object contains available information of the connection for that
215 * state listener is called.
216 *
217 * NOTE. Content of this type can be changed in future versions of RESTinio.
218 *
219 * @since v.0.5.1
220 */
222{
226
227public :
228 //! Initializing constructor.
230 connection_id_t conn_id,
231 endpoint_t remote_endpoint,
232 cause_t cause )
233 : m_conn_id{ conn_id }
235 , m_cause{ cause }
236 {}
237
238 //! Get the connection id.
239 [[nodiscard]]
241 connection_id() const noexcept { return m_conn_id; }
242
243 //! Get the remote endpoint for the connection.
244 [[nodiscard]]
246 remote_endpoint() const noexcept { return m_remote_endpoint; }
247
248 //! Get the cause for the notification.
249 /*!
250 * @attention
251 * Since v.0.6.0 the type cause_t is a variant, not a simple
252 * enumeration as in v.0.5.
253 */
254 [[nodiscard]]
255 cause_t
256 cause() const noexcept { return m_cause; }
257};
258
259/*!
260 * @brief The default no-op state listener.
261 *
262 * This type is used for connection_state_listener_t trait by default.
263 *
264 * NOTE. When this type if used no calls to state listener will be generated.
265 * It means that there won't be any performance penalties related to
266 * invoking of state listener's state_changed() method.
267 *
268 * @since v.0.5.1
269 */
271{
272 // empty type by design.
273};
274
275} /* namespace connection_state */
276
277} /* namespace restinio */
decltype(auto) inspect_tls_or_throw(Lambda &&lambda) const
Calls the specified lambda-function if the accepted connection is a TLS-connection.
Definition tls.hpp:109
T inspect_tls_or_default(Lambda &&lambda, T &&default_value) const
Calls the specified lambda-function if the accepted connection is a TLS-connection.
Definition tls.hpp:120
tls_socket_t * m_tls_socket
An optional pointer to TLS-related connection.
void try_inspect_tls(Lambda &&lambda) const
Calls the specified lambda-function if the accepted connection is a TLS-connection.
Definition tls.hpp:101
bool is_tls_connection() const noexcept
Checks if the accepted connection is a TLS-connection.
An object with info about connection to be passed to state listener.
endpoint_t remote_endpoint() const noexcept
Get the remote endpoint for the connection.
connection_id_t connection_id() const noexcept
Get the connection id.
notice_t(connection_id_t conn_id, endpoint_t remote_endpoint, cause_t cause)
Initializing constructor.
cause_t cause() const noexcept
Get the cause for the notification.
std::variant< accepted_t, closed_t, upgraded_to_websocket_t > cause_t
A type for the representation of the current state of a connection.
asio_ns::ip::tcp::endpoint endpoint_t
An alias for endpoint type from Asio.
impl::tls_socket_t tls_socket_t
A public alias for the actual implementation of TLS-socket.
Definition tls_fwd.hpp:30
std::uint64_t connection_id_t
Type for ID of connection.