114 lines
2.9 KiB
C++
114 lines
2.9 KiB
C++
#include "web_server_handler.h"
|
|
#include "esp_log.h"
|
|
#include <cstring>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <unistd.h>
|
|
|
|
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=<key>" 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;
|
|
}
|