#include "web_server_handler.h" #include "esp_log.h" #include #include #include #include static const char* TAG = "WebServerHandler"; WebServerHandler::WebServerHandler() { } WebServerHandler::~WebServerHandler() { stop(); } uint16_t WebServerHandler::start(const std::string& auth_key, uint16_t base_port) { if (server_ != nullptr) { ESP_LOGW(TAG, "Server already running on port %d", current_port_); return current_port_; } auth_key_ = auth_key; // Try to find a free port uint16_t port = base_port; const uint16_t max_attempts = 100; for (uint16_t attempt = 0; attempt < max_attempts; attempt++) { httpd_config_t config = HTTPD_DEFAULT_CONFIG(); config.server_port = port; config.ctrl_port = port + 1000; // Control port config.max_open_sockets = 7; config.lru_purge_enable = true; esp_err_t err = httpd_start(&server_, &config); if (err == ESP_OK) { current_port_ = port; ESP_LOGI(TAG, "Web server started successfully on port %d", current_port_); return current_port_; } else if (err == ESP_ERR_HTTPD_ALLOC_MEM) { ESP_LOGE(TAG, "Failed to allocate memory for web server"); return 0; } else { // Port likely in use, try next port ESP_LOGD(TAG, "Port %d in use, trying next port", port); port++; } } ESP_LOGE(TAG, "Failed to find free port after %d attempts", max_attempts); return 0; } esp_err_t WebServerHandler::stop() { if (server_ == nullptr) { return ESP_OK; } esp_err_t err = httpd_stop(server_); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to stop web server: %s", esp_err_to_name(err)); return err; } server_ = nullptr; current_port_ = 0; auth_key_.clear(); ESP_LOGI(TAG, "Web server stopped"); return ESP_OK; } esp_err_t WebServerHandler::register_uri_handler(const httpd_uri_t* uri_handler) { if (server_ == nullptr) { ESP_LOGE(TAG, "Server not running, cannot register URI handler"); return ESP_ERR_INVALID_STATE; } esp_err_t err = httpd_register_uri_handler(server_, uri_handler); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to register URI handler: %s", esp_err_to_name(err)); return err; } return ESP_OK; } bool WebServerHandler::validate_auth(const char* query_string) const { if (!query_string || auth_key_.empty()) { return false; } // Look for "auth=" in query string const char* auth_param = strstr(query_string, "auth="); if (!auth_param) { return false; } // Skip "auth=" auth_param += 5; // Find end of auth value (& or end of string) const char* end = strchr(auth_param, '&'); size_t auth_len = end ? (size_t)(end - auth_param) : strlen(auth_param); // Compare with stored auth key if (auth_len != auth_key_.length()) { return false; } return strncmp(auth_param, auth_key_.c_str(), auth_len) == 0; }