1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00

[web_server_idf] Add const char* overloads for getParam/hasParam to avoid temporary string allocations

This commit is contained in:
J. Nick Koston
2026-02-03 15:30:40 +01:00
parent 21bd0ff6aa
commit f021df399e
4 changed files with 20 additions and 15 deletions

View File

@@ -73,18 +73,15 @@ optional<std::string> request_get_url_query(httpd_req_t *req) {
return {str}; return {str};
} }
optional<std::string> query_key_value(const std::string &query_url, const std::string &key) { optional<std::string> query_key_value(const char *query_url, size_t query_len, const char *key) {
if (query_url.empty()) { if (query_url == nullptr || query_len == 0) {
return {}; return {};
} }
auto val = std::unique_ptr<char[]>(new char[query_url.size()]); // Use stack buffer for typical query strings, heap fallback for large ones
if (!val) { SmallBufferWithHeapFallback<256, char> val(query_len);
ESP_LOGE(TAG, "Not enough memory to the query key value");
return {};
}
if (httpd_query_key_value(query_url.c_str(), key.c_str(), val.get(), query_url.size()) != ESP_OK) { if (httpd_query_key_value(query_url, key, val.get(), query_len) != ESP_OK) {
return {}; return {};
} }

View File

@@ -15,7 +15,10 @@ size_t url_decode(char *str);
bool request_has_header(httpd_req_t *req, const char *name); bool request_has_header(httpd_req_t *req, const char *name);
optional<std::string> request_get_header(httpd_req_t *req, const char *name); optional<std::string> request_get_header(httpd_req_t *req, const char *name);
optional<std::string> request_get_url_query(httpd_req_t *req); optional<std::string> request_get_url_query(httpd_req_t *req);
optional<std::string> query_key_value(const std::string &query_url, const std::string &key); optional<std::string> query_key_value(const char *query_url, size_t query_len, const char *key);
inline optional<std::string> query_key_value(const std::string &query_url, const std::string &key) {
return query_key_value(query_url.c_str(), query_url.size(), key.c_str());
}
// Helper function for case-insensitive character comparison // Helper function for case-insensitive character comparison
inline bool char_equals_ci(char a, char b) { return ::tolower(a) == ::tolower(b); } inline bool char_equals_ci(char a, char b) { return ::tolower(a) == ::tolower(b); }

View File

@@ -366,7 +366,7 @@ void AsyncWebServerRequest::requestAuthentication(const char *realm) const {
} }
#endif #endif
AsyncWebParameter *AsyncWebServerRequest::getParam(const std::string &name) { AsyncWebParameter *AsyncWebServerRequest::getParam(const char *name) {
// Check cache first - only successful lookups are cached // Check cache first - only successful lookups are cached
for (auto *param : this->params_) { for (auto *param : this->params_) {
if (param->name() == name) { if (param->name() == name) {
@@ -375,11 +375,11 @@ AsyncWebParameter *AsyncWebServerRequest::getParam(const std::string &name) {
} }
// Look up value from query strings // Look up value from query strings
optional<std::string> val = query_key_value(this->post_query_, name); optional<std::string> val = query_key_value(this->post_query_.c_str(), this->post_query_.size(), name);
if (!val.has_value()) { if (!val.has_value()) {
auto url_query = request_get_url_query(*this); auto url_query = request_get_url_query(*this);
if (url_query.has_value()) { if (url_query.has_value()) {
val = query_key_value(url_query.value(), name); val = query_key_value(url_query.value().c_str(), url_query.value().size(), name);
} }
} }

View File

@@ -162,19 +162,24 @@ class AsyncWebServerRequest {
} }
// NOLINTNEXTLINE(readability-identifier-naming) // NOLINTNEXTLINE(readability-identifier-naming)
bool hasParam(const std::string &name) { return this->getParam(name) != nullptr; } bool hasParam(const char *name) { return this->getParam(name) != nullptr; }
// NOLINTNEXTLINE(readability-identifier-naming) // NOLINTNEXTLINE(readability-identifier-naming)
AsyncWebParameter *getParam(const std::string &name); bool hasParam(const std::string &name) { return this->getParam(name.c_str()) != nullptr; }
// NOLINTNEXTLINE(readability-identifier-naming)
AsyncWebParameter *getParam(const char *name);
// NOLINTNEXTLINE(readability-identifier-naming)
AsyncWebParameter *getParam(const std::string &name) { return this->getParam(name.c_str()); }
// NOLINTNEXTLINE(readability-identifier-naming) // NOLINTNEXTLINE(readability-identifier-naming)
bool hasArg(const char *name) { return this->hasParam(name); } bool hasArg(const char *name) { return this->hasParam(name); }
std::string arg(const std::string &name) { std::string arg(const char *name) {
auto *param = this->getParam(name); auto *param = this->getParam(name);
if (param) { if (param) {
return param->value(); return param->value();
} }
return {}; return {};
} }
std::string arg(const std::string &name) { return this->arg(name.c_str()); }
operator httpd_req_t *() const { return this->req_; } operator httpd_req_t *() const { return this->req_; }
optional<std::string> get_header(const char *name) const; optional<std::string> get_header(const char *name) const;