SNode.C
Loading...
Searching...
No Matches
testregex.cpp File Reference
Include dependency graph for testregex.cpp:

Go to the source code of this file.

Functions

Router router (database::mariadb::MariaDBClient &db)
 
int main (int argc, char *argv[])
 

Function Documentation

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 217 of file testregex.cpp.

217 {
218 WebApp::init(argc, argv);
219
221 .hostname = "localhost",
222 .username = "snodec",
223 .password = "pentium5",
224 .database = "snodec",
225 .port = 3306,
226 .socket = "/run/mysqld/mysqld.sock",
227 .flags = 0,
228 };
229
230 // CREATE USER 'snodec'@localhost IDENTIFIED BY 'pentium5'
231 // GRANT ALL PRIVILEGES ON *.* TO 'snodec'@localhost
232 // GRANT ALL PRIVILEGES ON 'snodec'.'snodec' TO 'snodec'@localhost
233 // CREATE DATABASE 'snodec';
234 // CREATE TABLE 'snodec' ('username' text NOT NULL, 'password' text NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
235
237
238 {
239 legacy::in::WebApp legacyApp("legacy-testregex");
240
241 legacyApp.use(router(db));
242
243 legacyApp.listen(8080, [](const legacy::in::WebApp::SocketAddress& socketAddress, const core::socket::State& state) {
244 switch (state) {
246 VLOG(1) << "legacy-testregex: listening on '" << socketAddress.toString() << "'";
247 break;
249 VLOG(1) << "legacy-testregex: disabled";
250 break;
252 VLOG(1) << "legacy-testregex: error occurred";
253 break;
255 VLOG(1) << "legacy-testregex: fatal error occurred";
256 break;
257 }
258 });
259
260 legacyApp.setOnConnect([](legacy::in::WebApp::SocketConnection* socketConnection) {
261 VLOG(1) << "OnConnect:";
262
263 VLOG(1) << "\tServer: " + socketConnection->getRemoteAddress().toString();
264 VLOG(1) << "\tClient: " + socketConnection->getLocalAddress().toString();
265 });
266
267 legacyApp.setOnDisconnect([](legacy::in::WebApp::SocketConnection* socketConnection) {
268 VLOG(1) << "OnDisconnect:";
269
270 VLOG(1) << "\tServer: " + socketConnection->getRemoteAddress().toString();
271 VLOG(1) << "\tClient: " + socketConnection->getLocalAddress().toString();
272 });
273
274 tls::in::WebApp tlsApp("tls-testregex");
275
276 tlsApp.use(legacyApp);
277
278 tlsApp.listen(8088, [](const tls::in::WebApp::SocketAddress& socketAddress, const core::socket::State& state) {
279 switch (state) {
281 VLOG(1) << "tls-testregex: listening on '" << socketAddress.toString() << "'";
282 break;
284 VLOG(1) << "tls-testregex: disabled";
285 break;
287 VLOG(1) << "tls-testregex: error occurred";
288 break;
290 VLOG(1) << "tls-testregex: fatal error occurred";
291 break;
292 }
293 });
294
295 tlsApp.setOnConnect([](tls::in::WebApp::SocketConnection* socketConnection) {
296 VLOG(1) << "OnConnect:";
297
298 VLOG(1) << "\tServer: " + socketConnection->getRemoteAddress().toString();
299 VLOG(1) << "\tClient: " + socketConnection->getLocalAddress().toString();
300 });
301
302 tlsApp.setOnConnected([](tls::in::WebApp::SocketConnection* socketConnection) {
303 VLOG(1) << "OnConnected:";
304
305 X509* client_cert = SSL_get_peer_certificate(socketConnection->getSSL());
306
307 if (client_cert != nullptr) {
308 const long verifyErr = SSL_get_verify_result(socketConnection->getSSL());
309
310 VLOG(1) << "\tClient certificate: " + std::string(X509_verify_cert_error_string(verifyErr));
311
312 char* str = X509_NAME_oneline(X509_get_subject_name(client_cert), nullptr, 0);
313 VLOG(1) << "\t Subject: " + std::string(str);
314 OPENSSL_free(str);
315
316 str = X509_NAME_oneline(X509_get_issuer_name(client_cert), nullptr, 0);
317 VLOG(1) << "\t Issuer: " + std::string(str);
318 OPENSSL_free(str);
319
320 // We could do all sorts of certificate verification stuff here before deallocating the certificate.
321
322 GENERAL_NAMES* subjectAltNames =
323 static_cast<GENERAL_NAMES*>(X509_get_ext_d2i(client_cert, NID_subject_alt_name, nullptr, nullptr));
324#ifdef __GNUC__
325#pragma GCC diagnostic push
326#ifdef __has_warning
327#if __has_warning("-Wused-but-marked-unused")
328#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
329#endif
330#endif
331#endif
332 const int32_t altNameCount = sk_GENERAL_NAME_num(subjectAltNames);
333#ifdef __GNUC_
334#pragma GCC diagnostic pop
335#endif
336 VLOG(1) << "\t Subject alternative name count: " << altNameCount;
337 for (int32_t i = 0; i < altNameCount; ++i) {
338#ifdef __GNUC__
339#pragma GCC diagnostic push
340#ifdef __has_warning
341#if __has_warning("-Wused-but-marked-unused")
342#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
343#endif
344#endif
345#endif
346 GENERAL_NAME* generalName = sk_GENERAL_NAME_value(subjectAltNames, i);
347#ifdef __GNUC_
348#pragma GCC diagnostic pop
349#endif
350 if (generalName->type == GEN_URI) {
351 const std::string subjectAltName =
352 std::string(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.uniformResourceIdentifier)),
353 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.uniformResourceIdentifier)));
354 VLOG(1) << "\t SAN (URI): '" + subjectAltName;
355 } else if (generalName->type == GEN_DNS) {
356 const std::string subjectAltName =
357 std::string(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.dNSName)),
358 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.dNSName)));
359 VLOG(1) << "\t SAN (DNS): '" + subjectAltName;
360 } else {
361 VLOG(1) << "\t SAN (Type): '" + std::to_string(generalName->type);
362 }
363 }
364#ifdef __GNUC__
365#pragma GCC diagnostic push
366#ifdef __has_warning
367#if __has_warning("-Wused-but-marked-unused")
368#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
369#endif
370#endif
371#endif
372 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
373#ifdef __GNUC_
374#pragma GCC diagnostic pop
375#endif
376 X509_free(client_cert);
377 } else {
378 VLOG(1) << "\tClient certificate: no certificate";
379 }
380 });
381
382 tlsApp.setOnDisconnect([](tls::in::WebApp::SocketConnection* socketConnection) {
383 VLOG(1) << "OnDisconnect:";
384
385 VLOG(1) << "\tServer: " + socketConnection->getRemoteAddress().toString();
386 VLOG(1) << "\tClient: " + socketConnection->getLocalAddress().toString();
387 });
388 }
389
390 return WebApp::start();
391}
static constexpr int DISABLED
Definition State.h:34
static constexpr int ERROR
Definition State.h:35
static constexpr int FATAL
Definition State.h:36
static constexpr int OK
Definition State.h:33
typename Server::SocketConnection SocketConnection
Definition WebAppT.h:47
typename Server::SocketAddress SocketAddress
Definition WebAppT.h:48
static void init(int argc, char *argv[])
Definition WebApp.cpp:34
static int start(const utils::Timeval &timeOut={LONG_MAX, 0})
Definition WebApp.cpp:38
Router router(database::mariadb::MariaDBClient &db)
Definition testregex.cpp:46

