#include "network/http_handler.h" #include "esp_http_client.h" #include "esp_log.h" #include "string.h" #include #include esp_err_t http_event_handler(esp_http_client_event_t *evt) { HttpHandler* handler = static_cast(evt->user_data); switch (evt->event_id) { case HTTP_EVENT_ON_DATA: if (handler && evt->data_len > 0) { // Pre-allocate with some extra capacity to reduce reallocations size_t new_capacity = handler->response_size + evt->data_len + 1; // Double capacity if we already have data, to amortize reallocation cost if (handler->response_size > 0) { new_capacity = std::max(new_capacity, (handler->response_size * 2) + 1); new_capacity = std::min(new_capacity, (size_t)65536); // Cap at 64KB } char* new_buffer = new char[new_capacity]; if (handler->response_buffer && handler->response_size > 0) { memcpy(new_buffer, handler->response_buffer, handler->response_size); delete[] handler->response_buffer; } memcpy(new_buffer + handler->response_size, evt->data, evt->data_len); handler->response_size += evt->data_len; new_buffer[handler->response_size] = '\0'; handler->response_buffer = new_buffer; handler->response_capacity = new_capacity; } break; default: break; } return ESP_OK; } HttpHandler::HttpHandler(const esp_http_client_config_t&& config, WifiHandler* wifiHandler) : wifiHandler(wifiHandler), response_buffer(nullptr), response_size(0) { esp_http_client_config_t modified_config = config; modified_config.event_handler = http_event_handler; modified_config.user_data = this; this->client = esp_http_client_init(&modified_config); } HttpHandler::~HttpHandler() { if (this->client) { esp_http_client_cleanup(this->client); } if (response_buffer) { delete[] response_buffer; } } esp_err_t HttpHandler::set_method(esp_http_client_method_t method) { return esp_http_client_set_method(this->client, method); } esp_err_t HttpHandler::set_header(const char* header, const char* value) { return esp_http_client_set_header(this->client, header, value); } esp_err_t HttpHandler::set_post_field(const char* field, size_t len) { return esp_http_client_set_post_field(this->client, field, len); } esp_err_t HttpHandler::perform_request() { return esp_http_client_perform(this->client); } void HttpHandler::get_body( char*& buffer, int& total_len ) { total_len = response_size; if (response_buffer && response_size > 0) { buffer = new char[response_size + 1]; memcpy(buffer, response_buffer, response_size); buffer[response_size] = '\0'; } else { buffer = nullptr; total_len = 0; } }