#ifndef HTTPSERVER_HPP #define HTTPSERVER_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace pmc { namespace net { namespace beast = boost::beast; namespace http = beast::http; namespace websocket = beast::websocket; namespace asio = boost::asio; using tcp = boost::asio::ip::tcp; using HttpRequestHandler = std::function( const http::request&, const std::unordered_map&)>; using MiddlewareHandler = std::function&, http::response&, const std::unordered_map&)>; // WebSocket 回调类型 using WebSocketMessageHandler = std::function sendCallback)>; using WebSocketConnectHandler = std::function; using WebSocketDisconnectHandler = std::function; // WebSocket 代理:握手回调接收 HTTP upgrade 请求,返回目标 ws:// 或 wss:// URL // 返回空字符串表示拒绝(返回 403) using WsProxyHandshakeHandler = std::function& upgradeReq)>; struct RouteEntry { std::string path; std::regex pattern; HttpRequestHandler handler; bool is_wildcard; }; struct WsRouteEntry { std::string path; WebSocketMessageHandler handler; }; struct WsProxyRouteEntry { std::string path; WsProxyHandshakeHandler handshake; }; class HttpServer { public: explicit HttpServer(const std::string& address, unsigned short port, unsigned int threads = 1); explicit HttpServer(const std::string& address, unsigned short port, const std::string& cert_file, const std::string& key_file, unsigned int threads = 1); ~HttpServer(); void start(); void stop(); void get(const std::string& path, HttpRequestHandler handler); void post(const std::string& path, HttpRequestHandler handler); void put(const std::string& path, HttpRequestHandler handler); void del(const std::string& path, HttpRequestHandler handler); void options(const std::string& path, HttpRequestHandler handler); void use(MiddlewareHandler middleware); void setStaticDirectory(const std::string& path); // WebSocket 接口 void ws(const std::string& path, WebSocketMessageHandler handler); void ws_proxy(const std::string& path, WsProxyHandshakeHandler handshake); void onWsConnect(WebSocketConnectHandler handler); void onWsDisconnect(WebSocketDisconnectHandler handler); bool sendToWsClient(const std::string& clientId, const std::string& message); size_t broadcastWs(const std::string& message); void disconnectWsClient(const std::string& clientId); size_t getWsClientCount() const; bool isRunning() const; unsigned short getPort() const; std::string getAddress() const; bool isSSLEnabled() const; void run(); void showStatus() const; void setPrivateKeyPassword(const std::string& password); class debug { public: static void print_all_header_fields(const http::request& req); }; private: class Session; class Listener; std::string address_; unsigned short port_; unsigned int threads_; std::atomic running_{false}; bool ssl_enabled_{false}; std::string cert_file_; std::string key_file_; std::string private_key_password_; std::unique_ptr ssl_ctx_; std::unique_ptr ioc_; std::shared_ptr listener_; std::vector worker_threads_; std::vector get_handlers_; std::vector post_handlers_; std::vector put_handlers_; std::vector delete_handlers_; std::vector options_handlers_; std::vector middlewares_; std::string static_directory_; // WebSocket 路由和处理 std::vector ws_handlers_; std::vector ws_proxy_handlers_; WebSocketConnectHandler ws_connect_handler_; WebSocketDisconnectHandler ws_disconnect_handler_; std::unordered_map> ws_clients_; mutable std::mutex ws_clients_mutex_; std::atomic ws_client_counter_{0}; std::vector> sessions_; std::mutex sessions_mutex_; std::unordered_map parseQueryParams(const std::string& query); std::regex wildcardToRegex(const std::string& pattern); bool matchPath(const std::string& path, const std::regex& pattern); http::response handleRequest(const http::request& req); HttpRequestHandler findRoute(const std::string& method, const std::string& path); bool routeExists(const std::string& method, const std::string& path); WebSocketMessageHandler findWsRoute(const std::string& path); WsProxyHandshakeHandler findWsProxyRoute(const std::string& path); // WebSocket 客户端管理 std::string generateWsClientId(); void addWsClient(const std::string& clientId, std::shared_ptr session); void removeWsClient(const std::string& clientId); std::shared_ptr getWsClient(const std::string& clientId); void addSession(const std::shared_ptr& session); void removeSession(const Session* session); void closeAllSessions(); void initSSLContext(); friend class Session; }; } // namespace net } // namespace pmc #endif // HTTPSERVER_HPP