1
0

HttpService.cpp 4.6 KB

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