server.cpp
Go to the documentation of this file.
1 #include "server.h"
2 
3 #include <chrono>
4 #include <condition_variable>
5 #include <cstdio>
6 #include <mutex>
7 #include <sstream>
8 #include <thread>
9 
10 #include "mongoose.h"
11 
12 #include <time.h>
13 
14 #define SERVER_PORT "8080"
15 
18 std::condition_variable server_cv;
19 
20 static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
21  "abcdefghijklmnopqrstuvwxyz"
22  "0123456789+/";
23 
24 static inline bool is_base64(unsigned char c);
25 std::string base64_decode(std::string const& encoded_string);
26 static int lowercase(const char *s);
27 static int mg_strncasecmp(const char *s1, const char *s2, size_t len);
28 
29 static int options(struct mg_connection* conn) {
30  if (std::string{conn->request_method} == std::string{"OPTIONS"}) {
31  auto response = std::string{""};
32  mg_send_status(conn, 200);
33  mg_send_header(conn, "content-type", "text/html");
34  mg_send_header(conn, "Access-Control-Allow-Origin", "*");
35  mg_send_header(conn, "Access-Control-Allow-Credentials", "true");
36  mg_send_header(conn, "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
37  mg_send_header(conn, "Access-Control-Max-Age", "3600");
38  mg_send_data(conn, response.data(), response.length());
39  } else {
40  auto response = std::string{"Method unallowed"};
41  mg_send_status(conn, 405);
42  mg_send_header(conn, "content-type", "text/html");
43  mg_send_data(conn, response.data(), response.length());
44  }
45  return MG_TRUE;
46 }
47 
48 static int hello(struct mg_connection* conn) {
49  if (std::string{conn->request_method} == std::string{"OPTIONS"}) {
50  auto response = std::string{""};
51  mg_send_status(conn, 200);
52  mg_send_header(conn, "content-type", "text/html");
53  mg_send_header(conn, "Access-Control-Allow-Origin", "*");
54  mg_send_header(conn, "Access-Control-Allow-Credentials", "true");
55  mg_send_header(conn, "Access-Control-Allow-Methods", "GET, OPTIONS");
56  mg_send_header(conn, "Access-Control-Max-Age", "3600");
57  mg_send_data(conn, response.data(), response.length());
58  } else {
59  auto response = std::string{"Hello world!"};
60  mg_send_status(conn, 200);
61  mg_send_header(conn, "content-type", "text/html");
62  mg_send_data(conn, response.data(), response.length());
63  }
64  return MG_TRUE;
65 }
66 
67 static int timeout(struct mg_connection* conn) {
68  std::this_thread::sleep_for(std::chrono::milliseconds(10));
69  auto response = std::string{"Hello world!"};
70  mg_send_status(conn, 200);
71  mg_send_header(conn, "content-type", "text/html");
72  mg_send_data(conn, response.data(), response.length());
73  return MG_TRUE;
74 }
75 
76 static int lowSpeed(struct mg_connection* conn) {
77  auto response = std::string{"Hello world!"};
78  mg_send_status(conn, 200);
79  mg_send_header(conn, "content-type", "text/html");
80  std::this_thread::sleep_for(std::chrono::seconds(2));
81  mg_send_data(conn, response.data(), response.length());
82  return MG_TRUE;
83 }
84 
85 static int lowSpeedBytes(struct mg_connection* conn) {
86  auto response = std::string{"a"};
87  mg_send_status(conn, 200);
88  mg_send_header(conn, "content-type", "text/html");
89  for (auto i = 0; i < 20; ++i) {
90  std::this_thread::sleep_for(std::chrono::milliseconds(100));
91  mg_send_data(conn, response.data(), response.length());
92  }
93  return MG_TRUE;
94 }
95 
96 static int basicCookies(struct mg_connection* conn) {
97  auto response = std::string{"Hello world!"};
98  mg_send_status(conn, 200);
99  mg_send_header(conn, "content-type", "text/html");
100  time_t t = time(NULL) + 5; // Valid for 1 hour
101  char expire[100], expire_epoch[100];
102  snprintf(expire_epoch, sizeof(expire_epoch), "%lu", static_cast<unsigned long>(t));
103  strftime(expire, sizeof(expire), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&t));
104  std::string cookie{"cookie=chocolate; expires=\"" + std::string{expire} + "\"; http-only;"};
105  std::string cookie2{"icecream=vanilla; expires=\"" + std::string{expire} + "\"; http-only;"};
106  mg_send_header(conn, "Set-Cookie", cookie.data());
107  mg_send_header(conn, "Set-Cookie", cookie2.data());
108  mg_send_data(conn, response.data(), response.length());
109  return MG_TRUE;
110 }
111 
112 static int v1Cookies(struct mg_connection* conn) {
113  auto response = std::string{"Hello world!"};
114  mg_send_status(conn, 200);
115  mg_send_header(conn, "content-type", "text/html");
116  time_t t = time(NULL) + 5; // Valid for 1 hour
117  char expire[100], expire_epoch[100];
118  snprintf(expire_epoch, sizeof(expire_epoch), "%lu", static_cast<unsigned long>(t));
119  strftime(expire, sizeof(expire), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&t));
120  std::string v1cookie{"cookie=\"value with spaces (v1 cookie)\"; expires=\"" +
121  std::string{expire} + "\"; http-only;"};
122  mg_send_header(conn, "Set-Cookie", v1cookie.data());
123  mg_send_data(conn, response.data(), response.length());
124  return MG_TRUE;
125 }
126 
127 static int checkBasicCookies(struct mg_connection* conn) {
128  const char* request_cookies;
129  if ((request_cookies = mg_get_header(conn, "Cookie")) == NULL)
130  return MG_FALSE;
131  std::string cookie_str{request_cookies};
132 
133  if (cookie_str.find("cookie=chocolate;") == cookie_str.npos ||
134  cookie_str.find("icecream=vanilla;") == cookie_str.npos) {
135  return MG_FALSE;
136  }
137 
138  auto response = std::string{"Hello world!"};
139  mg_send_status(conn, 200);
140  mg_send_header(conn, "content-type", "text/html");
141  mg_send_data(conn, response.data(), response.length());
142  return MG_TRUE;
143 }
144 
145 static int checkV1Cookies(struct mg_connection* conn) {
146  const char* request_cookies;
147  if ((request_cookies = mg_get_header(conn, "Cookie")) == NULL)
148  return MG_FALSE;
149  std::string cookie_str{request_cookies};
150 
151  if (cookie_str.find("cookie=\"value with spaces (v1 cookie)\";") == cookie_str.npos) {
152  return MG_FALSE;
153  }
154 
155  auto response = std::string{"Hello world!"};
156  mg_send_status(conn, 200);
157  mg_send_header(conn, "content-type", "text/html");
158  mg_send_data(conn, response.data(), response.length());
159  return MG_TRUE;
160 }
161 
162 static int basicAuth(struct mg_connection* conn) {
163  auto response = std::string{"Hello world!"};
164  const char* requested_auth;
165  auto auth = std::string{"Basic"};
166  if ((requested_auth = mg_get_header(conn, "Authorization")) == NULL ||
167  mg_strncasecmp(requested_auth, auth.data(), auth.length()) != 0) {
168  return MG_FALSE;
169  }
170  auto auth_string = std::string{requested_auth};
171  auto basic_token = auth_string.find(' ') + 1;
172  auth_string = auth_string.substr(basic_token, auth_string.length() - basic_token);
173  auth_string = base64_decode(auth_string);
174  auto colon = auth_string.find(':');
175  auto username = auth_string.substr(0, colon);
176  auto password = auth_string.substr(colon + 1, auth_string.length() - colon - 1);
177  if (username == "user" && password == "password") {
178  return MG_TRUE;
179  }
180 
181  return MG_FALSE;
182 }
183 
184 static int digestAuth(struct mg_connection* conn) {
185  int result = MG_FALSE;
186  {
187  FILE *fp;
188  if ((fp = fopen("digest.txt", "w")) != NULL) {
189  fprintf(fp, "user:mydomain.com:0cf722ef3dd136b48da83758c5d855f8\n");
190  fclose(fp);
191  }
192  }
193 
194  {
195  FILE *fp;
196  if ((fp = fopen("digest.txt", "r")) != NULL) {
197  result = mg_authorize_digest(conn, fp);
198  fclose(fp);
199  }
200  }
201 
202  return result;
203 }
204 
205 static int basicJson(struct mg_connection* conn) {
206  auto response = std::string{"[\n"
207  " {\n"
208  " \"first_key\": \"first_value\",\n"
209  " \"second_key\": \"second_value\"\n"
210  " }\n"
211  "]"};
212  mg_send_status(conn, 200);
213  auto raw_header = mg_get_header(conn, "Content-type");
214  std::string header;
215  if (raw_header != NULL) {
216  header = raw_header;
217  }
218  if (!header.empty() && header == "application/json") {
219  mg_send_header(conn, "content-type", "application/json");
220  } else {
221  mg_send_header(conn, "content-type", "application/octet-stream");
222  }
223  mg_send_data(conn, response.data(), response.length());
224  return MG_TRUE;
225 }
226 
227 static int headerReflect(struct mg_connection* conn) {
228  auto response = std::string{"Header reflect "} +
230  mg_send_status(conn, 200);
231  mg_send_header(conn, "content-type", "text/html");
232  auto num_headers = conn->num_headers;
233  auto headers = conn->http_headers;
234  for (int i = 0; i < num_headers; ++i) {
235  auto name = headers[i].name;
236  if (std::string{"Host"} != name && std::string{"Accept"} != name) {
237  mg_send_header(conn, name, headers[i].value);
238  }
239  }
240  mg_send_data(conn, response.data(), response.length());
241  return MG_TRUE;
242 }
243 
244 static int temporaryRedirect(struct mg_connection* conn) {
245  auto response = std::string{"Found"};
246  mg_send_status(conn, 302);
247  mg_send_header(conn, "Location", "hello.html");
248  mg_send_data(conn, response.data(), response.length());
249  return MG_TRUE;
250 }
251 
252 static int permanentRedirect(struct mg_connection* conn) {
253  auto response = std::string{"Moved Permanently"};
254  mg_send_status(conn, 301);
255  mg_send_header(conn, "Location", "hello.html");
256  mg_send_data(conn, response.data(), response.length());
257  return MG_TRUE;
258 }
259 
260 static int twoRedirects(struct mg_connection* conn) {
261  auto response = std::string{"Moved Permanently"};
262  mg_send_status(conn, 301);
263  mg_send_header(conn, "Location", "permanent_redirect.html");
264  mg_send_data(conn, response.data(), response.length());
265  return MG_TRUE;
266 }
267 
268 static int bodyGet(struct mg_connection* conn) {
269  char message[100];
270  mg_get_var(conn, "Message", message, sizeof(message));
271  auto response = std::string{message};
272  mg_send_status(conn, 200);
273  mg_send_header(conn, "content-type", "text/html");
274  mg_send_data(conn, response.data(), response.length());
275  return MG_TRUE;
276 }
277 
278 static int urlPost(struct mg_connection* conn) {
279  mg_send_status(conn, 201);
280  mg_send_header(conn, "content-type", "application/json");
281  char x[100];
282  char y[100];
283  mg_get_var(conn, "x", x, sizeof(x));
284  mg_get_var(conn, "y", y, sizeof(y));
285  auto x_string = std::string{x};
286  auto y_string = std::string{y};
287  if (y_string.empty()) {
288  auto response = std::string{"{\n"
289  " \"x\": " + x_string + "\n"
290  "}"};
291  mg_send_data(conn, response.data(), response.length());
292  } else {
293  std::ostringstream s;
294  s << (atoi(x) + atoi(y));
295  auto response = std::string{"{\n"
296  " \"x\": " + x_string + ",\n"
297  " \"y\": " + y_string + ",\n"
298  " \"sum\": " + s.str() + "\n"
299  "}"};
300  mg_send_data(conn, response.data(), response.length());
301  }
302  return MG_TRUE;
303 }
304 
305 static int jsonPost(struct mg_connection* conn) {
306  auto num_headers = conn->num_headers;
307  auto headers = conn->http_headers;
308  auto has_json_header = false;
309  for (int i = 0; i < num_headers; ++i) {
310  if (std::string{"Content-Type"} == headers[i].name &&
311  std::string{"application/json"} == headers[i].value) {
312  has_json_header = true;
313  }
314  }
315  if (!has_json_header) {
316  auto response = std::string{"Unsupported Media Type"};
317  mg_send_status(conn, 415);
318  mg_send_header(conn, "content-type", "text/html");
319  mg_send_data(conn, response.data(), response.length());
320  return MG_TRUE;
321  }
322  mg_send_status(conn, 201);
323  mg_send_header(conn, "content-type", "application/json");
324  auto response = std::string{conn->content, conn->content_len};
325  mg_send_data(conn, response.data(), response.length());
326  return MG_TRUE;
327 }
328 
329 static int formPost(struct mg_connection* conn) {
330  auto content = conn->content;
331  auto content_len = conn->content_len;
332 
333  std::map<std::string, std::string> forms;
334 
335  while (true) {
336  char* data = new char[10000];
337  int data_len;
338  char name[100];
339  char filename[100];
340  auto read_len = mg_parse_multipart(content, content_len,
341  name, sizeof(name),
342  filename, sizeof(filename),
343  const_cast<const char**>(&data), &data_len);
344  if (read_len == 0) {
345  delete[] data;
346  break;
347  }
348 
349  content += read_len;
350  content_len -= read_len;
351 
352  if (strlen(data) == 0) {
353  delete[] data;
354  break;
355  }
356 
357  forms[name] = std::string{data, static_cast<unsigned long>(data_len)};
358  }
359 
360  mg_send_status(conn, 201);
361  mg_send_header(conn, "content-type", "application/json");
362  if (forms.find("y") == forms.end()) {
363  auto response = std::string{"{\n"
364  " \"x\": " + forms["x"] + "\n"
365  "}"};
366  mg_send_data(conn, response.data(), response.length());
367  } else {
368  std::ostringstream s;
369  s << (atoi(forms["x"].data()) + atoi(forms["y"].data()));
370  auto response = std::string{"{\n"
371  " \"x\": " + forms["x"] + ",\n"
372  " \"y\": " + forms["y"] + ",\n"
373  " \"sum\": " + s.str() + "\n"
374  "}"};
375  mg_send_data(conn, response.data(), response.length());
376  }
377  return MG_TRUE;
378 }
379 
380 static int deleteRequest(struct mg_connection* conn) {
381  auto num_headers = conn->num_headers;
382  auto headers = conn->http_headers;
383  auto has_json_header = false;
384  for (int i = 0; i < num_headers; ++i) {
385  if (std::string{"Content-Type"} == headers[i].name &&
386  std::string{"application/json"} == headers[i].value) {
387  has_json_header = true;
388  }
389  }
390  if (std::string{conn->request_method} == std::string{"DELETE"}) {
391  if (!has_json_header) {
392  auto response = std::string{"Delete success"};
393  mg_send_status(conn, 200);
394  mg_send_header(conn, "content-type", "text/html");
395  mg_send_data(conn, response.data(), response.length());
396  } else {
397  auto response = std::string{conn->content, conn->content_len};
398  mg_send_status(conn, 200);
399  mg_send_header(conn, "content-type", "application/json");
400  mg_send_data(conn, response.data(), response.length());
401  }
402  } else {
403  auto response = std::string{"Method unallowed"};
404  mg_send_status(conn, 405);
405  mg_send_header(conn, "content-type", "text/html");
406  mg_send_data(conn, response.data(), response.length());
407  }
408  return MG_TRUE;
409 }
410 
411 static int deleteUnallowedRequest(struct mg_connection* conn) {
412  if (std::string{conn->request_method} == std::string{"DELETE"}) {
413  auto response = std::string{"Method unallowed"};
414  mg_send_status(conn, 405);
415  mg_send_header(conn, "content-type", "text/html");
416  mg_send_data(conn, response.data(), response.length());
417  } else {
418  auto response = std::string{"Delete success"};
419  mg_send_status(conn, 200);
420  mg_send_header(conn, "content-type", "text/html");
421  mg_send_data(conn, response.data(), response.length());
422  }
423  return MG_TRUE;
424 }
425 
426 static int patch(struct mg_connection* conn) {
427  if (std::string{conn->request_method} == std::string{"PATCH"}) {
428  mg_send_status(conn, 200);
429  mg_send_header(conn, "content-type", "application/json");
430  char x[100];
431  char y[100];
432  mg_get_var(conn, "x", x, sizeof(x));
433  mg_get_var(conn, "y", y, sizeof(y));
434  auto x_string = std::string{x};
435  auto y_string = std::string{y};
436  if (y_string.empty()) {
437  auto response = std::string{"{\n"
438  " \"x\": " + x_string + "\n"
439  "}"};
440  mg_send_data(conn, response.data(), response.length());
441  } else {
442  std::ostringstream s;
443  s << (atoi(x) + atoi(y));
444  auto response = std::string{"{\n"
445  " \"x\": " + x_string + ",\n"
446  " \"y\": " + y_string + ",\n"
447  " \"sum\": " + s.str() + "\n"
448  "}"};
449  mg_send_data(conn, response.data(), response.length());
450  }
451  } else {
452  auto response = std::string{"Method unallowed"};
453  mg_send_status(conn, 405);
454  mg_send_header(conn, "content-type", "text/html");
455  mg_send_data(conn, response.data(), response.length());
456  }
457  return MG_TRUE;
458 }
459 
460 static int patchUnallowed(struct mg_connection* conn) {
461  if (std::string{conn->request_method} == std::string{"PATCH"}) {
462  auto response = std::string{"Method unallowed"};
463  mg_send_status(conn, 405);
464  mg_send_header(conn, "content-type", "text/html");
465  mg_send_data(conn, response.data(), response.length());
466  } else {
467  auto response = std::string{"Patch success"};
468  mg_send_status(conn, 200);
469  mg_send_header(conn, "content-type", "text/html");
470  mg_send_data(conn, response.data(), response.length());
471  }
472  return MG_TRUE;
473 }
474 
475 static int put(struct mg_connection* conn) {
476  if (std::string{conn->request_method} == std::string{"PUT"}) {
477  mg_send_status(conn, 200);
478  mg_send_header(conn, "content-type", "application/json");
479  char x[100];
480  char y[100];
481  mg_get_var(conn, "x", x, sizeof(x));
482  mg_get_var(conn, "y", y, sizeof(y));
483  auto x_string = std::string{x};
484  auto y_string = std::string{y};
485  if (y_string.empty()) {
486  auto response = std::string{"{\n"
487  " \"x\": " + x_string + "\n"
488  "}"};
489  mg_send_data(conn, response.data(), response.length());
490  } else {
491  std::ostringstream s;
492  s << (atoi(x) + atoi(y));
493  auto response = std::string{"{\n"
494  " \"x\": " + x_string + ",\n"
495  " \"y\": " + y_string + ",\n"
496  " \"sum\": " + s.str() + "\n"
497  "}"};
498  mg_send_data(conn, response.data(), response.length());
499  }
500  } else {
501  auto response = std::string{"Method unallowed"};
502  mg_send_status(conn, 405);
503  mg_send_header(conn, "content-type", "text/html");
504  mg_send_data(conn, response.data(), response.length());
505  }
506  return MG_TRUE;
507 }
508 
509 static int putUnallowed(struct mg_connection* conn) {
510  if (std::string{conn->request_method} == std::string{"PUT"}) {
511  auto response = std::string{"Method unallowed"};
512  mg_send_status(conn, 405);
513  mg_send_header(conn, "content-type", "text/html");
514  mg_send_data(conn, response.data(), response.length());
515  } else {
516  auto response = std::string{"Put success"};
517  mg_send_status(conn, 200);
518  mg_send_header(conn, "content-type", "text/html");
519  mg_send_data(conn, response.data(), response.length());
520  }
521  return MG_TRUE;
522 }
523 
524 static int evHandler(struct mg_connection* conn, enum mg_event ev) {
525  switch (ev) {
526  case MG_AUTH:
527  if (Url{conn->uri} == "/basic_auth.html") {
528  return basicAuth(conn);
529  } else if (Url{conn->uri} == "/digest_auth.html") {
530  return digestAuth(conn);
531  }
532  return MG_TRUE;
533  case MG_REQUEST:
534  if (Url{conn->uri} == "/") {
535  return options(conn);
536  } else if (Url{conn->uri} == "/hello.html") {
537  return hello(conn);
538  } else if (Url{conn->uri} == "/timeout.html") {
539  return timeout(conn);
540  } else if (Url{conn->uri} == "/low_speed.html") {
541  return lowSpeed(conn);
542  } else if (Url{conn->uri} == "/low_speed_bytes.html") {
543  return lowSpeedBytes(conn);
544  } else if (Url{conn->uri} == "/basic_cookies.html") {
545  return basicCookies(conn);
546  } else if (Url{conn->uri} == "/check_cookies.html") {
547  return checkBasicCookies(conn);
548  } else if (Url{conn->uri} == "/v1_cookies.html") {
549  return v1Cookies(conn);
550  } else if (Url{conn->uri} == "/check_v1_cookies.html") {
551  return checkV1Cookies(conn);
552  } else if (Url{conn->uri} == "/basic_auth.html") {
553  return headerReflect(conn);
554  } else if (Url{conn->uri} == "/digest_auth.html") {
555  return headerReflect(conn);
556  } else if (Url{conn->uri} == "/basic.json") {
557  return basicJson(conn);
558  } else if (Url{conn->uri} == "/header_reflect.html") {
559  return headerReflect(conn);
560  } else if (Url{conn->uri} == "/temporary_redirect.html") {
561  return temporaryRedirect(conn);
562  } else if (Url{conn->uri} == "/permanent_redirect.html") {
563  return permanentRedirect(conn);
564  } else if (Url{conn->uri} == "/two_redirects.html") {
565  return twoRedirects(conn);
566  } else if (Url{conn->uri} == "/url_post.html") {
567  return urlPost(conn);
568  } else if (Url{conn->uri} == "/body_get.html") {
569  return bodyGet(conn);
570  } else if (Url{conn->uri} == "/json_post.html") {
571  return jsonPost(conn);
572  } else if (Url{conn->uri} == "/form_post.html") {
573  return formPost(conn);
574  } else if (Url{conn->uri} == "/delete.html") {
575  return deleteRequest(conn);
576  } else if (Url{conn->uri} == "/delete_unallowed.html") {
577  return deleteUnallowedRequest(conn);
578  } else if (Url{conn->uri} == "/put.html") {
579  return put(conn);
580  } else if (Url{conn->uri} == "/put_unallowed.html") {
581  return putUnallowed(conn);
582  } else if (Url{conn->uri} == "/patch.html") {
583  return patch(conn);
584  } else if (Url{conn->uri} == "/patch_unallowed.html") {
585  return patchUnallowed(conn);
586  }
587  return MG_FALSE;
588  default:
589  return MG_FALSE;
590  }
591 }
592 
593 void runServer(struct mg_server* server) {
594  {
595  std::lock_guard<std::mutex> server_lock(server_mutex);
596  mg_set_option(server, "listening_port", SERVER_PORT);
597  server_cv.notify_one();
598  }
599 
600  do {
601  mg_poll_server(server, 1000);
602  } while (!shutdown_mutex.try_lock());
603 
604  shutdown_mutex.unlock();
605  std::lock_guard<std::mutex> server_lock(server_mutex);
606  mg_destroy_server(&server);
607  server_cv.notify_one();
608 }
609 
611  shutdown_mutex.lock();
612  struct mg_server* server;
613  server = mg_create_server(NULL, evHandler);
614  std::unique_lock<std::mutex> server_lock(server_mutex);
615  std::thread(runServer, server).detach();
616  server_cv.wait(server_lock);
617 }
618 
620  std::unique_lock<std::mutex> server_lock(server_mutex);
621  shutdown_mutex.unlock();
622  server_cv.wait(server_lock);
623 }
624 
626  return Url{"http://127.0.0.1:"}.append(SERVER_PORT);
627 }
628 
630  return Url{"https://127.0.0.1:"}.append(SERVER_PORT);
631 }
632 
633 static inline bool is_base64(unsigned char c) {
634  return (isalnum(c) || (c == '+') || (c == '/'));
635 }
636 
637 std::string base64_decode(std::string const& encoded_string) {
638  int in_len = encoded_string.size();
639  int i = 0;
640  int j = 0;
641  int in_ = 0;
642  unsigned char char_array_4[4], char_array_3[3];
643  std::string ret;
644 
645  while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
646  char_array_4[i++] = encoded_string[in_]; in_++;
647  if (i ==4) {
648  for (i = 0; i <4; i++) {
649  char_array_4[i] = base64_chars.find(char_array_4[i]);
650  }
651 
652  char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
653  char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
654  char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
655 
656  for (i = 0; (i < 3); i++) {
657  ret += char_array_3[i];
658  }
659 
660  i = 0;
661  }
662  }
663 
664  if (i) {
665  for (j = i; j <4; j++) {
666  char_array_4[j] = 0;
667  }
668 
669  for (j = 0; j <4; j++) {
670  char_array_4[j] = base64_chars.find(char_array_4[j]);
671  }
672 
673  char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
674  char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
675  char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
676 
677  for (j = 0; (j < i - 1); j++) {
678  ret += char_array_3[j];
679  }
680  }
681 
682  return ret;
683 }
684 
685 static int lowercase(const char *s) {
686  return tolower(* reinterpret_cast<const unsigned char *>(s));
687 }
688 
689 static int mg_strncasecmp(const char *s1, const char *s2, size_t len) {
690  int diff = 0;
691 
692  if (len > 0) {
693  do {
694  diff = lowercase(s1++) - lowercase(s2++);
695  } while (diff == 0 && s1[-1] != '\0' && --len > 0);
696  }
697 
698  return diff;
699 }
700 
Url GetBaseUrlSSL()
Definition: server.cpp:629
struct mg_connection::mg_header http_headers[30]
int mg_get_var(const struct mg_connection *conn, const char *name, char *dst, size_t dst_len)
Definition: mongoose.c:5040
void mg_send_header(struct mg_connection *c, const char *name, const char *v)
Definition: mongoose.c:2759
filename
static int lowercase(const char *s)
Definition: server.cpp:685
std::string Url
Definition: cprtypes.h:14
static int options(struct mg_connection *conn)
Definition: server.cpp:29
static pthread_mutex_t mutex
Definition: os400sys.c:86
static int checkBasicCookies(struct mg_connection *conn)
Definition: server.cpp:127
static int basicAuth(struct mg_connection *conn)
Definition: server.cpp:162
const char * mg_get_header(const struct mg_connection *ri, const char *s)
Definition: mongoose.c:2566
const char * uri
Definition: mongoose.h:34
::std::string string
Definition: gtest-port.h:1129
XmlRpcServer s
IMETHOD Vector diff(const Vector &p_w_a, const Vector &p_w_b, double dt=1)
void runServer(struct mg_server *server)
Definition: server.cpp:593
static int mg_strncasecmp(const char *s1, const char *s2, size_t len)
Definition: server.cpp:689
struct mg_server * mg_create_server(void *server_data, mg_handler_t handler)
Definition: mongoose.c:5431
static char * password
Definition: unit1304.c:27
void mg_send_status(struct mg_connection *c, int status)
Definition: mongoose.c:2750
TFSIMD_FORCE_INLINE const tfScalar & y() const
static int twoRedirects(struct mg_connection *conn)
Definition: server.cpp:260
geometry_msgs::TransformStamped t
UNITTEST_START int result
Definition: unit1304.c:49
static int deleteRequest(struct mg_connection *conn)
Definition: server.cpp:380
static int headerReflect(struct mg_connection *conn)
Definition: server.cpp:227
std::mutex server_mutex
Definition: server.cpp:17
int j
static int digestAuth(struct mg_connection *conn)
Definition: server.cpp:184
static int jsonPost(struct mg_connection *conn)
Definition: server.cpp:305
unsigned int i
Definition: unit1303.c:79
size_t len
Definition: curl_sasl.c:55
time_t mg_poll_server(struct mg_server *server, int milliseconds)
Definition: mongoose.c:4965
Definition: urldata.h:1179
static int patchUnallowed(struct mg_connection *conn)
Definition: server.cpp:460
std::condition_variable server_cv
Definition: server.cpp:18
static int patch(struct mg_connection *conn)
Definition: server.cpp:426
static int putUnallowed(struct mg_connection *conn)
Definition: server.cpp:509
static int formPost(struct mg_connection *conn)
Definition: server.cpp:329
UNITTEST_START struct Curl_easy data
Definition: unit1399.c:82
mg_event
Definition: mongoose.h:62
static struct mg_server * server
Definition: web_server.c:72
static int basicJson(struct mg_connection *conn)
Definition: server.cpp:205
static const std::string base64_chars
Definition: server.cpp:20
TFSIMD_FORCE_INLINE const tfScalar & x() const
static int lowSpeedBytes(struct mg_connection *conn)
Definition: server.cpp:85
virtual void TearDown()
Definition: server.cpp:619
int num_headers
Definition: mongoose.h:43
Url GetBaseUrl()
Definition: server.cpp:625
std::mutex shutdown_mutex
Definition: server.cpp:16
int mg_authorize_digest(struct mg_connection *c, FILE *fp)
Definition: mongoose.c:4163
static int put(struct mg_connection *conn)
Definition: server.cpp:475
static int lowSpeed(struct mg_connection *conn)
Definition: server.cpp:76
static int urlPost(struct mg_connection *conn)
Definition: server.cpp:278
static int bodyGet(struct mg_connection *conn)
Definition: server.cpp:268
const char * mg_set_option(struct mg_server *server, const char *name, const char *value)
Definition: mongoose.c:5143
UNITTEST_START int * value
Definition: unit1602.c:51
std::string base64_decode(std::string const &encoded_string)
Definition: server.cpp:637
static int basicCookies(struct mg_connection *conn)
Definition: server.cpp:96
static int v1Cookies(struct mg_connection *conn)
Definition: server.cpp:112
#define fprintf
Definition: curl_printf.h:41
#define snprintf
Definition: curl_printf.h:42
static int deleteUnallowedRequest(struct mg_connection *conn)
Definition: server.cpp:411
static int hello(struct mg_connection *conn)
Definition: server.cpp:48
#define SERVER_PORT
Definition: server.cpp:14
static int evHandler(struct mg_connection *conn, enum mg_event ev)
Definition: server.cpp:524
static int timeout(struct mg_connection *conn)
Definition: server.cpp:67
const char * request_method
Definition: mongoose.h:33
const char * name
Definition: curl_sasl.c:54
virtual void SetUp()
Definition: server.cpp:610
int mg_parse_multipart(const char *buf, int buf_len, char *var_name, int var_name_len, char *file_name, int file_name_len, const char **data, int *data_len)
Definition: mongoose.c:5056
static int temporaryRedirect(struct mg_connection *conn)
Definition: server.cpp:244
void mg_destroy_server(struct mg_server **server)
Definition: mongoose.c:4969
Definition: debug.c:29
size_t content_len
Definition: mongoose.h:50
static int checkV1Cookies(struct mg_connection *conn)
Definition: server.cpp:145
static bool is_base64(unsigned char c)
Definition: server.cpp:633
char * content
Definition: mongoose.h:49
size_t mg_send_data(struct mg_connection *c, const void *data, int data_len)
Definition: mongoose.c:2778
static int permanentRedirect(struct mg_connection *conn)
Definition: server.cpp:252


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:16