From 2348ad2a03ce51776fe509eda0d0ebf8577189cb Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 11 Feb 2026 19:05:52 -0600 Subject: [PATCH 1/2] Access URL query string directly from req->uri instead of stack copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The query string already lives in req->uri. Access it via strchr('?') instead of copying into a 513-byte stack buffer via httpd_req_get_url_query_str. This is the same pattern url_to() uses — http_parser identifies URI components by offset/length without modifying the source string. Eliminates 513 bytes of stack usage on the httpd task, leaving only the 128-byte value extraction buffer in query_key_value. --- .../web_server_idf/web_server_idf.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/esphome/components/web_server_idf/web_server_idf.cpp b/esphome/components/web_server_idf/web_server_idf.cpp index f4ac94d1225..c335a47023e 100644 --- a/esphome/components/web_server_idf/web_server_idf.cpp +++ b/esphome/components/web_server_idf/web_server_idf.cpp @@ -408,6 +408,7 @@ AsyncWebParameter *AsyncWebServerRequest::getParam(const char *name) { /// Search post_query then URL query with a callback. /// Returns first truthy result, or value-initialized default. +/// URL query is accessed directly from req->uri (same pattern as url_to()). template static auto search_query_sources(httpd_req_t *req, const std::string &post_query, const char *name, Func func) -> decltype(func(nullptr, size_t{0}, name)) { @@ -417,15 +418,19 @@ static auto search_query_sources(httpd_req_t *req, const std::string &post_query return result; } } - auto len = httpd_req_get_url_query_len(req); + // Access query string directly from URI — no stack buffer needed. + // http_parser identifies components by offset/length without modifying the URI string. + // This is the same pattern used by url_to(). + const char *query = strchr(req->uri, '?'); + if (query == nullptr) { + return {}; + } + query++; // skip '?' + size_t len = strlen(query); if (len == 0) { return {}; } - char buf[AsyncWebServerRequest::URL_BUF_SIZE]; - if (httpd_req_get_url_query_str(req, buf, len + 1) != ESP_OK) { - return {}; - } - return func(buf, len, name); + return func(query, len, name); } optional AsyncWebServerRequest::find_query_value_(const char *name) const { From 52461f10e71ff8329afc158e600a79e3e29ddb21 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 11 Feb 2026 19:06:28 -0600 Subject: [PATCH 2/2] Use httpd_req_get_url_query_len instead of strlen for query length The parsed URL already has the query length available via the httpd API. Avoids redundant strlen over the query string. --- esphome/components/web_server_idf/web_server_idf.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/components/web_server_idf/web_server_idf.cpp b/esphome/components/web_server_idf/web_server_idf.cpp index c335a47023e..1798159e7f7 100644 --- a/esphome/components/web_server_idf/web_server_idf.cpp +++ b/esphome/components/web_server_idf/web_server_idf.cpp @@ -418,18 +418,18 @@ static auto search_query_sources(httpd_req_t *req, const std::string &post_query return result; } } - // Access query string directly from URI — no stack buffer needed. + // Use httpd API for query length, then access string directly from URI. // http_parser identifies components by offset/length without modifying the URI string. // This is the same pattern used by url_to(). + auto len = httpd_req_get_url_query_len(req); + if (len == 0) { + return {}; + } const char *query = strchr(req->uri, '?'); if (query == nullptr) { return {}; } query++; // skip '?' - size_t len = strlen(query); - if (len == 0) { - return {}; - } return func(query, len, name); }