BellHTTPServer.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #pragma once
  2. #include <BellLogger.h> // for bell
  3. #include <stdint.h> // for uint8_t
  4. #include <stdlib.h> // for free, size_t
  5. #include <functional> // for function
  6. #include <map> // for map
  7. #include <memory> // for unique_ptr
  8. #include <mutex> // for mutex
  9. #include <string> // for string, hash, operator==, operator<
  10. #include <unordered_map> // for unordered_map
  11. #include <utility> // for pair
  12. #include <vector> // for vector
  13. #include "CivetServer.h" // for CivetServer, CivetHandler
  14. using namespace bell;
  15. namespace bell {
  16. class BellHTTPServer : public CivetHandler {
  17. public:
  18. BellHTTPServer(int serverPort);
  19. ~BellHTTPServer();
  20. enum class WSState { CONNECTED, READY, CLOSED };
  21. struct HTTPResponse {
  22. uint8_t* body;
  23. size_t bodySize;
  24. std::map<std::string, std::string> headers;
  25. int status;
  26. HTTPResponse() {
  27. body = nullptr;
  28. bodySize = 0;
  29. status = 200;
  30. }
  31. ~HTTPResponse() {
  32. if (body != nullptr) {
  33. free(body);
  34. body = nullptr;
  35. }
  36. }
  37. };
  38. typedef std::function<std::unique_ptr<HTTPResponse>(
  39. struct mg_connection* conn)>
  40. HTTPHandler;
  41. typedef std::function<void(struct mg_connection* conn, WSState)>
  42. WSStateHandler;
  43. typedef std::function<void(struct mg_connection* conn, char*, size_t)>
  44. WSDataHandler;
  45. class Router {
  46. public:
  47. struct RouterNode {
  48. std::unordered_map<std::string, std::unique_ptr<RouterNode>> children;
  49. HTTPHandler value = nullptr;
  50. std::string paramName = "";
  51. bool isParam = false;
  52. bool isCatchAll = false;
  53. };
  54. RouterNode root = RouterNode();
  55. typedef std::unordered_map<std::string, std::string> Params;
  56. typedef std::pair<HTTPHandler, Params> HandlerAndParams;
  57. std::vector<std::string> split(const std::string str,
  58. const std::string regex_str);
  59. void insert(const std::string& route, HTTPHandler& value);
  60. HandlerAndParams find(const std::string& route);
  61. };
  62. std::vector<int> getListeningPorts() { return server->getListeningPorts(); };
  63. void close() { server->close(); }
  64. std::unique_ptr<HTTPResponse> makeJsonResponse(const std::string& json,
  65. int status = 200);
  66. std::unique_ptr<HTTPResponse> makeEmptyResponse();
  67. void registerNotFound(HTTPHandler handler);
  68. void registerGet(const std::string&, HTTPHandler handler);
  69. void registerPost(const std::string&, HTTPHandler handler);
  70. void registerWS(const std::string&, WSDataHandler dataHandler,
  71. WSStateHandler stateHandler);
  72. static std::unordered_map<std::string, std::string> extractParams(
  73. struct mg_connection* conn);
  74. private:
  75. std::unique_ptr<CivetServer> server;
  76. std::vector<std::string> civetWebOptions;
  77. int serverPort = 8080;
  78. Router getRequestsRouter;
  79. Router postRequestsRouter;
  80. std::mutex responseMutex;
  81. HTTPHandler notFoundHandler;
  82. static std::mutex initMutex;
  83. bool handleGet(CivetServer* server, struct mg_connection* conn);
  84. bool handlePost(CivetServer* server, struct mg_connection* conn);
  85. };
  86. } // namespace bell