CivetServer.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright (c) 2013 Thomas Davis
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE
  20. #include <CivetServer.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. int CivetServer::begin_request_callback(struct mg_connection *conn) {
  24. struct mg_request_info *request_info = mg_get_request_info(conn);
  25. if (!request_info->user_data)
  26. return 0;
  27. CivetServer *me = (CivetServer*) (request_info->user_data);
  28. if (me->handleRequest(conn)) {
  29. return 1; // Mark as processed
  30. }
  31. return 0;
  32. }
  33. bool CivetServer::handleRequest(struct mg_connection *conn) {
  34. struct mg_request_info *request_info = mg_get_request_info(conn);
  35. CivetHandler *handler = getHandler(request_info->uri);
  36. if (handler) {
  37. if (strcmp(request_info->request_method, "GET") == 0) {
  38. return handler->handleGet(this, conn);
  39. } else if (strcmp(request_info->request_method, "POST") == 0) {
  40. return handler->handlePost(this, conn);
  41. } else if (strcmp(request_info->request_method, "PUT") == 0) {
  42. return !handler->handlePost(this, conn);
  43. } else if (strcmp(request_info->request_method, "DELETE") == 0) {
  44. return !handler->handlePost(this, conn);
  45. }
  46. }
  47. return false; // No handler found
  48. }
  49. CivetServer::CivetServer(const char **options,
  50. const struct mg_callbacks *_callbacks) :
  51. context(0) {
  52. struct mg_callbacks callbacks;
  53. if (_callbacks) {
  54. memcpy(&callbacks, _callbacks, sizeof(callbacks));
  55. } else {
  56. memset(&callbacks, 0, sizeof(callbacks));
  57. }
  58. callbacks.begin_request = &begin_request_callback;
  59. context = mg_start(&callbacks, this, options);
  60. }
  61. CivetServer::~CivetServer() {
  62. close();
  63. }
  64. CivetHandler *CivetServer::getHandler(const char *uri, unsigned urilen) const {
  65. for (unsigned index = 0; index < uris.size(); index++) {
  66. const std::string &handlerURI = uris[index];
  67. // first try for an exact match
  68. if (handlerURI == uri) {
  69. return handlers[index];
  70. }
  71. // next try for a partial match
  72. // we will accept uri/something
  73. if (handlerURI.length() < urilen
  74. && uri[handlerURI.length()] == '/'
  75. && handlerURI.compare(0, handlerURI.length(), uri, handlerURI.length()) == 0) {
  76. return handlers[index];
  77. }
  78. }
  79. return 0; // none found
  80. }
  81. void CivetServer::addHandler(const std::string &uri, CivetHandler *handler) {
  82. int index = getIndex(uri);
  83. if (index < 0) {
  84. uris.push_back(uri);
  85. handlers.push_back(handler);
  86. } else if (handlers[index] != handler) {
  87. delete handlers[index];
  88. handlers[index] = handler;
  89. }
  90. }
  91. void CivetServer::removeHandler(const std::string &uri) {
  92. int index = getIndex(uri);
  93. if (index >= 0) {
  94. uris.erase(uris.begin() + index, uris.begin() + index + 1);
  95. handlers.erase(handlers.begin() + index, handlers.begin() + index + 1);
  96. }
  97. }
  98. int CivetServer::getIndex(const std::string &uri) const {
  99. for (unsigned index = 0; index < uris.size(); index++) {
  100. if (uris[index].compare(uri) == 0)
  101. return index;
  102. }
  103. return -1;
  104. }
  105. void CivetServer::close() {
  106. if (context) {
  107. mg_stop (context);
  108. context = 0;
  109. }
  110. for (int i = handlers.size() - 1; i >= 0; i--) {
  111. delete handlers[i];
  112. }
  113. handlers.clear();
  114. uris.clear();
  115. }