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 268 of file testregex.cpp.

268 {
269 WebApp::init(argc, argv);
270
272 .connectionName = "regex",
273 .hostname = "localhost",
274 .username = "snodec",
275 .password = "pentium5",
276 .database = "snodec",
277 .port = 3306,
278 .socket = "/run/mysqld/mysqld.sock",
279 .flags = 0,
280 };
281
282 // CREATE USER 'snodec'@localhost IDENTIFIED BY 'pentium5'
283 // GRANT ALL PRIVILEGES ON *.* TO 'snodec'@localhost
284 // GRANT ALL PRIVILEGES ON 'snodec'.'snodec' TO 'snodec'@localhost
285 // CREATE DATABASE 'snodec';
286 // CREATE TABLE 'snodec' ('username' text NOT NULL, 'password' text NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
287
289 if (state.error != 0) {
290 VLOG(0) << "MySQL error: " << state.errorMessage << " [" << state.error << "]";
291 } else if (state.connected) {
292 VLOG(0) << "MySQL connected";
293 } else {
294 VLOG(0) << "MySQL disconnected";
295 }
296 });
297
298 {
299 legacy::in::WebApp legacyApp("legacy-testregex");
300
301 legacyApp.use(router(db));
302
303 legacyApp.listen(8080, [](const legacy::in::WebApp::SocketAddress& socketAddress, const core::socket::State& state) {
304 switch (state) {
306 VLOG(1) << "legacy-testregex: listening on '" << socketAddress.toString() << "'";
307 break;
309 VLOG(1) << "legacy-testregex: disabled";
310 break;
312 VLOG(1) << "legacy-testregex: error occurred";
313 break;
315 VLOG(1) << "legacy-testregex: fatal error occurred";
316 break;
317 }
318 });
319
320 legacyApp.setOnConnect([](legacy::in::WebApp::SocketConnection* socketConnection) {
321 VLOG(1) << "OnConnect:";
322
323 VLOG(1) << "\tServer: " + socketConnection->getRemoteAddress().toString();
324 VLOG(1) << "\tClient: " + socketConnection->getLocalAddress().toString();
325 });
326
327 legacyApp.setOnDisconnect([](legacy::in::WebApp::SocketConnection* socketConnection) {
328 VLOG(1) << "OnDisconnect:";
329
330 VLOG(1) << "\tServer: " + socketConnection->getRemoteAddress().toString();
331 VLOG(1) << "\tClient: " + socketConnection->getLocalAddress().toString();
332 });
333
334 tls::in::WebApp tlsApp("tls-testregex");
335
336 tlsApp.use(legacyApp);
337
338 tlsApp.listen(8088, [](const tls::in::WebApp::SocketAddress& socketAddress, const core::socket::State& state) {
339 switch (state) {
341 VLOG(1) << "tls-testregex: listening on '" << socketAddress.toString() << "'";
342 break;
344 VLOG(1) << "tls-testregex: disabled";
345 break;
347 VLOG(1) << "tls-testregex: error occurred";
348 break;
350 VLOG(1) << "tls-testregex: fatal error occurred";
351 break;
352 }
353 });
354
355 tlsApp.setOnConnect([](tls::in::WebApp::SocketConnection* socketConnection) {
356 VLOG(1) << "OnConnect:";
357
358 VLOG(1) << "\tServer: " + socketConnection->getRemoteAddress().toString();
359 VLOG(1) << "\tClient: " + socketConnection->getLocalAddress().toString();
360 });
361
362 tlsApp.setOnConnected([](tls::in::WebApp::SocketConnection* socketConnection) {
363 VLOG(1) << "OnConnected:";
364
365 X509* client_cert = SSL_get_peer_certificate(socketConnection->getSSL());
366
367 if (client_cert != nullptr) {
368 const long verifyErr = SSL_get_verify_result(socketConnection->getSSL());
369
370 VLOG(1) << "\tClient certificate: " + std::string(X509_verify_cert_error_string(verifyErr));
371
372 char* str = X509_NAME_oneline(X509_get_subject_name(client_cert), nullptr, 0);
373 VLOG(1) << "\t Subject: " + std::string(str);
374 OPENSSL_free(str);
375
376 str = X509_NAME_oneline(X509_get_issuer_name(client_cert), nullptr, 0);
377 VLOG(1) << "\t Issuer: " + std::string(str);
378 OPENSSL_free(str);
379
380 // We could do all sorts of certificate verification stuff here before deallocating the certificate.
381
382 GENERAL_NAMES* subjectAltNames =
383 static_cast<GENERAL_NAMES*>(X509_get_ext_d2i(client_cert, NID_subject_alt_name, nullptr, nullptr));
384
385 const int32_t altNameCount = sk_GENERAL_NAME_num(subjectAltNames);
386
387 VLOG(1) << "\t Subject alternative name count: " << altNameCount;
388 for (int32_t i = 0; i < altNameCount; ++i) {
389 GENERAL_NAME* generalName = sk_GENERAL_NAME_value(subjectAltNames, i);
390 if (generalName->type == GEN_URI) {
391 const std::string subjectAltName =
392 std::string(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.uniformResourceIdentifier)),
393 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.uniformResourceIdentifier)));
394 VLOG(1) << "\t SAN (URI): '" + subjectAltName;
395 } else if (generalName->type == GEN_DNS) {
396 const std::string subjectAltName =
397 std::string(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.dNSName)),
398 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.dNSName)));
399 VLOG(1) << "\t SAN (DNS): '" + subjectAltName;
400 } else {
401 VLOG(1) << "\t SAN (Type): '" + std::to_string(generalName->type);
402 }
403 }
404
405 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
406
407 X509_free(client_cert);
408 } else {
409 VLOG(1) << "\tClient certificate: no certificate";
410 }
411 });
412
413 tlsApp.setOnDisconnect([](tls::in::WebApp::SocketConnection* socketConnection) {
414 VLOG(1) << "OnDisconnect:";
415
416 VLOG(1) << "\tServer: " + socketConnection->getRemoteAddress().toString();
417 VLOG(1) << "\tClient: " + socketConnection->getLocalAddress().toString();
418 });
419 }
420
421 return WebApp::start();
422}
static constexpr int DISABLED
Definition State.h:56
static constexpr int ERROR
Definition State.h:57
static constexpr int FATAL
Definition State.h:58
static constexpr int OK
Definition State.h:55
typename Server::SocketConnection SocketConnection
Definition WebAppT.h:67
typename Server::SocketAddress SocketAddress
Definition WebAppT.h:68
static void init(int argc, char *argv[])
Definition WebApp.cpp:56
static int start(const utils::Timeval &timeOut={LONG_MAX, 0})
Definition WebApp.cpp:60
WebAppT< web::http::legacy::in::Server > WebApp
Definition WebApp.h:56
WebAppT< web::http::tls::in::Server > WebApp
Definition WebApp.h:54
Router router(database::mariadb::MariaDBClient &db)
Definition testregex.cpp:67

