From c397f143065e5353500eaaeb8bc103406d6ebe4b Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Mon, 15 Nov 2021 11:44:17 +0100 Subject: [PATCH] Implemented max response size limit --- src/asynchttprequest.cpp | 33 ++++++++++++++++++++++++--------- src/asynchttprequest.h | 7 ++++++- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/asynchttprequest.cpp b/src/asynchttprequest.cpp index 322b6ae..e10136a 100644 --- a/src/asynchttprequest.cpp +++ b/src/asynchttprequest.cpp @@ -8,6 +8,7 @@ #include #include #include +#include // esp-idf includes #include @@ -132,7 +133,7 @@ tl::expected AsyncHttpRequest::createClient(std::string_view esp_http_client_config_t config{}; config.url = url.data(); - config.event_handler = httpEventHandler; + config.event_handler = staticHttpEventHandler; config.user_data = this; m_client = espcpputils::http_client{&config}; @@ -244,11 +245,8 @@ void AsyncHttpRequest::clearFinished() esp_err_t AsyncHttpRequest::httpEventHandler(esp_http_client_event_t *evt) { - auto _this = reinterpret_cast(evt->user_data); - - assert(_this); - - switch(evt->event_id) { + switch(evt->event_id) + { case HTTP_EVENT_ON_HEADER: if (evt->header_key && evt->header_value) { @@ -258,7 +256,7 @@ esp_err_t AsyncHttpRequest::httpEventHandler(esp_http_client_event_t *evt) if (std::sscanf(evt->header_value, "%u", &size) == 1) { //ESP_LOGD(TAG, "reserving %u bytes for http buffer", size); - _this->m_buf.reserve(size); + m_buf.reserve(std::min(size, m_sizeLimit)); } else { @@ -272,16 +270,33 @@ esp_err_t AsyncHttpRequest::httpEventHandler(esp_http_client_event_t *evt) ESP_LOGW(TAG, "handler with invalid data ptr"); else if (evt->data_len <= 0) ESP_LOGW(TAG, "handler with invalid data_len %i", evt->data_len); + else if (m_buf.size() >= m_sizeLimit) + return ESP_ERR_NO_MEM; else - _this->m_buf += std::string_view((const char *)evt->data, evt->data_len); + { + const auto remainingSize = m_sizeLimit - m_buf.size(); + m_buf += std::string_view((const char *)evt->data, std::min(evt->data_len, remainingSize)); + if (remainingSize < evt->data_len) + return ESP_ERR_NO_MEM; + } break; - default:; + default: + ; } return ESP_OK; } +esp_err_t AsyncHttpRequest::staticHttpEventHandler(esp_http_client_event_t *evt) +{ + auto _this = reinterpret_cast(evt->user_data); + + assert(_this); + + return _this->httpEventHandler(evt); +} + void AsyncHttpRequest::requestTask(void *ptr) { auto _this = reinterpret_cast(ptr); diff --git a/src/asynchttprequest.h b/src/asynchttprequest.h index 25c24fb..b18c668 100644 --- a/src/asynchttprequest.h +++ b/src/asynchttprequest.h @@ -43,8 +43,12 @@ public: const std::string &buffer() const { return m_buf; } std::string &&takeBuffer() { return std::move(m_buf); } + std::size_t sizeLimit() const { return m_sizeLimit; } + void setSizeLimit(std::size_t sizeLimit) { m_sizeLimit = sizeLimit; } + private: - static esp_err_t httpEventHandler(esp_http_client_event_t *evt); + esp_err_t httpEventHandler(esp_http_client_event_t *evt); + static esp_err_t staticHttpEventHandler(esp_http_client_event_t *evt); static void requestTask(void *ptr); void requestTask(); @@ -54,6 +58,7 @@ private: espcpputils::event_group m_eventGroup; esp_err_t m_result{}; int m_statusCode{}; + std::size_t m_sizeLimit{4096}; const char * const m_taskName; const espcpputils::CoreAffinity m_coreAffinity;