CivetServer.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Copyright (c) 2013 No Face Press, LLC
  3. * License http://opensource.org/licenses/mit-license.php MIT License
  4. */
  5. #include "CivetServer.h"
  6. #include <stdlib.h>
  7. #include <string.h>
  8. int CivetServer::begin_request_callback(struct mg_connection *conn) {
  9. struct mg_request_info *request_info = mg_get_request_info(conn);
  10. if (!request_info->user_data)
  11. return 0;
  12. CivetServer *me = (CivetServer*) (request_info->user_data);
  13. if (me->handleRequest(conn)) {
  14. return 1; // Mark as processed
  15. }
  16. return 0;
  17. }
  18. bool CivetServer::handleRequest(struct mg_connection *conn) {
  19. struct mg_request_info *request_info = mg_get_request_info(conn);
  20. CivetHandler *handler = getHandler(request_info->uri);
  21. if (handler) {
  22. if (strcmp(request_info->request_method, "GET") == 0) {
  23. return handler->handleGet(this, conn);
  24. } else if (strcmp(request_info->request_method, "POST") == 0) {
  25. return handler->handlePost(this, conn);
  26. } else if (strcmp(request_info->request_method, "PUT") == 0) {
  27. return !handler->handlePost(this, conn);
  28. } else if (strcmp(request_info->request_method, "DELETE") == 0) {
  29. return !handler->handlePost(this, conn);
  30. }
  31. }
  32. return false; // No handler found
  33. }
  34. CivetServer::CivetServer(const char **options,
  35. const struct mg_callbacks *_callbacks) :
  36. context(0) {
  37. struct mg_callbacks callbacks;
  38. if (_callbacks) {
  39. memcpy(&callbacks, _callbacks, sizeof(callbacks));
  40. } else {
  41. memset(&callbacks, 0, sizeof(callbacks));
  42. }
  43. callbacks.begin_request = &begin_request_callback;
  44. context = mg_start(&callbacks, this, options);
  45. }
  46. CivetServer::~CivetServer() {
  47. close();
  48. }
  49. CivetHandler *CivetServer::getHandler(const char *uri, unsigned urilen) const {
  50. for (unsigned index = 0; index < uris.size(); index++) {
  51. const std::string &handlerURI = uris[index];
  52. // first try for an exact match
  53. if (handlerURI == uri) {
  54. return handlers[index];
  55. }
  56. // next try for a partial match
  57. // we will accept uri/something
  58. if (handlerURI.length() < urilen
  59. && uri[handlerURI.length()] == '/'
  60. && handlerURI.compare(0, handlerURI.length(), uri, handlerURI.length()) == 0) {
  61. return handlers[index];
  62. }
  63. }
  64. return 0; // none found
  65. }
  66. void CivetServer::addHandler(const std::string &uri, CivetHandler *handler) {
  67. int index = getIndex(uri);
  68. if (index < 0) {
  69. uris.push_back(uri);
  70. handlers.push_back(handler);
  71. } else if (handlers[index] != handler) {
  72. delete handlers[index];
  73. handlers[index] = handler;
  74. }
  75. }
  76. void CivetServer::removeHandler(const std::string &uri) {
  77. int index = getIndex(uri);
  78. if (index >= 0) {
  79. uris.erase(uris.begin() + index, uris.begin() + index + 1);
  80. handlers.erase(handlers.begin() + index, handlers.begin() + index + 1);
  81. }
  82. }
  83. int CivetServer::getIndex(const std::string &uri) const {
  84. for (unsigned index = 0; index < uris.size(); index++) {
  85. if (uris[index].compare(uri) == 0)
  86. return index;
  87. }
  88. return -1;
  89. }
  90. void CivetServer::close() {
  91. if (context) {
  92. mg_stop (context);
  93. context = 0;
  94. }
  95. for (int i = handlers.size() - 1; i >= 0; i--) {
  96. delete handlers[i];
  97. }
  98. handlers.clear();
  99. uris.clear();
  100. }