BellHTTPServer.h 2.8 KB

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