Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
CivetServer.h
Go to the documentation of this file.
1/* Copyright (c) 2013-2017 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#ifndef CIVETSERVER_HEADER_INCLUDED
8#define CIVETSERVER_HEADER_INCLUDED
9#ifdef __cplusplus
10
11#include "civetweb.h"
12#include <map>
13#include <stdexcept>
14#include <string>
15#include <vector>
16
17#ifndef CIVETWEB_CXX_API
18#if defined(_WIN32)
19#if defined(CIVETWEB_CXX_DLL_EXPORTS)
20#define CIVETWEB_CXX_API __declspec(dllexport)
21#elif defined(CIVETWEB_CXX_DLL_IMPORTS)
22#define CIVETWEB_CXX_API __declspec(dllimport)
23#else
24#define CIVETWEB_CXX_API
25#endif
26#elif __GNUC__ >= 4
27#define CIVETWEB_CXX_API __attribute__((visibility("default")))
28#else
29#define CIVETWEB_CXX_API
30#endif
31#endif
32
33// forward declaration
34class CivetServer;
35
36/**
37 * Exception class for thrown exceptions within the CivetHandler object.
38 */
39class CIVETWEB_CXX_API CivetException : public std::runtime_error
40{
41 public:
42 CivetException(const std::string &msg) : std::runtime_error(msg)
43 {
44 }
45};
46
47/**
48 * Basic interface for a URI request handler. Handlers implementations
49 * must be reentrant.
50 */
51class CIVETWEB_CXX_API CivetHandler
52{
53 public:
54 /**
55 * Destructor
56 */
57 virtual ~CivetHandler()
58 {
59 }
60
61 /**
62 * Callback method for GET request.
63 *
64 * @param server - the calling server
65 * @param conn - the connection information
66 * @returns true if implemented, false otherwise
67 */
68 virtual bool handleGet(CivetServer *server, struct mg_connection *conn);
69
70 /**
71 * Callback method for GET request.
72 *
73 * @param server - the calling server
74 * @param conn - the connection information
75 * @param status_code - pointer to return status code
76 * @returns true if implemented, false otherwise
77 */
78 virtual bool handleGet(CivetServer *server,
79 struct mg_connection *conn,
80 int *status_code);
81
82 /**
83 * Callback method for POST request.
84 *
85 * @param server - the calling server
86 * @param conn - the connection information
87 * @returns true if implemented, false otherwise
88 */
89 virtual bool handlePost(CivetServer *server, struct mg_connection *conn);
90
91 /**
92 * Callback method for POST request.
93 *
94 * @param server - the calling server
95 * @param conn - the connection information
96 * @param status_code - pointer to return status code
97 * @returns true if implemented, false otherwise
98 */
99 virtual bool handlePost(CivetServer *server,
100 struct mg_connection *conn,
101 int *status_code);
102
103 /**
104 * Callback method for HEAD request.
105 *
106 * @param server - the calling server
107 * @param conn - the connection information
108 * @returns true if implemented, false otherwise
109 */
110 virtual bool handleHead(CivetServer *server, struct mg_connection *conn);
111
112 /**
113 * Callback method for HEAD request.
114 *
115 * @param server - the calling server
116 * @param conn - the connection information
117 * @param status_code - pointer to return status code
118 * @returns true if implemented, false otherwise
119 */
120 virtual bool handleHead(CivetServer *server,
121 struct mg_connection *conn,
122 int *status_code);
123
124 /**
125 * Callback method for PUT request.
126 *
127 * @param server - the calling server
128 * @param conn - the connection information
129 * @returns true if implemented, false otherwise
130 */
131 virtual bool handlePut(CivetServer *server, struct mg_connection *conn);
132
133 /**
134 * Callback method for PUT request.
135 *
136 * @param server - the calling server
137 * @param conn - the connection information
138 * @param status_code - pointer to return status code
139 * @returns true if implemented, false otherwise
140 */
141 virtual bool handlePut(CivetServer *server,
142 struct mg_connection *conn,
143 int *status_code);
144
145 /**
146 * Callback method for DELETE request.
147 *
148 * @param server - the calling server
149 * @param conn - the connection information
150 * @returns true if implemented, false otherwise
151 */
152 virtual bool handleDelete(CivetServer *server, struct mg_connection *conn);
153
154 /**
155 * Callback method for DELETE request.
156 *
157 * @param server - the calling server
158 * @param conn - the connection information
159 * @param status_code - pointer to return status code
160 * @returns true if implemented, false otherwise
161 */
162 virtual bool handleDelete(CivetServer *server,
163 struct mg_connection *conn,
164 int *status_code);
165
166 /**
167 * Callback method for OPTIONS request.
168 *
169 * @param server - the calling server
170 * @param conn - the connection information
171 * @returns true if implemented, false otherwise
172 */
173 virtual bool handleOptions(CivetServer *server, struct mg_connection *conn);
174
175 /**
176 * Callback method for OPTIONS request.
177 *
178 * @param server - the calling server
179 * @param conn - the connection information
180 * @param status_code - pointer to return status code
181 * @returns true if implemented, false otherwise
182 */
183 virtual bool handleOptions(CivetServer *server,
184 struct mg_connection *conn,
185 int *status_code);
186
187 /**
188 * Callback method for PATCH request.
189 *
190 * @param server - the calling server
191 * @param conn - the connection information
192 * @returns true if implemented, false otherwise
193 */
194 virtual bool handlePatch(CivetServer *server, struct mg_connection *conn);
195
196 /**
197 * Callback method for PATCH request.
198 *
199 * @param server - the calling server
200 * @param conn - the connection information
201 * @param status_code - pointer to return status code
202 * @returns true if implemented, false otherwise
203 */
204 virtual bool handlePatch(CivetServer *server,
205 struct mg_connection *conn,
206 int *status_code);
207};
208
209/**
210 * Basic interface for a URI authorization handler. Handler implementations
211 * must be reentrant.
212 */
213class CIVETWEB_CXX_API CivetAuthHandler
214{
215 public:
216 /**
217 * Destructor
218 */
219 virtual ~CivetAuthHandler()
220 {
221 }
222
223 /**
224 * Callback method for authorization requests. It is up the this handler
225 * to generate 401 responses if authorization fails.
226 *
227 * @param server - the calling server
228 * @param conn - the connection information
229 * @returns true if authorization succeeded, false otherwise
230 */
231 virtual bool authorize(CivetServer *server, struct mg_connection *conn) = 0;
232};
233
234/**
235 * Basic interface for a websocket handler. Handlers implementations
236 * must be reentrant.
237 */
238class CIVETWEB_CXX_API CivetWebSocketHandler
239{
240 public:
241 /**
242 * Destructor
243 */
244 virtual ~CivetWebSocketHandler()
245 {
246 }
247
248 /**
249 * Callback method for when the client intends to establish a websocket
250 *connection, before websocket handshake.
251 *
252 * @param server - the calling server
253 * @param conn - the connection information
254 * @returns true to keep socket open, false to close it
255 */
256 virtual bool handleConnection(CivetServer *server,
257 const struct mg_connection *conn);
258
259 /**
260 * Callback method for when websocket handshake is successfully completed,
261 *and connection is ready for data exchange.
262 *
263 * @param server - the calling server
264 * @param conn - the connection information
265 */
266 virtual void handleReadyState(CivetServer *server,
267 struct mg_connection *conn);
268
269 /**
270 * Callback method for when a data frame has been received from the client.
271 *
272 * @param server - the calling server
273 * @param conn - the connection information
274 * @bits: first byte of the websocket frame, see websocket RFC at
275 *http://tools.ietf.org/html/rfc6455, section 5.2
276 * @data, data_len: payload, with mask (if any) already applied.
277 * @returns true to keep socket open, false to close it
278 */
279 virtual bool handleData(CivetServer *server,
280 struct mg_connection *conn,
281 int bits,
282 char *data,
283 size_t data_len);
284
285 /**
286 * Callback method for when the connection is closed.
287 *
288 * @param server - the calling server
289 * @param conn - the connection information
290 */
291 virtual void handleClose(CivetServer *server,
292 const struct mg_connection *conn);
293};
294
295/**
296 * CivetCallbacks
297 *
298 * wrapper for mg_callbacks
299 */
300struct CIVETWEB_CXX_API CivetCallbacks : public mg_callbacks {
301 CivetCallbacks();
302};
303
304/**
305 * CivetServer
306 *
307 * Basic class for embedded web server. This has an URL mapping built-in.
308 */
309class CIVETWEB_CXX_API CivetServer
310{
311 public:
312 /**
313 * Constructor
314 *
315 * This automatically starts the sever.
316 * It is good practice to call getContext() after this in case there
317 * were errors starting the server.
318 *
319 * Note: CivetServer should not be used as a static instance in a Windows
320 * DLL, since the constructor creates threads and the destructor joins
321 * them again (creating/joining threads should not be done in static
322 * constructors).
323 *
324 * @param options - the web server options.
325 * @param callbacks - optional web server callback methods.
326 *
327 * @throws CivetException
328 */
329 CivetServer(const char **options,
330 const struct CivetCallbacks *callbacks = 0,
331 const void *UserContext = 0);
332 CivetServer(const std::vector<std::string> &options,
333 const struct CivetCallbacks *callbacks = 0,
334 const void *UserContext = 0);
335
336 /**
337 * Destructor
338 */
339 virtual ~CivetServer();
340
341 /**
342 * close()
343 *
344 * Stops server and frees resources.
345 */
346 void close();
347
348 /**
349 * getContext()
350 *
351 * @return the context or 0 if not running.
352 */
353 const struct mg_context *
354 getContext() const
355 {
356 return context;
357 }
358
359 /**
360 * addHandler(const std::string &, CivetHandler *)
361 *
362 * Adds a URI handler. If there is existing URI handler, it will
363 * be replaced with this one.
364 *
365 * URI's are ordered and prefix (REST) URI's are supported.
366 *
367 * @param uri - URI to match.
368 * @param handler - handler instance to use.
369 */
370 void addHandler(const std::string &uri, CivetHandler *handler);
371
372 void
373 addHandler(const std::string &uri, CivetHandler &handler)
374 {
375 addHandler(uri, &handler);
376 }
377
378 /**
379 * addWebSocketHandler
380 *
381 * Adds a WebSocket handler for a specific URI. If there is existing URI
382 *handler, it will
383 * be replaced with this one.
384 *
385 * URI's are ordered and prefix (REST) URI's are supported.
386 *
387 * @param uri - URI to match.
388 * @param handler - handler instance to use.
389 */
390 void addWebSocketHandler(const std::string &uri,
391 CivetWebSocketHandler *handler);
392
393 void
394 addWebSocketHandler(const std::string &uri, CivetWebSocketHandler &handler)
395 {
396 addWebSocketHandler(uri, &handler);
397 }
398
399 /**
400 * removeHandler(const std::string &)
401 *
402 * Removes a handler.
403 *
404 * @param uri - the exact URL used in addHandler().
405 */
406 void removeHandler(const std::string &uri);
407
408 /**
409 * removeWebSocketHandler(const std::string &)
410 *
411 * Removes a web socket handler.
412 *
413 * @param uri - the exact URL used in addWebSocketHandler().
414 */
415 void removeWebSocketHandler(const std::string &uri);
416
417 /**
418 * addAuthHandler(const std::string &, CivetAuthHandler *)
419 *
420 * Adds a URI authorization handler. If there is existing URI authorization
421 * handler, it will be replaced with this one.
422 *
423 * URI's are ordered and prefix (REST) URI's are supported.
424 *
425 * @param uri - URI to match.
426 * @param handler - authorization handler instance to use.
427 */
428 void addAuthHandler(const std::string &uri, CivetAuthHandler *handler);
429
430 void
431 addAuthHandler(const std::string &uri, CivetAuthHandler &handler)
432 {
433 addAuthHandler(uri, &handler);
434 }
435
436 /**
437 * removeAuthHandler(const std::string &)
438 *
439 * Removes an authorization handler.
440 *
441 * @param uri - the exact URL used in addAuthHandler().
442 */
443 void removeAuthHandler(const std::string &uri);
444
445 /**
446 * getListeningPorts()
447 *
448 * Returns a list of ports that are listening
449 *
450 * @return A vector of ports
451 */
452
453 std::vector<int> getListeningPorts();
454
455 /**
456 * getListeningPorts()
457 *
458 * Variant of getListeningPorts() returning the full port information
459 * (protocol, SSL, ...)
460 *
461 * @return A vector of ports
462 */
463 std::vector<struct mg_server_port> getListeningPortsFull();
464
465 /**
466 * getCookie(struct mg_connection *conn, const std::string &cookieName,
467 * std::string &cookieValue)
468 *
469 * Puts the cookie value string that matches the cookie name in the
470 * cookieValue destination string.
471 *
472 * @param conn - the connection information
473 * @param cookieName - cookie name to get the value from
474 * @param cookieValue - cookie value is returned using this reference
475 * @returns the size of the cookie value string read.
476 */
477 static int getCookie(struct mg_connection *conn,
478 const std::string &cookieName,
479 std::string &cookieValue);
480
481 /**
482 * getHeader(struct mg_connection *conn, const std::string &headerName)
483 * @param conn - the connection information
484 * @param headerName - header name to get the value from
485 * @returns a char array which contains the header value as string
486 */
487 static const char *getHeader(struct mg_connection *conn,
488 const std::string &headerName);
489
490 /**
491 * getMethod(struct mg_connection *conn)
492 * @param conn - the connection information
493 * @returns method of HTTP request
494 */
495 static const char *getMethod(struct mg_connection *conn);
496
497 /**
498 * getParam(struct mg_connection *conn, const char *, std::string &, size_t)
499 *
500 * Returns a query which contained in the supplied buffer. The
501 * occurrence value is a zero-based index of a particular key name. This
502 * should not be confused with the index over all of the keys. Note that
503 *this
504 * function assumes that parameters are sent as text in http query string
505 * format, which is the default for web forms. This function will work for
506 * html forms with method="GET" and method="POST" attributes. In other
507 *cases,
508 * you may use a getParam version that directly takes the data instead of
509 *the
510 * connection as a first argument.
511 *
512 * @param conn - parameters are read from the data sent through this
513 *connection
514 * @param name - the key to search for
515 * @param dst - the destination string
516 * @param occurrence - the occurrence of the selected name in the query (0
517 *based).
518 * @return true if key was found
519 */
520 static bool getParam(struct mg_connection *conn,
521 const char *name,
522 std::string &dst,
523 size_t occurrence = 0);
524
525 /**
526 * getParam(const std::string &, const char *, std::string &, size_t)
527 *
528 * Returns a query parameter contained in the supplied buffer. The
529 * occurrence value is a zero-based index of a particular key name. This
530 * should not be confused with the index over all of the keys.
531 *
532 * @param data - the query string (text)
533 * @param name - the key to search for
534 * @param dst - the destination string
535 * @param occurrence - the occurrence of the selected name in the query (0
536 *based).
537 * @return true if key was found
538 */
539 static bool
540 getParam(const std::string &data,
541 const char *name,
542 std::string &dst,
543 size_t occurrence = 0)
544 {
545 return getParam(data.c_str(), data.length(), name, dst, occurrence);
546 }
547
548 /**
549 * getParam(const char *, size_t, const char *, std::string &, size_t)
550 *
551 * Returns a query parameter contained in the supplied buffer. The
552 * occurrence value is a zero-based index of a particular key name. This
553 * should not be confused with the index over all of the keys.
554 *
555 * @param data the - query string (text)
556 * @param data_len - length of the query string
557 * @param name - the key to search for
558 * @param dst - the destination string
559 * @param occurrence - the occurrence of the selected name in the query (0
560 *based).
561 * @return true if key was found
562 */
563 static bool getParam(const char *data,
564 size_t data_len,
565 const char *name,
566 std::string &dst,
567 size_t occurrence = 0);
568
569 /**
570 * getPostData(struct mg_connection *)
571 *
572 * Returns response body from a request made as POST. Since the
573 * connections map is protected, it can't be directly accessed.
574 * This uses string to store post data to handle big posts.
575 *
576 * @param conn - connection from which post data will be read
577 * @return Post data (empty if not available).
578 */
579 static std::string getPostData(struct mg_connection *conn);
580
581 /**
582 * urlDecode(const std::string &, std::string &, bool)
583 *
584 * @param src - string to be decoded
585 * @param dst - destination string
586 * @param is_form_url_encoded - true if form url encoded
587 * form-url-encoded data differs from URI encoding in a way that it
588 * uses '+' as character for space, see RFC 1866 section 8.2.1
589 * http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
590 */
591 static void
592 urlDecode(const std::string &src,
593 std::string &dst,
594 bool is_form_url_encoded = true)
595 {
596 urlDecode(src.c_str(), src.length(), dst, is_form_url_encoded);
597 }
598
599 /**
600 * urlDecode(const char *, size_t, std::string &, bool)
601 *
602 * @param src - buffer to be decoded
603 * @param src_len - length of buffer to be decoded
604 * @param dst - destination string
605 * @param is_form_url_encoded - true if form url encoded
606 * form-url-encoded data differs from URI encoding in a way that it
607 * uses '+' as character for space, see RFC 1866 section 8.2.1
608 * http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
609 */
610 static void urlDecode(const char *src,
611 size_t src_len,
612 std::string &dst,
613 bool is_form_url_encoded = true);
614
615 /**
616 * urlDecode(const char *, std::string &, bool)
617 *
618 * @param src - buffer to be decoded (0 terminated)
619 * @param dst - destination string
620 * @param is_form_url_encoded true - if form url encoded
621 * form-url-encoded data differs from URI encoding in a way that it
622 * uses '+' as character for space, see RFC 1866 section 8.2.1
623 * http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
624 */
625 static void urlDecode(const char *src,
626 std::string &dst,
627 bool is_form_url_encoded = true);
628
629 /**
630 * urlEncode(const std::string &, std::string &, bool)
631 *
632 * @param src - buffer to be encoded
633 * @param dst - destination string
634 * @param append - true if string should not be cleared before encoding.
635 */
636 static void
637 urlEncode(const std::string &src, std::string &dst, bool append = false)
638 {
639 urlEncode(src.c_str(), src.length(), dst, append);
640 }
641
642 /**
643 * urlEncode(const char *, size_t, std::string &, bool)
644 *
645 * @param src - buffer to be encoded (0 terminated)
646 * @param dst - destination string
647 * @param append - true if string should not be cleared before encoding.
648 */
649 static void
650 urlEncode(const char *src, std::string &dst, bool append = false);
651
652 /**
653 * urlEncode(const char *, size_t, std::string &, bool)
654 *
655 * @param src - buffer to be encoded
656 * @param src_len - length of buffer to be decoded
657 * @param dst - destination string
658 * @param append - true if string should not be cleared before encoding.
659 */
660 static void urlEncode(const char *src,
661 size_t src_len,
662 std::string &dst,
663 bool append = false);
664
665 // generic user context which can be set/read,
666 // the server does nothing with this apart from keep it.
667 const void *
668 getUserContext() const
669 {
670 return UserContext;
671 }
672
673 protected:
674 class CivetConnection
675 {
676 public:
677 std::vector<char> postData;
678 };
679
680 struct mg_context *context;
681 std::map<const struct mg_connection *, CivetConnection> connections;
682
683 // generic user context which can be set/read,
684 // the server does nothing with this apart from keep it.
685 const void *UserContext;
686
687 private:
688 /**
689 * requestHandler(struct mg_connection *, void *cbdata)
690 *
691 * Handles the incoming request.
692 *
693 * @param conn - the connection information
694 * @param cbdata - pointer to the CivetHandler instance.
695 * @returns 0 if implemented, false otherwise
696 */
697 static int requestHandler(struct mg_connection *conn, void *cbdata);
698
699 static int webSocketConnectionHandler(const struct mg_connection *conn,
700 void *cbdata);
701 static void webSocketReadyHandler(struct mg_connection *conn, void *cbdata);
702 static int webSocketDataHandler(struct mg_connection *conn,
703 int bits,
704 char *data,
705 size_t data_len,
706 void *cbdata);
707 static void webSocketCloseHandler(const struct mg_connection *conn,
708 void *cbdata);
709 /**
710 * authHandler(struct mg_connection *, void *cbdata)
711 *
712 * Handles the authorization requests.
713 *
714 * @param conn - the connection information
715 * @param cbdata - pointer to the CivetAuthHandler instance.
716 * @returns 1 if authorized, 0 otherwise
717 */
718 static int authHandler(struct mg_connection *conn, void *cbdata);
719
720 /**
721 * closeHandler(struct mg_connection *)
722 *
723 * Handles closing a request (internal handler)
724 *
725 * @param conn - the connection information
726 */
727 static void closeHandler(const struct mg_connection *conn);
728
729 /**
730 * Stores the user provided close handler
731 */
732 void (*userCloseHandler)(const struct mg_connection *conn);
733};
734
735#endif /* __cplusplus */
736#endif /* CIVETSERVER_HEADER_INCLUDED */
static int authorize(struct mg_connection *conn, struct mg_file *filep, const char *realm)
Definition civetweb.c:8861
CURL_EXTERN int void curl_formget_callback append
Definition curl.h:2623
const char * name
Definition lsqlite3.c:2154
Definition doctest.h:522