1
0

HttpService.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include "HttpService.h"
  2. #include "hbase.h" // import strendswith
  3. namespace hv {
  4. void HttpService::AddApi(const char* path, http_method method, http_sync_handler sync_handler, http_async_handler async_handler, http_handler handler) {
  5. std::shared_ptr<http_method_handlers> method_handlers = NULL;
  6. auto iter = api_handlers.find(path);
  7. if (iter == api_handlers.end()) {
  8. // add path
  9. method_handlers = std::shared_ptr<http_method_handlers>(new http_method_handlers);
  10. api_handlers[path] = method_handlers;
  11. }
  12. else {
  13. method_handlers = iter->second;
  14. }
  15. for (auto iter = method_handlers->begin(); iter != method_handlers->end(); ++iter) {
  16. if (iter->method == method) {
  17. // update
  18. iter->sync_handler = sync_handler;
  19. iter->async_handler = async_handler;
  20. iter->handler = handler;
  21. return;
  22. }
  23. }
  24. // add
  25. method_handlers->push_back(http_method_handler(method, sync_handler, async_handler, handler));
  26. }
  27. int HttpService::GetApi(const char* url, http_method method, http_sync_handler* sync_handler, http_async_handler* async_handler, http_handler* handler) {
  28. // {base_url}/path?query
  29. const char* s = url;
  30. const char* b = base_url.c_str();
  31. while (*s && *b && *s == *b) {++s;++b;}
  32. if (*b != '\0') {
  33. return HTTP_STATUS_NOT_FOUND;
  34. }
  35. const char* e = s;
  36. while (*e && *e != '?') ++e;
  37. std::string path = std::string(s, e);
  38. auto iter = api_handlers.find(path);
  39. if (iter == api_handlers.end()) {
  40. if (sync_handler) *sync_handler = NULL;
  41. if (async_handler) *async_handler = NULL;
  42. if (handler) *handler = NULL;
  43. return HTTP_STATUS_NOT_FOUND;
  44. }
  45. auto method_handlers = iter->second;
  46. for (auto iter = method_handlers->begin(); iter != method_handlers->end(); ++iter) {
  47. if (iter->method == method) {
  48. if (sync_handler) *sync_handler = iter->sync_handler;
  49. if (async_handler) *async_handler = iter->async_handler;
  50. if (handler) *handler = iter->handler;
  51. return 0;
  52. }
  53. }
  54. if (handler) *handler = NULL;
  55. if (async_handler) *async_handler = NULL;
  56. return HTTP_STATUS_METHOD_NOT_ALLOWED;
  57. }
  58. int HttpService::GetApi(HttpRequest* req, http_sync_handler* sync_handler, http_async_handler* async_handler, http_handler* handler) {
  59. // {base_url}/path?query
  60. const char* s = req->path.c_str();
  61. const char* b = base_url.c_str();
  62. while (*s && *b && *s == *b) {++s;++b;}
  63. if (*b != '\0') {
  64. return HTTP_STATUS_NOT_FOUND;
  65. }
  66. const char* e = s;
  67. while (*e && *e != '?') ++e;
  68. std::string path = std::string(s, e);
  69. const char *kp, *ks, *vp, *vs;
  70. bool match;
  71. for (auto iter = api_handlers.begin(); iter != api_handlers.end(); ++iter) {
  72. kp = iter->first.c_str();
  73. vp = path.c_str();
  74. match = false;
  75. std::map<std::string, std::string> params;
  76. while (*kp && *vp) {
  77. if (kp[0] == '*') {
  78. // wildcard *
  79. match = strendswith(vp, kp+1);
  80. break;
  81. } else if (*kp != *vp) {
  82. match = false;
  83. break;
  84. } else if (kp[0] == '/' && (kp[1] == ':' || kp[1] == '{')) {
  85. // RESTful /:field/
  86. // RESTful /{field}/
  87. kp += 2;
  88. ks = kp;
  89. while (*kp && *kp != '/') {++kp;}
  90. vp += 1;
  91. vs = vp;
  92. while (*vp && *vp != '/') {++vp;}
  93. int klen = kp - ks;
  94. if (*(ks-1) == '{' && *(kp-1) == '}') {
  95. --klen;
  96. }
  97. params[std::string(ks, klen)] = std::string(vs, vp-vs);
  98. continue;
  99. } else {
  100. ++kp;
  101. ++vp;
  102. }
  103. }
  104. match = match ? match : (*kp == '\0' && *vp == '\0');
  105. if (match) {
  106. auto method_handlers = iter->second;
  107. for (auto iter = method_handlers->begin(); iter != method_handlers->end(); ++iter) {
  108. if (iter->method == req->method) {
  109. for (auto& param : params) {
  110. // RESTful /:field/ => req->query_params[field]
  111. req->query_params[param.first] = param.second;
  112. }
  113. if (sync_handler) *sync_handler = iter->sync_handler;
  114. if (async_handler) *async_handler = iter->async_handler;
  115. if (handler) *handler = iter->handler;
  116. return 0;
  117. }
  118. }
  119. if (params.size() == 0) {
  120. if (sync_handler) *sync_handler = NULL;
  121. if (async_handler) *async_handler = NULL;
  122. if (handler) *handler = NULL;
  123. return HTTP_STATUS_METHOD_NOT_ALLOWED;
  124. }
  125. }
  126. }
  127. if (sync_handler) *sync_handler = NULL;
  128. if (async_handler) *async_handler = NULL;
  129. if (handler) *handler = NULL;
  130. return HTTP_STATUS_NOT_FOUND;
  131. }
  132. }