Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
CivetServer.cpp
Go to the documentation of this file.
1/* Copyright (c) 2013-2020 the Civetweb developers
2 * Copyright (c) 2013 No Face Press, LLC
3 *
4 * License http://opensource.org/licenses/mit-license.php MIT License
5 */
6
7#include "CivetServer.h"
8
9#include <assert.h>
10#include <stdexcept>
11#include <string.h>
12
13#ifndef UNUSED_PARAMETER
14#define UNUSED_PARAMETER(x) (void)(x)
15#endif
16
17#ifndef MAX_PARAM_BODY_LENGTH
18// Set a default limit for parameters in a form body: 2 MB
19#define MAX_PARAM_BODY_LENGTH (1024 * 1024 * 2)
20#endif
21
22bool
23CivetHandler::handleGet(CivetServer *server, struct mg_connection *conn)
24{
25 UNUSED_PARAMETER(server);
26 UNUSED_PARAMETER(conn);
27 return false;
28}
29
30bool
31CivetHandler::handleGet(CivetServer *server,
32 struct mg_connection *conn,
33 int *status_code)
34{
35 UNUSED_PARAMETER(server);
36 UNUSED_PARAMETER(conn);
37 if (status_code) {
38 *status_code = -1;
39 }
40 return false;
41}
42
43bool
44CivetHandler::handlePost(CivetServer *server, struct mg_connection *conn)
45{
46 UNUSED_PARAMETER(server);
47 UNUSED_PARAMETER(conn);
48 return false;
49}
50
51bool
52CivetHandler::handlePost(CivetServer *server,
53 struct mg_connection *conn,
54 int *status_code)
55{
56 UNUSED_PARAMETER(server);
57 UNUSED_PARAMETER(conn);
58 if (status_code) {
59 *status_code = -1;
60 }
61 return false;
62}
63
64bool
65CivetHandler::handleHead(CivetServer *server, struct mg_connection *conn)
66{
67 UNUSED_PARAMETER(server);
68 UNUSED_PARAMETER(conn);
69 return false;
70}
71
72bool
73CivetHandler::handleHead(CivetServer *server,
74 struct mg_connection *conn,
75 int *status_code)
76{
77 UNUSED_PARAMETER(server);
78 UNUSED_PARAMETER(conn);
79 if (status_code) {
80 *status_code = -1;
81 }
82 return false;
83}
84
85bool
86CivetHandler::handlePut(CivetServer *server, struct mg_connection *conn)
87{
88 UNUSED_PARAMETER(server);
89 UNUSED_PARAMETER(conn);
90 return false;
91}
92
93bool
94CivetHandler::handlePut(CivetServer *server,
95 struct mg_connection *conn,
96 int *status_code)
97{
98 UNUSED_PARAMETER(server);
99 UNUSED_PARAMETER(conn);
100 if (status_code) {
101 *status_code = -1;
102 }
103 return false;
104}
105
106bool
107CivetHandler::handlePatch(CivetServer *server, struct mg_connection *conn)
108{
109 UNUSED_PARAMETER(server);
110 UNUSED_PARAMETER(conn);
111 return false;
112}
113
114bool
115CivetHandler::handlePatch(CivetServer *server,
116 struct mg_connection *conn,
117 int *status_code)
118{
119 UNUSED_PARAMETER(server);
120 UNUSED_PARAMETER(conn);
121 if (status_code) {
122 *status_code = -1;
123 }
124 return false;
125}
126
127bool
128CivetHandler::handleDelete(CivetServer *server, struct mg_connection *conn)
129{
130 UNUSED_PARAMETER(server);
131 UNUSED_PARAMETER(conn);
132 return false;
133}
134
135bool
136CivetHandler::handleDelete(CivetServer *server,
137 struct mg_connection *conn,
138 int *status_code)
139{
140 UNUSED_PARAMETER(server);
141 UNUSED_PARAMETER(conn);
142 if (status_code) {
143 *status_code = -1;
144 }
145 return false;
146}
147
148bool
149CivetHandler::handleOptions(CivetServer *server, struct mg_connection *conn)
150{
151 UNUSED_PARAMETER(server);
152 UNUSED_PARAMETER(conn);
153 return false;
154}
155
156bool
157CivetHandler::handleOptions(CivetServer *server,
158 struct mg_connection *conn,
159 int *status_code)
160{
161 UNUSED_PARAMETER(server);
162 UNUSED_PARAMETER(conn);
163 if (status_code) {
164 *status_code = -1;
165 }
166 return false;
167}
168
169bool
170CivetWebSocketHandler::handleConnection(CivetServer *server,
171 const struct mg_connection *conn)
172{
173 UNUSED_PARAMETER(server);
174 UNUSED_PARAMETER(conn);
175 return true;
176}
177
178void
179CivetWebSocketHandler::handleReadyState(CivetServer *server,
180 struct mg_connection *conn)
181{
182 UNUSED_PARAMETER(server);
183 UNUSED_PARAMETER(conn);
184 return;
185}
186
187bool
188CivetWebSocketHandler::handleData(CivetServer *server,
189 struct mg_connection *conn,
190 int bits,
191 char *data,
192 size_t data_len)
193{
194 UNUSED_PARAMETER(server);
195 UNUSED_PARAMETER(conn);
196 UNUSED_PARAMETER(bits);
197 UNUSED_PARAMETER(data);
198 UNUSED_PARAMETER(data_len);
199 return true;
200}
201
202void
203CivetWebSocketHandler::handleClose(CivetServer *server,
204 const struct mg_connection *conn)
205{
206 UNUSED_PARAMETER(server);
207 UNUSED_PARAMETER(conn);
208 return;
209}
210
211int
212CivetServer::requestHandler(struct mg_connection *conn, void *cbdata)
213{
214 const struct mg_request_info *request_info = mg_get_request_info(conn);
215 assert(request_info != NULL);
216 CivetServer *me = (CivetServer *)(request_info->user_data);
217 assert(me != NULL);
218 int http_status_code = -1;
219 bool status_ok = false;
220
221 // Happens when a request hits the server before the context is saved
222 if (me->context == NULL)
223 return 0;
224
225 mg_lock_context(me->context);
226 me->connections[conn] = CivetConnection();
227 mg_unlock_context(me->context);
228
229 CivetHandler *handler = (CivetHandler *)cbdata;
230
231 if (handler) {
232 if (strcmp(request_info->request_method, "GET") == 0) {
233 status_ok = handler->handleGet(me, conn, &http_status_code);
234 if (http_status_code < 0) {
235 status_ok = handler->handleGet(me, conn);
236 }
237 } else if (strcmp(request_info->request_method, "POST") == 0) {
238 status_ok = handler->handlePost(me, conn, &http_status_code);
239 if (http_status_code < 0) {
240 status_ok = handler->handlePost(me, conn);
241 }
242 } else if (strcmp(request_info->request_method, "HEAD") == 0) {
243 status_ok = handler->handleHead(me, conn, &http_status_code);
244 if (http_status_code < 0) {
245 status_ok = handler->handleHead(me, conn);
246 }
247 } else if (strcmp(request_info->request_method, "PUT") == 0) {
248 status_ok = handler->handlePut(me, conn, &http_status_code);
249 if (http_status_code < 0) {
250 status_ok = handler->handlePut(me, conn);
251 }
252 } else if (strcmp(request_info->request_method, "DELETE") == 0) {
253 status_ok = handler->handleDelete(me, conn, &http_status_code);
254 if (http_status_code < 0) {
255 status_ok = handler->handleDelete(me, conn);
256 }
257 } else if (strcmp(request_info->request_method, "OPTIONS") == 0) {
258 status_ok = handler->handleOptions(me, conn, &http_status_code);
259 if (http_status_code < 0) {
260 status_ok = handler->handleOptions(me, conn);
261 }
262 } else if (strcmp(request_info->request_method, "PATCH") == 0) {
263 status_ok = handler->handlePatch(me, conn, &http_status_code);
264 if (http_status_code < 0) {
265 status_ok = handler->handlePatch(me, conn);
266 }
267 }
268 }
269
270 if (http_status_code < 0) {
271 http_status_code = status_ok ? 1 : 0;
272 }
273
274 return http_status_code;
275}
276
277int
278CivetServer::authHandler(struct mg_connection *conn, void *cbdata)
279{
280 const struct mg_request_info *request_info = mg_get_request_info(conn);
281 assert(request_info != NULL);
282 CivetServer *me = (CivetServer *)(request_info->user_data);
283 assert(me != NULL);
284
285 // Happens when a request hits the server before the context is saved
286 if (me->context == NULL)
287 return 0;
288
289 mg_lock_context(me->context);
290 me->connections[conn] = CivetConnection();
291 mg_unlock_context(me->context);
292
293 CivetAuthHandler *handler = (CivetAuthHandler *)cbdata;
294
295 if (handler) {
296 return handler->authorize(me, conn) ? 1 : 0;
297 }
298
299 return 0; // No handler found
300}
301
302int
303CivetServer::webSocketConnectionHandler(const struct mg_connection *conn,
304 void *cbdata)
305{
306 const struct mg_request_info *request_info = mg_get_request_info(conn);
307 assert(request_info != NULL);
308 CivetServer *me = (CivetServer *)(request_info->user_data);
309 assert(me != NULL);
310
311 // Happens when a request hits the server before the context is saved
312 if (me->context == NULL)
313 return 0;
314
315 CivetWebSocketHandler *handler = (CivetWebSocketHandler *)cbdata;
316
317 if (handler) {
318 return handler->handleConnection(me, conn) ? 0 : 1;
319 }
320
321 return 1; // No handler found, close connection
322}
323
324void
325CivetServer::webSocketReadyHandler(struct mg_connection *conn, void *cbdata)
326{
327 const struct mg_request_info *request_info = mg_get_request_info(conn);
328 assert(request_info != NULL);
329 CivetServer *me = (CivetServer *)(request_info->user_data);
330 assert(me != NULL);
331
332 // Happens when a request hits the server before the context is saved
333 if (me->context == NULL)
334 return;
335
336 CivetWebSocketHandler *handler = (CivetWebSocketHandler *)cbdata;
337
338 if (handler) {
339 handler->handleReadyState(me, conn);
340 }
341}
342
343int
344CivetServer::webSocketDataHandler(struct mg_connection *conn,
345 int bits,
346 char *data,
347 size_t data_len,
348 void *cbdata)
349{
350 const struct mg_request_info *request_info = mg_get_request_info(conn);
351 assert(request_info != NULL);
352 CivetServer *me = (CivetServer *)(request_info->user_data);
353 assert(me != NULL);
354
355 // Happens when a request hits the server before the context is saved
356 if (me->context == NULL)
357 return 0;
358
359 CivetWebSocketHandler *handler = (CivetWebSocketHandler *)cbdata;
360
361 if (handler) {
362 return handler->handleData(me, conn, bits, data, data_len) ? 1 : 0;
363 }
364
365 return 1; // No handler found
366}
367
368void
369CivetServer::webSocketCloseHandler(const struct mg_connection *conn,
370 void *cbdata)
371{
372 const struct mg_request_info *request_info = mg_get_request_info(conn);
373 assert(request_info != NULL);
374 CivetServer *me = (CivetServer *)(request_info->user_data);
375 assert(me != NULL);
376
377 // Happens when a request hits the server before the context is saved
378 if (me->context == NULL)
379 return;
380
381 CivetWebSocketHandler *handler = (CivetWebSocketHandler *)cbdata;
382
383 if (handler) {
384 handler->handleClose(me, conn);
385 }
386}
387
388CivetCallbacks::CivetCallbacks()
389{
390 memset(this, 0, sizeof(*this));
391}
392
393CivetServer::CivetServer(const char **options,
394 const struct CivetCallbacks *_callbacks,
395 const void *UserContextIn)
396 : context(0)
397{
398 struct CivetCallbacks callbacks;
399
400 UserContext = UserContextIn;
401
402 if (_callbacks) {
403 callbacks = *_callbacks;
404 userCloseHandler = _callbacks->connection_close;
405 } else {
406 userCloseHandler = NULL;
407 }
408 callbacks.connection_close = closeHandler;
409 struct mg_init_data mg_start_init_data = {0};
410 mg_start_init_data.callbacks = &callbacks;
411 mg_start_init_data.user_data = this;
412 mg_start_init_data.configuration_options = options;
413
414 struct mg_error_data mg_start_error_data = {0};
415 char errtxtbuf[256] = {0};
416 mg_start_error_data.text = errtxtbuf;
417 mg_start_error_data.text_buffer_size = sizeof(errtxtbuf);
418
419 context = mg_start2(&mg_start_init_data, &mg_start_error_data);
420
421 if (context == NULL) {
422 std::string exceptionMsg =
423 "null context when constructing CivetServer. "
424 "Possible problem binding to port. Error: ";
425 exceptionMsg += errtxtbuf;
426 throw CivetException(exceptionMsg);
427 }
428}
429
430CivetServer::CivetServer(const std::vector<std::string> &options,
431 const struct CivetCallbacks *_callbacks,
432 const void *UserContextIn)
433 : context(0)
434{
435 struct CivetCallbacks callbacks;
436
437 UserContext = UserContextIn;
438
439 if (_callbacks) {
440 callbacks = *_callbacks;
441 userCloseHandler = _callbacks->connection_close;
442 } else {
443 userCloseHandler = NULL;
444 }
445 callbacks.connection_close = closeHandler;
446
447 std::vector<const char *> pointers(options.size() + 1);
448 for (size_t i = 0; i < options.size(); i++) {
449 pointers[i] = (options[i].c_str());
450 }
451 pointers.back() = NULL;
452
453 struct mg_init_data mg_start_init_data = {0};
454 mg_start_init_data.callbacks = &callbacks;
455 mg_start_init_data.user_data = this;
456 mg_start_init_data.configuration_options = &pointers[0];
457
458 struct mg_error_data mg_start_error_data = {0};
459 char errtxtbuf[256] = {0};
460 mg_start_error_data.text = errtxtbuf;
461 mg_start_error_data.text_buffer_size = sizeof(errtxtbuf);
462
463 context = mg_start2(&mg_start_init_data, &mg_start_error_data);
464
465 if (context == NULL) {
466 std::string exceptionMsg =
467 "null context when constructing CivetServer. "
468 "Possible problem binding to port. Error: ";
469 exceptionMsg += errtxtbuf;
470 throw CivetException(exceptionMsg);
471 }
472}
473
474CivetServer::~CivetServer()
475{
476 close();
477}
478
479void
480CivetServer::closeHandler(const struct mg_connection *conn)
481{
482 CivetServer *me = (CivetServer *)mg_get_user_data(mg_get_context(conn));
483 assert(me != NULL);
484
485 // Happens when a request hits the server before the context is saved
486 if (me->context == NULL)
487 return;
488
489 if (me->userCloseHandler) {
490 me->userCloseHandler(conn);
491 }
492 mg_lock_context(me->context);
493 me->connections.erase(conn);
494 mg_unlock_context(me->context);
495}
496
497void
498CivetServer::addHandler(const std::string &uri, CivetHandler *handler)
499{
500 mg_set_request_handler(context, uri.c_str(), requestHandler, handler);
501}
502
503void
504CivetServer::addWebSocketHandler(const std::string &uri,
505 CivetWebSocketHandler *handler)
506{
508 uri.c_str(),
509 webSocketConnectionHandler,
510 webSocketReadyHandler,
511 webSocketDataHandler,
512 webSocketCloseHandler,
513 handler);
514}
515
516void
517CivetServer::addAuthHandler(const std::string &uri, CivetAuthHandler *handler)
518{
519 mg_set_auth_handler(context, uri.c_str(), authHandler, handler);
520}
521
522void
523CivetServer::removeHandler(const std::string &uri)
524{
525 mg_set_request_handler(context, uri.c_str(), NULL, NULL);
526}
527
528void
529CivetServer::removeWebSocketHandler(const std::string &uri)
530{
532 context, uri.c_str(), NULL, NULL, NULL, NULL, NULL);
533}
534
535void
536CivetServer::removeAuthHandler(const std::string &uri)
537{
538 mg_set_auth_handler(context, uri.c_str(), NULL, NULL);
539}
540
541void
542CivetServer::close()
543{
544 if (context) {
545 mg_stop(context);
546 context = 0;
547 }
548}
549
550int
551CivetServer::getCookie(struct mg_connection *conn,
552 const std::string &cookieName,
553 std::string &cookieValue)
554{
555 // Maximum cookie length as per microsoft is 4096.
556 // http://msdn.microsoft.com/en-us/library/ms178194.aspx
557 char _cookieValue[4096];
558 const char *cookie = mg_get_header(conn, "Cookie");
559 int lRead = mg_get_cookie(cookie,
560 cookieName.c_str(),
561 _cookieValue,
562 sizeof(_cookieValue));
563 cookieValue.clear();
564 if (lRead >= 0) {
565 cookieValue.append(_cookieValue);
566 }
567 return lRead;
568}
569
570const char *
571CivetServer::getHeader(struct mg_connection *conn,
572 const std::string &headerName)
573{
574 return mg_get_header(conn, headerName.c_str());
575}
576
577const char *
578CivetServer::getMethod(struct mg_connection *conn)
579{
580 const struct mg_request_info *request_info = mg_get_request_info(conn);
581 assert(request_info != NULL);
582 return request_info->request_method;
583}
584
585void
586CivetServer::urlDecode(const char *src,
587 std::string &dst,
588 bool is_form_url_encoded)
589{
590 urlDecode(src, strlen(src), dst, is_form_url_encoded);
591}
592
593void
594CivetServer::urlDecode(const char *src,
595 size_t src_len,
596 std::string &dst,
597 bool is_form_url_encoded)
598{
599 // assign enough buffer
600 std::vector<char> buf(src_len + 1);
601 int r = mg_url_decode(src,
602 static_cast<int>(src_len),
603 &buf[0],
604 static_cast<int>(buf.size()),
605 is_form_url_encoded);
606 if (r < 0) {
607 // never reach here
608 throw std::out_of_range("");
609 }
610 // dst can contain NUL characters
611 dst.assign(buf.begin(), buf.begin() + r);
612}
613
614bool
615CivetServer::getParam(struct mg_connection *conn,
616 const char *name,
617 std::string &dst,
618 size_t occurrence)
619{
620 const char *formParams = NULL;
621 const char *queryString = NULL;
622 const struct mg_request_info *ri = mg_get_request_info(conn);
623 assert(ri != NULL);
624 CivetServer *me = (CivetServer *)(ri->user_data);
625 assert(me != NULL);
626 mg_lock_context(me->context);
627 CivetConnection &conobj = me->connections[conn];
628 mg_unlock_context(me->context);
629
630 mg_lock_connection(conn);
631 if (conobj.postData.empty()) {
632 // check if there is a request body
633 for (;;) {
634 char buf[2048];
635 int r = mg_read(conn, buf, sizeof(buf));
636 try {
637 if (r == 0) {
638 conobj.postData.push_back('\0');
639 break;
640 } else if ((r < 0)
641 || ((conobj.postData.size() + r)
643 conobj.postData.assign(1, '\0');
644 break;
645 }
646 conobj.postData.insert(conobj.postData.end(), buf, buf + r);
647 } catch (...) {
648 conobj.postData.clear();
649 break;
650 }
651 }
652 }
653 if (!conobj.postData.empty()) {
654 // check if form parameter are already stored
655 formParams = &conobj.postData[0];
656 }
657
658 if (ri->query_string != NULL) {
659 // get requests do store html <form> field values in the http
660 // query_string
661 queryString = ri->query_string;
662 }
663
665
666 bool get_param_success = false;
667 if (formParams != NULL) {
668 get_param_success =
669 getParam(formParams, strlen(formParams), name, dst, occurrence);
670 }
671 if (!get_param_success && queryString != NULL) {
672 get_param_success =
673 getParam(queryString, strlen(queryString), name, dst, occurrence);
674 }
675
676 return get_param_success;
677}
678
679bool
680CivetServer::getParam(const char *data,
681 size_t data_len,
682 const char *name,
683 std::string &dst,
684 size_t occurrence)
685{
686 char buf[256];
687 int r = mg_get_var2(data, data_len, name, buf, sizeof(buf), occurrence);
688 if (r >= 0) {
689 // dst can contain NUL characters
690 dst.assign(buf, r);
691 return true;
692 } else if (r == -2) {
693 // more buffer
694 std::vector<char> vbuf(sizeof(buf) * 2);
695 for (;;) {
696 r = mg_get_var2(
697 data, data_len, name, &vbuf[0], vbuf.size(), occurrence);
698 if (r >= 0) {
699 dst.assign(vbuf.begin(), vbuf.begin() + r);
700 return true;
701 } else if (r != -2) {
702 break;
703 }
704 // more buffer
705 vbuf.resize(vbuf.size() * 2);
706 }
707 }
708 dst.clear();
709 return false;
710}
711
712std::string
713CivetServer::getPostData(struct mg_connection *conn)
714{
715 mg_lock_connection(conn);
716 std::string postdata;
717 char buf[2048];
718 int r = mg_read(conn, buf, sizeof(buf));
719 while (r > 0) {
720 postdata.append(buf, r);
721 r = mg_read(conn, buf, sizeof(buf));
722 }
724 return postdata;
725}
726
727void
728CivetServer::urlEncode(const char *src, std::string &dst, bool append)
729{
730 urlEncode(src, strlen(src), dst, append);
731}
732
733void
734CivetServer::urlEncode(const char *src,
735 size_t src_len,
736 std::string &dst,
737 bool append)
738{
739 if (!append)
740 dst.clear();
741
742 for (; src_len > 0; src++, src_len--) {
743 if (*src == '\0') {
744 // src and dst can contain NUL characters without encoding
745 dst.push_back(*src);
746 } else {
747 char buf[2] = {*src, '\0'};
748 char dst_buf[4];
749 if (mg_url_encode(buf, dst_buf, sizeof(dst_buf)) < 0) {
750 // never reach here
751 throw std::out_of_range("");
752 }
753 dst.append(dst_buf);
754 }
755 }
756}
757
758std::vector<int>
759CivetServer::getListeningPorts()
760{
761 std::vector<struct mg_server_port> server_ports = getListeningPortsFull();
762
763 std::vector<int> ports(server_ports.size());
764 for (size_t i = 0; i < server_ports.size(); i++) {
765 ports[i] = server_ports[i].port;
766 }
767
768 return ports;
769}
770
771std::vector<struct mg_server_port>
772CivetServer::getListeningPortsFull()
773{
774 std::vector<struct mg_server_port> server_ports(8);
775 for (;;) {
776 int size = mg_get_server_ports(context,
777 static_cast<int>(server_ports.size()),
778 &server_ports[0]);
779 if (size < static_cast<int>(server_ports.size())) {
780 server_ports.resize(size < 0 ? 0 : size);
781 break;
782 }
783 server_ports.resize(server_ports.size() * 2);
784 }
785 return server_ports;
786}
#define UNUSED_PARAMETER(x)
#define MAX_PARAM_BODY_LENGTH
CIVETWEB_API void mg_lock_context(struct mg_context *ctx)
Definition civetweb.c:13018
CIVETWEB_API void mg_lock_connection(struct mg_connection *conn)
Definition civetweb.c:13000
CIVETWEB_API void * mg_get_user_data(const struct mg_context *ctx)
Definition civetweb.c:3195
CIVETWEB_API struct mg_context * mg_start2(struct mg_init_data *init, struct mg_error_data *error)
Definition civetweb.c:20464
CIVETWEB_API void mg_unlock_connection(struct mg_connection *conn)
Definition civetweb.c:13009
CIVETWEB_API const char * mg_get_header(const struct mg_connection *conn, const char *name)
Definition civetweb.c:3855
CIVETWEB_API void mg_set_websocket_handler(struct mg_context *ctx, const char *uri, mg_websocket_connect_handler connect_handler, mg_websocket_ready_handler ready_handler, mg_websocket_data_handler data_handler, mg_websocket_close_handler close_handler, void *cbdata)
Definition civetweb.c:14488
CIVETWEB_API int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
Definition civetweb.c:7048
CIVETWEB_API int mg_get_var2(const char *data, size_t data_len, const char *name, char *dst, size_t dst_len, size_t occurrence)
Definition civetweb.c:7099
CIVETWEB_API void mg_unlock_context(struct mg_context *ctx)
Definition civetweb.c:13027
CIVETWEB_API void mg_stop(struct mg_context *ctx)
Definition civetweb.c:20346
CIVETWEB_API int mg_get_cookie(const char *cookie_header, const char *var_name, char *dst, size_t dst_size)
Definition civetweb.c:7256
CIVETWEB_API int mg_get_server_ports(const struct mg_context *ctx, int size, struct mg_server_port *ports)
Definition civetweb.c:3248
CIVETWEB_API struct mg_context * mg_get_context(const struct mg_connection *conn)
Definition civetweb.c:3188
CIVETWEB_API const struct mg_request_info * mg_get_request_info(const struct mg_connection *conn)
Definition civetweb.c:3521
CIVETWEB_API void mg_set_auth_handler(struct mg_context *ctx, const char *uri, mg_authorization_handler handler, void *cbdata)
Definition civetweb.c:14538
CIVETWEB_API void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata)
Definition civetweb.c:14466
CIVETWEB_API int mg_read(struct mg_connection *conn, void *buf, size_t len)
Definition civetweb.c:6614
CIVETWEB_API int mg_url_encode(const char *src, char *dst, size_t dst_len)
Definition civetweb.c:9581
CURL_EXTERN int void curl_formget_callback append
Definition curl.h:2623
#define NULL
Definition gmacros.h:924
const char * name
Definition lsqlite3.c:2154
size_t text_buffer_size
Definition civetweb.h:1727
void * user_data
Definition civetweb.h:1800
const struct mg_callbacks * callbacks
Definition civetweb.h:1799
const char ** configuration_options
Definition civetweb.h:1801
void * user_data
Definition civetweb.h:175
const char * request_method
Definition civetweb.h:151
const char * query_string
Definition civetweb.h:162