From 8120bd373ceb50266242740e14863fc554650a17 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 16 Feb 2026 18:11:58 -0600 Subject: [PATCH 01/10] [http_request] Replace std::map/std::set/std::list with std::vector for response headers Replace heavy STL containers with simple std::vector and linear scan for response header collection. This eliminates red-black tree (_Rb_tree) and hash table template instantiations that are unnecessary for the small number of headers typically collected (1-5 elements). Changes: - response_headers_: std::map> -> std::vector
- collect_headers_: std::set -> std::vector - perform() signature: std::set -> std::vector - Add should_collect_header() inline helper for linear scan - Lowercase collect_headers at config/insertion time instead of per-request - IDF UserData now holds references to container's vector instead of owning a separate map that gets moved after the request - Reuse existing Header struct instead of std::pair Reduces stack usage in perform() and eliminates STL container overhead on memory-constrained ESP devices. --- .../components/http_request/http_request.cpp | 22 ++++------- .../components/http_request/http_request.h | 37 ++++++++++++------- .../http_request/http_request_arduino.cpp | 8 ++-- .../http_request/http_request_arduino.h | 2 +- .../http_request/http_request_host.cpp | 6 +-- .../http_request/http_request_host.h | 2 +- .../http_request/http_request_idf.cpp | 16 ++++---- .../http_request/http_request_idf.h | 7 +--- 8 files changed, 49 insertions(+), 51 deletions(-) diff --git a/esphome/components/http_request/http_request.cpp b/esphome/components/http_request/http_request.cpp index 11dde4715a..6590d2018e 100644 --- a/esphome/components/http_request/http_request.cpp +++ b/esphome/components/http_request/http_request.cpp @@ -22,23 +22,15 @@ void HttpRequestComponent::dump_config() { } std::string HttpContainer::get_response_header(const std::string &header_name) { - auto response_headers = this->get_response_headers(); - auto header_name_lower_case = str_lower_case(header_name); - if (response_headers.count(header_name_lower_case) == 0) { - ESP_LOGW(TAG, "No header with name %s found", header_name_lower_case.c_str()); - return ""; - } else { - auto values = response_headers[header_name_lower_case]; - if (values.empty()) { - ESP_LOGE(TAG, "header with name %s returned an empty list, this shouldn't happen", - header_name_lower_case.c_str()); - return ""; - } else { - auto header_value = values.front(); - ESP_LOGD(TAG, "Header with name %s found with value %s", header_name_lower_case.c_str(), header_value.c_str()); - return header_value; + auto lower = str_lower_case(header_name); + for (const auto &entry : this->response_headers_) { + if (entry.name == lower) { + ESP_LOGD(TAG, "Header with name %s found with value %s", lower.c_str(), entry.value.c_str()); + return entry.value; } } + ESP_LOGW(TAG, "No header with name %s found", lower.c_str()); + return ""; } } // namespace esphome::http_request diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index a427cc4a05..8175cc51d0 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -80,6 +80,15 @@ inline bool is_redirect(int const status) { */ inline bool is_success(int const status) { return status >= HTTP_STATUS_OK && status < HTTP_STATUS_MULTIPLE_CHOICES; } +/// Check if a header name should be collected (linear scan, fine for small lists) +inline bool should_collect_header(const std::vector &collect_headers, const std::string &header_name) { + for (const auto &h : collect_headers) { + if (h == header_name) + return true; + } + return false; +} + /* * HTTP Container Read Semantics * ============================= @@ -258,20 +267,13 @@ class HttpContainer : public Parented { return !this->is_chunked_ && this->bytes_read_ >= this->content_length; } - /** - * @brief Get response headers. - * - * @return The key is the lower case response header name, the value is the header value. - */ - std::map> get_response_headers() { return this->response_headers_; } - std::string get_response_header(const std::string &header_name); protected: size_t bytes_read_{0}; bool secure_{false}; bool is_chunked_{false}; ///< True if response uses chunked transfer encoding - std::map> response_headers_{}; + std::vector
response_headers_{}; }; /// Read data from HTTP container into buffer with timeout handling @@ -351,23 +353,30 @@ class HttpRequestComponent : public Component { std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers) { - return this->start(url, method, body, request_headers, {}); + return this->perform(url, method, body, request_headers, {}); } std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, const std::set &collect_headers) { - std::set lower_case_collect_headers; + std::vector lower_case_collect_headers; + lower_case_collect_headers.reserve(collect_headers.size()); for (const std::string &collect_header : collect_headers) { - lower_case_collect_headers.insert(str_lower_case(collect_header)); + lower_case_collect_headers.push_back(str_lower_case(collect_header)); } return this->perform(url, method, body, request_headers, lower_case_collect_headers); } + std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, + const std::list
&request_headers, + const std::vector &collect_headers) { + return this->perform(url, method, body, request_headers, collect_headers); + } + protected: virtual std::shared_ptr perform(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, - const std::set &collect_headers) = 0; + const std::vector &collect_headers) = 0; const char *useragent_{nullptr}; bool follow_redirects_{}; uint16_t redirect_limit_{}; @@ -389,7 +398,7 @@ template class HttpRequestSendAction : public Action { this->request_headers_.insert({key, value}); } - void add_collect_header(const char *value) { this->collect_headers_.insert(value); } + void add_collect_header(const char *value) { this->collect_headers_.push_back(str_lower_case(value)); } void add_json(const char *key, TemplatableValue value) { this->json_.insert({key, value}); } @@ -494,7 +503,7 @@ template class HttpRequestSendAction : public Action { void encode_json_func_(Ts... x, JsonObject root) { this->json_func_(x..., root); } HttpRequestComponent *parent_; std::map> request_headers_{}; - std::set collect_headers_{"content-type", "content-length"}; + std::vector collect_headers_{"content-type", "content-length"}; std::map> json_{}; std::function json_func_{nullptr}; #ifdef USE_HTTP_REQUEST_RESPONSE diff --git a/esphome/components/http_request/http_request_arduino.cpp b/esphome/components/http_request/http_request_arduino.cpp index e5b919e380..d651631ffb 100644 --- a/esphome/components/http_request/http_request_arduino.cpp +++ b/esphome/components/http_request/http_request_arduino.cpp @@ -27,7 +27,7 @@ static constexpr int ESP8266_SSL_ERR_OOM = -1000; std::shared_ptr HttpRequestArduino::perform(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, - const std::set &collect_headers) { + const std::vector &collect_headers) { if (!network::is_connected()) { this->status_momentary_error("failed", 1000); ESP_LOGW(TAG, "HTTP Request failed; Not connected to network"); @@ -160,14 +160,14 @@ std::shared_ptr HttpRequestArduino::perform(const std::string &ur // Still return the container, so it can be used to get the status code and error message } - container->response_headers_ = {}; + container->response_headers_.clear(); auto header_count = container->client_.headers(); for (int i = 0; i < header_count; i++) { const std::string header_name = str_lower_case(container->client_.headerName(i).c_str()); - if (collect_headers.count(header_name) > 0) { + if (should_collect_header(collect_headers, header_name)) { std::string header_value = container->client_.header(i).c_str(); ESP_LOGD(TAG, "Received response header, name: %s, value: %s", header_name.c_str(), header_value.c_str()); - container->response_headers_[header_name].push_back(header_value); + container->response_headers_.push_back({header_name, header_value}); } } diff --git a/esphome/components/http_request/http_request_arduino.h b/esphome/components/http_request/http_request_arduino.h index a1084b12d5..1dfe406107 100644 --- a/esphome/components/http_request/http_request_arduino.h +++ b/esphome/components/http_request/http_request_arduino.h @@ -50,7 +50,7 @@ class HttpRequestArduino : public HttpRequestComponent { protected: std::shared_ptr perform(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, - const std::set &collect_headers) override; + const std::vector &collect_headers) override; }; } // namespace esphome::http_request diff --git a/esphome/components/http_request/http_request_host.cpp b/esphome/components/http_request/http_request_host.cpp index b94570be12..36aa463bfa 100644 --- a/esphome/components/http_request/http_request_host.cpp +++ b/esphome/components/http_request/http_request_host.cpp @@ -19,7 +19,7 @@ static const char *const TAG = "http_request.host"; std::shared_ptr HttpRequestHost::perform(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, - const std::set &response_headers) { + const std::vector &response_headers) { if (!network::is_connected()) { this->status_momentary_error("failed", 1000); ESP_LOGW(TAG, "HTTP Request failed; Not connected to network"); @@ -116,8 +116,8 @@ std::shared_ptr HttpRequestHost::perform(const std::string &url, for (auto header : response.headers) { ESP_LOGD(TAG, "Header: %s: %s", header.first.c_str(), header.second.c_str()); auto lower_name = str_lower_case(header.first); - if (response_headers.find(lower_name) != response_headers.end()) { - container->response_headers_[lower_name].emplace_back(header.second); + if (should_collect_header(response_headers, lower_name)) { + container->response_headers_.push_back({lower_name, header.second}); } } container->duration_ms = millis() - start; diff --git a/esphome/components/http_request/http_request_host.h b/esphome/components/http_request/http_request_host.h index 32e149e6a3..b63da4daa7 100644 --- a/esphome/components/http_request/http_request_host.h +++ b/esphome/components/http_request/http_request_host.h @@ -20,7 +20,7 @@ class HttpRequestHost : public HttpRequestComponent { public: std::shared_ptr perform(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, - const std::set &response_headers) override; + const std::vector &response_headers) override; void set_ca_path(const char *ca_path) { this->ca_path_ = ca_path; } protected: diff --git a/esphome/components/http_request/http_request_idf.cpp b/esphome/components/http_request/http_request_idf.cpp index 486984a694..e02b950bc6 100644 --- a/esphome/components/http_request/http_request_idf.cpp +++ b/esphome/components/http_request/http_request_idf.cpp @@ -19,8 +19,8 @@ namespace esphome::http_request { static const char *const TAG = "http_request.idf"; struct UserData { - const std::set &collect_headers; - std::map> response_headers; + const std::vector &collect_headers; + std::vector
&response_headers; }; void HttpRequestIDF::dump_config() { @@ -38,10 +38,10 @@ esp_err_t HttpRequestIDF::http_event_handler(esp_http_client_event_t *evt) { switch (evt->event_id) { case HTTP_EVENT_ON_HEADER: { const std::string header_name = str_lower_case(evt->header_key); - if (user_data->collect_headers.count(header_name)) { + if (should_collect_header(user_data->collect_headers, header_name)) { const std::string header_value = evt->header_value; ESP_LOGD(TAG, "Received response header, name: %s, value: %s", header_name.c_str(), header_value.c_str()); - user_data->response_headers[header_name].push_back(header_value); + user_data->response_headers.push_back({header_name, header_value}); } break; } @@ -55,7 +55,7 @@ esp_err_t HttpRequestIDF::http_event_handler(esp_http_client_event_t *evt) { std::shared_ptr HttpRequestIDF::perform(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, - const std::set &collect_headers) { + const std::vector &collect_headers) { if (!network::is_connected()) { this->status_momentary_error("failed", 1000); ESP_LOGE(TAG, "HTTP Request failed; Not connected to network"); @@ -110,8 +110,6 @@ std::shared_ptr HttpRequestIDF::perform(const std::string &url, c watchdog::WatchdogManager wdm(this->get_watchdog_timeout()); config.event_handler = http_event_handler; - auto user_data = UserData{collect_headers, {}}; - config.user_data = static_cast(&user_data); esp_http_client_handle_t client = esp_http_client_init(&config); @@ -120,6 +118,9 @@ std::shared_ptr HttpRequestIDF::perform(const std::string &url, c container->set_secure(secure); + auto user_data = UserData{collect_headers, container->response_headers_}; + esp_http_client_set_user_data(client, static_cast(&user_data)); + for (const auto &header : request_headers) { esp_http_client_set_header(client, header.name.c_str(), header.value.c_str()); } @@ -164,7 +165,6 @@ std::shared_ptr HttpRequestIDF::perform(const std::string &url, c container->feed_wdt(); container->status_code = esp_http_client_get_status_code(client); container->feed_wdt(); - container->set_response_headers(user_data.response_headers); container->duration_ms = millis() - start; if (is_success(container->status_code)) { return container; diff --git a/esphome/components/http_request/http_request_idf.h b/esphome/components/http_request/http_request_idf.h index 2a130eae58..0271c0fc69 100644 --- a/esphome/components/http_request/http_request_idf.h +++ b/esphome/components/http_request/http_request_idf.h @@ -21,11 +21,8 @@ class HttpContainerIDF : public HttpContainer { /// @brief Feeds the watchdog timer if the executing task has one attached void feed_wdt(); - void set_response_headers(std::map> &response_headers) { - this->response_headers_ = std::move(response_headers); - } - protected: + friend class HttpRequestIDF; esp_http_client_handle_t client_; }; @@ -41,7 +38,7 @@ class HttpRequestIDF : public HttpRequestComponent { protected: std::shared_ptr perform(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, - const std::set &collect_headers) override; + const std::vector &collect_headers) override; // if zero ESP-IDF will use DEFAULT_HTTP_BUF_SIZE uint16_t buffer_size_rx_{}; uint16_t buffer_size_tx_{}; From 3043ba8d897dd6c8ebdf7b3cd7990868f40521f2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 16 Feb 2026 18:17:11 -0600 Subject: [PATCH 02/10] [http_request] Deprecate std::set overloads of start(), use std::vector for get()/post() - Change get()/post() collect_headers param from std::set to std::vector (initializer list callers like online_image work unchanged) - Add ESPDEPRECATED on start() std::set overload with clear message about the collect_headers parameter --- esphome/components/http_request/http_request.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index 8175cc51d0..cdf8cd910e 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -335,7 +335,7 @@ class HttpRequestComponent : public Component { return this->start(url, "GET", "", request_headers); } std::shared_ptr get(const std::string &url, const std::list
&request_headers, - const std::set &collect_headers) { + const std::vector &collect_headers) { return this->start(url, "GET", "", request_headers, collect_headers); } std::shared_ptr post(const std::string &url, const std::string &body) { @@ -347,7 +347,7 @@ class HttpRequestComponent : public Component { } std::shared_ptr post(const std::string &url, const std::string &body, const std::list
&request_headers, - const std::set &collect_headers) { + const std::vector &collect_headers) { return this->start(url, "POST", body, request_headers, collect_headers); } @@ -356,6 +356,9 @@ class HttpRequestComponent : public Component { return this->perform(url, method, body, request_headers, {}); } + // Remove before 2027.1.0 + ESPDEPRECATED("Pass collect_headers as std::vector instead of std::set. Removed in 2027.1.0.", + "2026.7.0") std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, const std::set &collect_headers) { From 5e7b4c1e6c30622e9681d111af5dc39daf727660 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 16 Feb 2026 18:17:53 -0600 Subject: [PATCH 03/10] [http_request] Add comment explaining why start() calls perform() directly The no-collect-headers start() overload calls perform() directly instead of the vector start() overload to avoid ambiguity with the deprecated std::set overload. --- esphome/components/http_request/http_request.h | 1 + 1 file changed, 1 insertion(+) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index cdf8cd910e..dacf691d38 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -353,6 +353,7 @@ class HttpRequestComponent : public Component { std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers) { + // Call perform() directly to avoid ambiguity with the std::set overload return this->perform(url, method, body, request_headers, {}); } From 7c36dfa1fcab4fd140093e34076ae5a0518bebea Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 16 Feb 2026 18:24:41 -0600 Subject: [PATCH 04/10] [http_request] Ensure start() vector overload lowercases collect_headers The vector overload of start() was passing collect_headers directly to perform() without lowercasing. This meant callers using get()/post() with mixed-case header names (e.g. {"ETag"}) would fail to match against the lowercased header names from the HTTP response. --- esphome/components/http_request/http_request.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index dacf691d38..06c87bb4ab 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -374,7 +374,12 @@ class HttpRequestComponent : public Component { std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, const std::vector &collect_headers) { - return this->perform(url, method, body, request_headers, collect_headers); + std::vector lower_case_collect_headers; + lower_case_collect_headers.reserve(collect_headers.size()); + for (const auto &header : collect_headers) { + lower_case_collect_headers.push_back(str_lower_case(header)); + } + return this->perform(url, method, body, request_headers, lower_case_collect_headers); } protected: From a55abd8e5f6d6577828493a15baf9d6dd6ea3b5f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 16 Feb 2026 18:26:12 -0600 Subject: [PATCH 05/10] [http_request] Deduplicate lowercasing in start() overloads Have the deprecated std::set overload forward to the vector overload which already handles lowercasing. --- esphome/components/http_request/http_request.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index 06c87bb4ab..d7b63122a3 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -363,12 +363,8 @@ class HttpRequestComponent : public Component { std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, const std::set &collect_headers) { - std::vector lower_case_collect_headers; - lower_case_collect_headers.reserve(collect_headers.size()); - for (const std::string &collect_header : collect_headers) { - lower_case_collect_headers.push_back(str_lower_case(collect_header)); - } - return this->perform(url, method, body, request_headers, lower_case_collect_headers); + return this->start(url, method, body, request_headers, + std::vector(collect_headers.begin(), collect_headers.end())); } std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, From d2037aef8dd93d3bb2e499117cb02563d6cb2295 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 16 Feb 2026 18:28:04 -0600 Subject: [PATCH 06/10] [http_request] Extract lowercase_headers helper to avoid double-copy Both start() overloads now use a shared lowercase_headers() template that does a single pass from any iterator range, avoiding the extra vector copy that the set overload was doing. --- .../components/http_request/http_request.h | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index d7b63122a3..afa3336f8e 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -89,6 +89,16 @@ inline bool should_collect_header(const std::vector &collect_header return false; } +/// Lowercase a range of strings into a vector +template inline std::vector lowercase_headers(Iter begin, Iter end) { + std::vector result; + result.reserve(std::distance(begin, end)); + for (auto it = begin; it != end; ++it) { + result.push_back(str_lower_case(*it)); + } + return result; +} + /* * HTTP Container Read Semantics * ============================= @@ -363,19 +373,15 @@ class HttpRequestComponent : public Component { std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, const std::set &collect_headers) { - return this->start(url, method, body, request_headers, - std::vector(collect_headers.begin(), collect_headers.end())); + return this->perform(url, method, body, request_headers, + lowercase_headers(collect_headers.begin(), collect_headers.end())); } std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, const std::vector &collect_headers) { - std::vector lower_case_collect_headers; - lower_case_collect_headers.reserve(collect_headers.size()); - for (const auto &header : collect_headers) { - lower_case_collect_headers.push_back(str_lower_case(header)); - } - return this->perform(url, method, body, request_headers, lower_case_collect_headers); + return this->perform(url, method, body, request_headers, + lowercase_headers(collect_headers.begin(), collect_headers.end())); } protected: From f43ef21c69f9509cafcd9ea0e0f4cab522726c1b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 16 Feb 2026 18:34:41 -0600 Subject: [PATCH 07/10] [http_request] Remove redundant lowercasing from add_collect_header start() already lowercases all collect_headers via lowercase_headers(), so pre-lowercasing at insertion time was redundant double work on every request. --- esphome/components/http_request/http_request.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index afa3336f8e..b44f449e30 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -409,7 +409,7 @@ template class HttpRequestSendAction : public Action { this->request_headers_.insert({key, value}); } - void add_collect_header(const char *value) { this->collect_headers_.push_back(str_lower_case(value)); } + void add_collect_header(const char *value) { this->collect_headers_.push_back(value); } void add_json(const char *key, TemplatableValue value) { this->json_.insert({key, value}); } From 7726d0aac9846cf40b21695dbf6060f45ac4e206 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 16 Feb 2026 18:37:08 -0600 Subject: [PATCH 08/10] [http_request] Rename should_collect_header param to lower_header_name Makes it clear the caller must pass an already-lowercased header name. --- esphome/components/http_request/http_request.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index b44f449e30..3046c8a749 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -81,9 +81,10 @@ inline bool is_redirect(int const status) { inline bool is_success(int const status) { return status >= HTTP_STATUS_OK && status < HTTP_STATUS_MULTIPLE_CHOICES; } /// Check if a header name should be collected (linear scan, fine for small lists) -inline bool should_collect_header(const std::vector &collect_headers, const std::string &header_name) { +inline bool should_collect_header(const std::vector &collect_headers, + const std::string &lower_header_name) { for (const auto &h : collect_headers) { - if (h == header_name) + if (h == lower_header_name) return true; } return false; From 2fa6c15fc1de6a7d2076da493b2239d56370df39 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 16 Feb 2026 18:38:31 -0600 Subject: [PATCH 09/10] [http_request] Remove unnecessary lowercase_headers template helper The template only existed to share a loop between set and vector iterators. Instead, have the deprecated set overload forward to the vector overload, and inline the loop there. --- .../components/http_request/http_request.h | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index 3046c8a749..5402155393 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -90,16 +90,6 @@ inline bool should_collect_header(const std::vector &collect_header return false; } -/// Lowercase a range of strings into a vector -template inline std::vector lowercase_headers(Iter begin, Iter end) { - std::vector result; - result.reserve(std::distance(begin, end)); - for (auto it = begin; it != end; ++it) { - result.push_back(str_lower_case(*it)); - } - return result; -} - /* * HTTP Container Read Semantics * ============================= @@ -374,15 +364,19 @@ class HttpRequestComponent : public Component { std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, const std::set &collect_headers) { - return this->perform(url, method, body, request_headers, - lowercase_headers(collect_headers.begin(), collect_headers.end())); + return this->start(url, method, body, request_headers, + std::vector(collect_headers.begin(), collect_headers.end())); } std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, const std::vector &collect_headers) { - return this->perform(url, method, body, request_headers, - lowercase_headers(collect_headers.begin(), collect_headers.end())); + std::vector lower; + lower.reserve(collect_headers.size()); + for (const auto &h : collect_headers) { + lower.push_back(str_lower_case(h)); + } + return this->perform(url, method, body, request_headers, lower); } protected: From aa3ac552c8156f9b2014c852205b8b13d8ef1575 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 16 Feb 2026 18:48:32 -0600 Subject: [PATCH 10/10] [http_request] Restore descriptive variable name in start() --- esphome/components/http_request/http_request.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index 5402155393..cbf6273b51 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -371,12 +371,12 @@ class HttpRequestComponent : public Component { std::shared_ptr start(const std::string &url, const std::string &method, const std::string &body, const std::list
&request_headers, const std::vector &collect_headers) { - std::vector lower; - lower.reserve(collect_headers.size()); - for (const auto &h : collect_headers) { - lower.push_back(str_lower_case(h)); + std::vector lower_case_collect_headers; + lower_case_collect_headers.reserve(collect_headers.size()); + for (const auto &header : collect_headers) { + lower_case_collect_headers.push_back(str_lower_case(header)); } - return this->perform(url, method, body, request_headers, lower); + return this->perform(url, method, body, request_headers, lower_case_collect_headers); } protected: