1
0

HttpService.cpp 3.9 KB

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