]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/include/CivetServer.h
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / civetweb / include / CivetServer.h
1 /* Copyright (c) 2013-2014 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 _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
18 class CivetServer;
19
20 /**
21 * Exception class for thrown exceptions within the CivetHandler object.
22 */
23 class 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 */
35 class 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 */
113 class 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 */
138 class 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 */
200 struct 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 */
209 class 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,
230 const struct CivetCallbacks *callbacks = 0);
231 CivetServer(std::vector<std::string> options,
232 const struct CivetCallbacks *callbacks = 0);
233
234 /**
235 * Destructor
236 */
237 virtual ~CivetServer();
238
239 /**
240 * close()
241 *
242 * Stops server and frees resources.
243 */
244 void close();
245
246 /**
247 * getContext()
248 *
249 * @return the context or 0 if not running.
250 */
251 const struct mg_context *
252 getContext() const
253 {
254 return context;
255 }
256
257 /**
258 * addHandler(const std::string &, CivetHandler *)
259 *
260 * Adds a URI handler. If there is existing URI handler, it will
261 * be replaced with this one.
262 *
263 * URI's are ordered and prefix (REST) URI's are supported.
264 *
265 * @param uri - URI to match.
266 * @param handler - handler instance to use.
267 */
268 void addHandler(const std::string &uri, CivetHandler *handler);
269
270 void
271 addHandler(const std::string &uri, CivetHandler &handler)
272 {
273 addHandler(uri, &handler);
274 }
275
276 /**
277 * addWebSocketHandler
278 *
279 * Adds a WebSocket handler for a specific URI. If there is existing URI
280 *handler, it will
281 * be replaced with this one.
282 *
283 * URI's are ordered and prefix (REST) URI's are supported.
284 *
285 * @param uri - URI to match.
286 * @param handler - handler instance to use.
287 */
288 void addWebSocketHandler(const std::string &uri,
289 CivetWebSocketHandler *handler);
290
291 void
292 addWebSocketHandler(const std::string &uri, CivetWebSocketHandler &handler)
293 {
294 addWebSocketHandler(uri, &handler);
295 }
296
297 /**
298 * removeHandler(const std::string &)
299 *
300 * Removes a handler.
301 *
302 * @param uri - the exact URL used in addHandler().
303 */
304 void removeHandler(const std::string &uri);
305
306 /**
307 * removeWebSocketHandler(const std::string &)
308 *
309 * Removes a web socket handler.
310 *
311 * @param uri - the exact URL used in addWebSocketHandler().
312 */
313 void removeWebSocketHandler(const std::string &uri);
314
315 /**
316 * addAuthHandler(const std::string &, CivetAuthHandler *)
317 *
318 * Adds a URI authorization handler. If there is existing URI authorization
319 * handler, it will be replaced with this one.
320 *
321 * URI's are ordered and prefix (REST) URI's are supported.
322 *
323 * @param uri - URI to match.
324 * @param handler - authorization handler instance to use.
325 */
326 void addAuthHandler(const std::string &uri, CivetAuthHandler *handler);
327
328 void
329 addAuthHandler(const std::string &uri, CivetAuthHandler &handler)
330 {
331 addAuthHandler(uri, &handler);
332 }
333
334 /**
335 * removeAuthHandler(const std::string &)
336 *
337 * Removes an authorization handler.
338 *
339 * @param uri - the exact URL used in addAuthHandler().
340 */
341 void removeAuthHandler(const std::string &uri);
342
343 /**
344 * getListeningPorts()
345 *
346 * Returns a list of ports that are listening
347 *
348 * @return A vector of ports
349 */
350
351 std::vector<int> getListeningPorts();
352
353 /**
354 * getCookie(struct mg_connection *conn, const std::string &cookieName,
355 *std::string &cookieValue)
356 *
357 * Puts the cookie value string that matches the cookie name in the
358 *cookieValue destinaton string.
359 *
360 * @param conn - the connection information
361 * @param cookieName - cookie name to get the value from
362 * @param cookieValue - cookie value is returned using thiis reference
363 * @returns the size of the cookie value string read.
364 */
365 static int getCookie(struct mg_connection *conn,
366 const std::string &cookieName,
367 std::string &cookieValue);
368
369 /**
370 * getHeader(struct mg_connection *conn, const std::string &headerName)
371 * @param conn - the connection information
372 * @param headerName - header name to get the value from
373 * @returns a char array whcih contains the header value as string
374 */
375 static const char *getHeader(struct mg_connection *conn,
376 const std::string &headerName);
377
378 /**
379 * getParam(struct mg_connection *conn, const char *, std::string &, size_t)
380 *
381 * Returns a query paramter contained in the supplied buffer. The
382 * occurance value is a zero-based index of a particular key name. This
383 * should not be confused with the index over all of the keys. Note that
384 *this
385 * function assumes that parameters are sent as text in http query string
386 * format, which is the default for web forms. This function will work for
387 * html forms with method="GET" and method="POST" attributes. In other
388 *cases,
389 * you may use a getParam version that directly takes the data instead of
390 *the
391 * connection as a first argument.
392 *
393 * @param conn - parameters are read from the data sent through this
394 *connection
395 * @param name - the key to search for
396 * @param dst - the destination string
397 * @param occurrence - the occurrence of the selected name in the query (0
398 *based).
399 * @return true if key was found
400 */
401 static bool getParam(struct mg_connection *conn,
402 const char *name,
403 std::string &dst,
404 size_t occurrence = 0);
405
406 /**
407 * getParam(const std::string &, const char *, std::string &, size_t)
408 *
409 * Returns a query paramter contained in the supplied buffer. The
410 * occurance value is a zero-based index of a particular key name. This
411 * should not be confused with the index over all of the keys.
412 *
413 * @param data - the query string (text)
414 * @param name - the key to search for
415 * @param dst - the destination string
416 * @param occurrence - the occurrence of the selected name in the query (0
417 *based).
418 * @return true if key was found
419 */
420 static bool
421 getParam(const std::string &data,
422 const char *name,
423 std::string &dst,
424 size_t occurrence = 0)
425 {
426 return getParam(data.c_str(), data.length(), name, dst, occurrence);
427 }
428
429 /**
430 * getParam(const char *, size_t, const char *, std::string &, size_t)
431 *
432 * Returns a query paramter contained in the supplied buffer. The
433 * occurance value is a zero-based index of a particular key name. This
434 * should not be confused with the index over all of the keys.
435 *
436 * @param data the - query string (text)
437 * @param data_len - length of the query string
438 * @param name - the key to search for
439 * @param dst - the destination string
440 * @param occurrence - the occurrence of the selected name in the query (0
441 *based).
442 * @return true if key was found
443 */
444 static bool getParam(const char *data,
445 size_t data_len,
446 const char *name,
447 std::string &dst,
448 size_t occurrence = 0);
449
450 /**
451 * urlDecode(const std::string &, std::string &, bool)
452 *
453 * @param src - string to be decoded
454 * @param dst - destination string
455 * @param is_form_url_encoded - true if form url encoded
456 * form-url-encoded data differs from URI encoding in a way that it
457 * uses '+' as character for space, see RFC 1866 section 8.2.1
458 * http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
459 */
460 static void
461 urlDecode(const std::string &src,
462 std::string &dst,
463 bool is_form_url_encoded = true)
464 {
465 urlDecode(src.c_str(), src.length(), dst, is_form_url_encoded);
466 }
467
468 /**
469 * urlDecode(const char *, size_t, std::string &, bool)
470 *
471 * @param src - buffer to be decoded
472 * @param src_len - length of buffer to be decoded
473 * @param dst - destination string
474 * @param is_form_url_encoded - true if form url encoded
475 * form-url-encoded data differs from URI encoding in a way that it
476 * uses '+' as character for space, see RFC 1866 section 8.2.1
477 * http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
478 */
479 static void urlDecode(const char *src,
480 size_t src_len,
481 std::string &dst,
482 bool is_form_url_encoded = true);
483
484 /**
485 * urlDecode(const char *, std::string &, bool)
486 *
487 * @param src - buffer to be decoded (0 terminated)
488 * @param dst - destination string
489 * @param is_form_url_encoded true - if form url encoded
490 * form-url-encoded data differs from URI encoding in a way that it
491 * uses '+' as character for space, see RFC 1866 section 8.2.1
492 * http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
493 */
494 static void urlDecode(const char *src,
495 std::string &dst,
496 bool is_form_url_encoded = true);
497
498 /**
499 * urlEncode(const std::string &, std::string &, bool)
500 *
501 * @param src - buffer to be encoded
502 * @param dst - destination string
503 * @param append - true if string should not be cleared before encoding.
504 */
505 static void
506 urlEncode(const std::string &src, std::string &dst, bool append = false)
507 {
508 urlEncode(src.c_str(), src.length(), dst, append);
509 }
510
511 /**
512 * urlEncode(const char *, size_t, std::string &, bool)
513 *
514 * @param src - buffer to be encoded (0 terminated)
515 * @param dst - destination string
516 * @param append - true if string should not be cleared before encoding.
517 */
518 static void
519 urlEncode(const char *src, std::string &dst, bool append = false);
520
521 /**
522 * urlEncode(const char *, size_t, std::string &, bool)
523 *
524 * @param src - buffer to be encoded
525 * @param src_len - length of buffer to be decoded
526 * @param dst - destination string
527 * @param append - true if string should not be cleared before encoding.
528 */
529 static void urlEncode(const char *src,
530 size_t src_len,
531 std::string &dst,
532 bool append = false);
533
534 protected:
535 class CivetConnection
536 {
537 public:
538 char *postData;
539 unsigned long postDataLen;
540
541 CivetConnection();
542 ~CivetConnection();
543 };
544
545 struct mg_context *context;
546 std::map<struct mg_connection *, class CivetConnection> connections;
547
548 private:
549 /**
550 * requestHandler(struct mg_connection *, void *cbdata)
551 *
552 * Handles the incomming request.
553 *
554 * @param conn - the connection information
555 * @param cbdata - pointer to the CivetHandler instance.
556 * @returns 0 if implemented, false otherwise
557 */
558 static int requestHandler(struct mg_connection *conn, void *cbdata);
559
560 static int webSocketConnectionHandler(const struct mg_connection *conn,
561 void *cbdata);
562 static void webSocketReadyHandler(struct mg_connection *conn, void *cbdata);
563 static int webSocketDataHandler(struct mg_connection *conn,
564 int bits,
565 char *data,
566 size_t data_len,
567 void *cbdata);
568 static void webSocketCloseHandler(const struct mg_connection *conn,
569 void *cbdata);
570 /**
571 * authHandler(struct mg_connection *, void *cbdata)
572 *
573 * Handles the authorization requests.
574 *
575 * @param conn - the connection information
576 * @param cbdata - pointer to the CivetAuthHandler instance.
577 * @returns 1 if authorized, 0 otherwise
578 */
579 static int authHandler(struct mg_connection *conn, void *cbdata);
580
581 /**
582 * closeHandler(struct mg_connection *)
583 *
584 * Handles closing a request (internal handler)
585 *
586 * @param conn - the connection information
587 */
588 static void closeHandler(const struct mg_connection *conn);
589
590 /**
591 * Stores the user provided close handler
592 */
593 void (*userCloseHandler)(const struct mg_connection *conn);
594 };
595
596 #endif /* __cplusplus */
597 #endif /* _CIVETWEB_SERVER_H_ */