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