References database::mariadb::MariaDBConnectionDetails::database, database::mariadb::MariaDBConnectionDetails::flags, database::mariadb::MariaDBConnectionDetails::hostname, express::WebApp::init(), database::mariadb::MariaDBClient::MariaDBClient(), database::mariadb::MariaDBConnectionDetails::password, database::mariadb::MariaDBConnectionDetails::port, database::mariadb::MariaDBConnectionDetails::socket, express::WebApp::start(), and database::mariadb::MariaDBConnectionDetails::username.

Here is the call graph for this function:

◆ router()

Definition at line 46 of file testregex.cpp.

46 {
47 const Router router;
48
49 router.get("/test/:variable(\\d)/:uri", [] APPLICATION(req, res) { // http://localhost:8080/test/1/urlstring
50 std::cout << "TEST" << std::endl;
51 });
52 router
53 .get(
54 "/query/:userId",
55 [] MIDDLEWARE(req, res, next) {
56 VLOG(1) << "Move on to the next route to query database";
57 next();
58 },
59 [&db] MIDDLEWARE(req, res, next) { // http://localhost:8080/query/123
60 VLOG(1) << "UserId: " << req->params["userId"];
61 std::string userId = req->params["userId"];
62
63 req->setAttribute<std::string, "html-table">(std::string());
64
65 req->getAttribute<std::string, "html-table">([&userId](std::string& table) {
66 table = "<html>\n"
67 " <head>\n"
68 " <title>"
69 "Response from snode.c for " +
70 userId +
71 "\n"
72 " </title>\n"
73 " </head>\n"
74 " <body>\n"
75 " <h1>Return for " +
76 userId +
77 "\n"
78 " </h1>\n"
79 " <body>\n"
80 " <table border = \"1\">\n";
81 });
82
83 int i = 0;
84 db.query(
85 "SELECT * FROM snodec where username = '" + userId + "'",
86 [next, req, i](const MYSQL_ROW row) mutable {
87 if (row != nullptr) {
88 i++;
89 req->getAttribute<std::string, "html-table">([row, &i](std::string& table) {
90 table.append(" <tr>\n"
91 " <td>\n" +
92 std::to_string(i) +
93 "\n"
94 " </td>\n"
95 " <td>\n" +
96 std::string(row[0]) +
97 "\n"
98 " </td>\n"
99 " <td>\n" +
100 row[1] +
101 "\n"
102 " </td>\n"
103 " </tr>\n");
104 });
105 } else {
106 req->getAttribute<std::string, "html-table">([](std::string& table) {
107 table.append(std::string(" </table>\n"
108 " </body>\n"
109 "</html>\n"));
110 });
111 VLOG(1) << "Move on to the next route to send result";
112 next();
113 }
114 },
115 [res, userId](const std::string& errorString, unsigned int errorNumber) {
116 VLOG(1) << "Error: " << errorString << " : " << errorNumber;
117 res->status(404).send(userId + ": " + errorString + " - " + std::to_string(errorNumber));
118 });
119 },
120 [] MIDDLEWARE(req, res, next) {
121 VLOG(1) << "And again 1: Move on to the next route to send result";
122 next();
123 },
124 [] MIDDLEWARE(req, res, next) {
125 VLOG(1) << "And again 2: Move on to the next route to send result";
126 next();
127 })
128 .get([] MIDDLEWARE(req, res, next) {
129 VLOG(1) << "And again 3: Move on to the next route to send result";
130 next();
131 })
132 .get([] APPLICATION(req, res) {
133 VLOG(1) << "SendResult";
134
135 req->getAttribute<std::string, "html-table">(
136 [res](std::string& table) {
137 res->send(table);
138 },
139 [res](const std::string&) {
140 res->end();
141 });
142 });
143 router.get("/account/:userId(\\d*)/:userName", [&db] APPLICATION(req, res) { // http://localhost:8080/account/123/perfectNDSgroup
144 VLOG(1) << "Show account of";
145 VLOG(1) << "UserId: " << req->params["userId"];
146 VLOG(1) << "UserName: " << req->params["userName"];
147
148 const std::string response = "<html>"
149 " <head>"
150 " <title>Response from snode.c</title>"
151 " </head>"
152 " <body>"
153 " <h1>Regex return</h1>"
154 " <ul>"
155 " <li>UserId: " +
156 req->params["userId"] +
157 " </li>"
158 " <li>UserName: " +
159 req->params["userName"] +
160 " </li>"
161 " </ul>"
162 " </body>"
163 "</html>";
164
165 const std::string userId = req->params["userId"];
166 const std::string userName = req->params["userName"];
167
168 db.exec(
169 "INSERT INTO `snodec`(`username`, `password`) VALUES ('" + userId + "','" + userName + "')",
170 [userId, userName]() {
171 VLOG(1) << "Inserted: -> " << userId << " - " << userName;
172 },
173 [](const std::string& errorString, unsigned int errorNumber) {
174 VLOG(1) << "Error: " << errorString << " : " << errorNumber;
175 });
176
177 res->send(response);
178 });
179 router.get("/asdf/:testRegex1(d\\d{3}e)/jklö/:testRegex2", [] APPLICATION(req, res) { // http://localhost:8080/asdf/d123e/jklö/hallo
180 VLOG(1) << "Testing Regex";
181 VLOG(1) << "Regex1: " << req->params["testRegex1"];
182 VLOG(1) << "Regex2: " << req->params["testRegex2"];
183
184 const std::string response = "<html>"
185 " <head>"
186 " <title>Response from snode.c</title>"
187 " </head>"
188 " <body>"
189 " <h1>Regex return</h1>"
190 " <ul>"
191 " <li>Regex 1: " +
192 req->params["testRegex1"] +
193 " </li>"
194 " <li>Regex 2: " +
195 req->params["testRegex2"] +
196 " </li>"
197 " </ul>"
198 " </body>"
199 "</html>";
200
201 res->send(response);
202 });
203 router.get("/search/:search", [] APPLICATION(req, res) { // http://localhost:8080/search/buxtehude123
204 VLOG(1) << "Show Search of";
205 VLOG(1) << "Search: " << req->params["search"];
206 VLOG(1) << "Queries: " << req->query("test");
207
208 res->send(req->params["search"]);
209 });
210 router.use([] APPLICATION(req, res) {
211 res->status(404).send("Not found: " + req->url);
212 });
213
214 return router;
215}
#define APPLICATION(req, res)
Definition Router.h:45
#define MIDDLEWARE(req, res, next)
Definition Router.h:40
MariaDBCommandSequence & exec(const std::string &sql, const std::function< void(void)> &onExec, const std::function< void(const std::string &, unsigned int)> &onError)
MariaDBCommandSequence & query(const std::string &sql, const std::function< void(const MYSQL_ROW)> &onQuery, const std::function< void(const std::string &, unsigned int)> &onError)
Route & use(const Router &router) const
Definition Router.cpp:60
Route & get(const Router &router) const
Definition Router.cpp:62