#ifndef BELL_HTTP_SERVER_H #define BELL_HTTP_SERVER_H #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #include #include "win32shim.h" #else #include #include #include #include #endif #include #include #include #include #include #include #include #include "BaseHTTPServer.h" #ifndef SOCK_NONBLOCK #define SOCK_NONBLOCK O_NONBLOCK #endif namespace bell { class HTTPServer : public bell::BaseHTTPServer { private: std::regex routerPattern = std::regex(":([^\\/]+)?"); fd_set master; fd_set readFds; fd_set activeFdSet, readFdSet; bool isClosed = true; bool writingResponse = false; std::map> routes; std::map connections; void writeResponse(const HTTPResponse &); void writeResponseEvents(int connFd); void findAndHandleRoute(HTTPConnection& connection); std::vector splitUrl(const std::string &url, char delimiter); std::mutex responseMutex; std::vector responseBuffer = std::vector(128); void redirectCaptivePortal(int connectionFd); void readFromClient(int clientFd); std::map parseQueryString(const std::string &queryString); unsigned char h2int(char c); std::string urlDecode(std::string str); public: HTTPServer(int serverPort); void registerHandler(RequestType requestType, const std::string &, httpHandler, bool readDataToStr = false); void respond(const HTTPResponse &); void redirectTo(const std::string&, int connectionFd); void publishEvent(std::string eventName, std::string eventData); void closeConnection(int connection); void listen(); }; } #endif