BellHTTPServer.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. enum class WSState { CONNECTED, READY, CLOSED };
  20. struct HTTPResponse {
  21. uint8_t* body;
  22. size_t bodySize;
  23. std::map<std::string, std::string> headers;
  24. int status;
  25. HTTPResponse() {
  26. body = nullptr;
  27. bodySize = 0;
  28. status = 200;
  29. }
  30. ~HTTPResponse() {
  31. if (body != nullptr) {
  32. free(body);
  33. body = nullptr;
  34. }
  35. }
  36. };
  37. typedef std::function<std::unique_ptr<HTTPResponse>(
  38. struct mg_connection* conn)>
  39. HTTPHandler;
  40. typedef std::function<void(struct mg_connection* conn, WSState)>
  41. WSStateHandler;
  42. typedef std::function<void(struct mg_connection* conn, char*, size_t)>
  43. WSDataHandler;
  44. class Router {
  45. public:
  46. struct RouterNode {
  47. std::unordered_map<std::string, std::unique_ptr<RouterNode>> children;
  48. HTTPHandler value = nullptr;
  49. std::string paramName = "";
  50. bool isParam = false;
  51. bool isCatchAll = false;
  52. };
  53. RouterNode root = RouterNode();
  54. typedef std::unordered_map<std::string, std::string> Params;
  55. typedef std::pair<HTTPHandler, Params> HandlerAndParams;
  56. std::vector<std::string> split(const std::string str,
  57. const std::string regex_str);
  58. void insert(const std::string& route, HTTPHandler& value);
  59. HandlerAndParams find(const std::string& route);
  60. };
  61. std::vector<int> getListeningPorts() { return server->getListeningPorts(); };
  62. void close() { server->close(); }
  63. std::unique_ptr<HTTPResponse> makeJsonResponse(const std::string& json,
  64. int status = 200);
  65. std::unique_ptr<HTTPResponse> makeEmptyResponse();
  66. void registerNotFound(HTTPHandler handler);
  67. void registerGet(const std::string&, HTTPHandler handler);
  68. void registerPost(const std::string&, HTTPHandler handler);
  69. void registerWS(const std::string&, WSDataHandler dataHandler,
  70. WSStateHandler stateHandler);
  71. static std::unordered_map<std::string, std::string> extractParams(
  72. struct mg_connection* conn);
  73. private:
  74. std::unique_ptr<CivetServer> server;
  75. std::vector<std::string> civetWebOptions;
  76. int serverPort = 8080;
  77. Router getRequestsRouter;
  78. Router postRequestsRouter;
  79. std::mutex responseMutex;
  80. HTTPHandler notFoundHandler;
  81. bool handleGet(CivetServer* server, struct mg_connection* conn);
  82. bool handlePost(CivetServer* server, struct mg_connection* conn);
  83. };
  84. } // namespace bell