References database::mariadb::MariaDBState::connected, database::mariadb::MariaDBConnectionDetails::connectionName, database::mariadb::MariaDBConnectionDetails::database, database::mariadb::MariaDBState::error, database::mariadb::MariaDBState::errorMessage, database::mariadb::MariaDBConnectionDetails::flags, database::mariadb::MariaDBConnectionDetails::hostname, express::WebApp::init(), 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 67 of file testregex.cpp.

67 {
68 const Router router;
69
70 router.get(R"(/r1/:id([^/]+))", [] APPLICATION(req, res) {
71 std::cout << "Hier 1a ************" << std::endl;
72 std::cout << "Params: " << req->params["id"] << std::endl;
73 res->send("Done\n");
74 });
75
76 router.get(R"(/r1/:id/:subcollection)", [] APPLICATION(req, res) {
77 std::cout << "Hier 1b ************" << std::endl;
78 std::cout << "Params: " << req->params["id"] << std::endl;
79 std::cout << "Params: " << req->params["subcollection"] << std::endl;
80 res->send("Done\n");
81 });
82
83 router.get(R"(/r2/:id)", [] APPLICATION(req, res) {
84 std::cout << "Hier 2a ************" << std::endl;
85 std::cout << "Params: " << req->params["id"] << std::endl;
86 res->send("Done\n");
87 });
88
89 router.get(R"(/r2/:id/:subcollection)", [] APPLICATION(req, res) {
90 std::cout << "Hier 2b ************" << std::endl;
91 std::cout << "Params: " << req->params["id"] << std::endl;
92 std::cout << "Params: " << req->params["subcollection"] << std::endl;
93 res->send("Done\n");
94 });
95
96 router.get("/test/:variable(\\d)/:uri", [] APPLICATION(req, res) { // http://localhost:8080/test/1/urlstring
97 std::cout << "Hier 3 ************" << std::endl;
98 std::cout << "Params: " << req->params["variable"] << std::endl;
99 std::cout << "Params: " << req->params["uri"] << std::endl;
100 res->send("Done\n");
101 });
102
103 router
104 .get(
105 "/query/:userId",
106 [] MIDDLEWARE(req, res, next) {
107 VLOG(1) << "Move on to the next route to query database";
108 next();
109 },
110 [&db] MIDDLEWARE(req, res, next) { // http://localhost:8080/query/123
111 VLOG(1) << "UserId: " << req->params["userId"];
112 std::string userId = req->params["userId"];
113
114 req->setAttribute<std::string, "html-table">(std::string());
115
116 req->getAttribute<std::string, "html-table">([&userId](std::string& table) {
117 table = "<html>\n"
118 " <head>\n"
119 " <title>"
120 "Response from snode.c for " +
121 userId +
122 "\n"
123 " </title>\n"
124 " </head>\n"
125 " <body>\n"
126 " <h1>Return for " +
127 userId +
128 "\n"
129 " </h1>\n"
130 " <body>\n"
131 " <table border = \"1\">\n";
132 });
133
134 int i = 0;
135 db.query(
136 "SELECT * FROM snodec where username = '" + userId + "'",
137 [next, req, i](const MYSQL_ROW row) mutable {
138 if (row != nullptr) {
139 i++;
140 req->getAttribute<std::string, "html-table">([row, &i](std::string& table) {
141 table.append(" <tr>\n"
142 " <td>\n" +
143 std::to_string(i) +
144 "\n"
145 " </td>\n"
146 " <td>\n" +
147 std::string(row[0]) +
148 "\n"
149 " </td>\n"
150 " <td>\n" +
151 row[1] +
152 "\n"
153 " </td>\n"
154 " </tr>\n");
155 });
156 } else {
157 req->getAttribute<std::string, "html-table">([](std::string& table) {
158 table.append(std::string(" </table>\n"
159 " </body>\n"
160 "</html>\n"));
161 });
162 VLOG(1) << "Move on to the next route to send result";
163 next();
164 }
165 },
166 [res, userId](const std::string& errorString, unsigned int errorNumber) {
167 VLOG(1) << "Error: " << errorString << " : " << errorNumber;
168 res->status(404).send(userId + ": " + errorString + " - " + std::to_string(errorNumber));
169 });
170 },
171 [] MIDDLEWARE(req, res, next) {
172 VLOG(1) << "And again 1: Move on to the next route to send result";
173 next();
174 },
175 [] MIDDLEWARE(req, res, next) {
176 VLOG(1) << "And again 2: Move on to the next route to send result";
177 next();
178 })
179 .get([] MIDDLEWARE(req, res, next) {
180 VLOG(1) << "And again 3: Move on to the next route to send result";
181 next();
182 })
183 .get([] APPLICATION(req, res) {
184 VLOG(1) << "SendResult";
185
186 req->getAttribute<std::string, "html-table">(
187 [res](std::string& table) {
188 res->send(table);
189 },
190 [res](const std::string&) {
191 res->end();
192 });
193 });
194 router.get("/account/:userId(\\d*)/:userName", [&db] APPLICATION(req, res) { // http://localhost:8080/account/123/perfectNDSgroup
195 VLOG(1) << "Show account of";
196 VLOG(1) << "UserId: " << req->params["userId"];
197 VLOG(1) << "UserName: " << req->params["userName"];
198
199 const std::string response = "<html>"
200 " <head>"
201 " <title>Response from snode.c</title>"
202 " </head>"
203 " <body>"
204 " <h1>Regex return</h1>"
205 " <ul>"
206 " <li>UserId: " +
207 req->params["userId"] +
208 " </li>"
209 " <li>UserName: " +
210 req->params["userName"] +
211 " </li>"
212 " </ul>"
213 " </body>"
214 "</html>";
215
216 const std::string userId = req->params["userId"];
217 const std::string userName = req->params["userName"];
218
219 db.exec(
220 "INSERT INTO `snodec`(`username`, `password`) VALUES ('" + userId + "','" + userName + "')",
221 [userId, userName]() {
222 VLOG(1) << "Inserted: -> " << userId << " - " << userName;
223 },
224 [](const std::string& errorString, unsigned int errorNumber) {
225 VLOG(1) << "Error: " << errorString << " : " << errorNumber;
226 });
227
228 res->send(response);
229 });
230 router.get("/asdf/:testRegex1(d\\d{3}e)/jklö/:testRegex2", [] APPLICATION(req, res) { // http://localhost:8080/asdf/d123e/jklö/hallo
231 VLOG(1) << "Testing Regex";
232 VLOG(1) << "Regex1: " << req->params["testRegex1"];
233 VLOG(1) << "Regex2: " << req->params["testRegex2"];
234
235 const std::string response = "<html>"
236 " <head>"
237 " <title>Response from snode.c</title>"
238 " </head>"
239 " <body>"
240 " <h1>Regex return</h1>"
241 " <ul>"
242 " <li>Regex 1: " +
243 req->params["testRegex1"] +
244 " </li>"
245 " <li>Regex 2: " +
246 req->params["testRegex2"] +
247 " </li>"
248 " </ul>"
249 " </body>"
250 "</html>";
251
252 res->send(response);
253 });
254 router.get("/search/:search", [] APPLICATION(req, res) { // http://localhost:8080/search/buxtehude123
255 VLOG(1) << "Show Search of";
256 VLOG(1) << "Search: " << req->params["search"];
257 VLOG(1) << "Queries: " << req->query("test");
258
259 res->send(req->params["search"]);
260 });
261 router.use([] APPLICATION(req, res) {
262 res->status(404).send("Not found: " + req->url);
263 });
264
265 return router;
266}
#define APPLICATION(req, res)
Definition Router.h:68
#define MIDDLEWARE(req, res, next)
Definition Router.h:63
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)

References database::mariadb::MariaDBClientASyncAPI::exec(), and database::mariadb::MariaDBClientASyncAPI::query().

Here is the call graph for this function: