#pragma once #include // for bell #include // for uint8_t #include // for free, size_t #include // for function #include // for map #include // for unique_ptr #include // for mutex #include // for string, hash, operator==, operator< #include // for unordered_map #include // for pair #include // for vector #include "CivetServer.h" // for CivetServer, CivetHandler using namespace bell; namespace bell { class BellHTTPServer : public CivetHandler { public: BellHTTPServer(int serverPort); enum class WSState { CONNECTED, READY, CLOSED }; struct HTTPResponse { uint8_t* body; size_t bodySize; std::map headers; int status; HTTPResponse() { body = nullptr; bodySize = 0; status = 200; } ~HTTPResponse() { if (body != nullptr) { free(body); body = nullptr; } } }; typedef std::function( struct mg_connection* conn)> HTTPHandler; typedef std::function WSStateHandler; typedef std::function WSDataHandler; class Router { public: struct RouterNode { std::unordered_map> children; HTTPHandler value = nullptr; std::string paramName = ""; bool isParam = false; bool isCatchAll = false; }; RouterNode root = RouterNode(); typedef std::unordered_map Params; typedef std::pair HandlerAndParams; std::vector split(const std::string str, const std::string regex_str); void insert(const std::string& route, HTTPHandler& value); HandlerAndParams find(const std::string& route); }; std::vector getListeningPorts() { return server->getListeningPorts(); }; void close() { server->close(); } std::unique_ptr makeJsonResponse(const std::string& json, int status = 200); std::unique_ptr makeEmptyResponse(); void registerNotFound(HTTPHandler handler); void registerGet(const std::string&, HTTPHandler handler); void registerPost(const std::string&, HTTPHandler handler); void registerWS(const std::string&, WSDataHandler dataHandler, WSStateHandler stateHandler); static std::unordered_map extractParams( struct mg_connection* conn); private: std::unique_ptr server; int serverPort = 8080; Router getRequestsRouter; Router postRequestsRouter; std::mutex responseMutex; HTTPHandler notFoundHandler; bool handleGet(CivetServer* server, struct mg_connection* conn); bool handlePost(CivetServer* server, struct mg_connection* conn); }; } // namespace bell