mirror of
https://github.com/esphome/esphome.git
synced 2025-10-07 04:13:47 +01:00
Merge branch 'idf_query' into integration
This commit is contained in:
@@ -190,8 +190,8 @@ esp_err_t AsyncWebServer::request_handler_(AsyncWebServerRequest *request) const
|
|||||||
|
|
||||||
AsyncWebServerRequest::~AsyncWebServerRequest() {
|
AsyncWebServerRequest::~AsyncWebServerRequest() {
|
||||||
delete this->rsp_;
|
delete this->rsp_;
|
||||||
for (const auto &pair : this->params_) {
|
for (auto *param : this->params_) {
|
||||||
delete pair.second; // NOLINT(cppcoreguidelines-owning-memory)
|
delete param; // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,10 +231,23 @@ void AsyncWebServerRequest::redirect(const std::string &url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AsyncWebServerRequest::init_response_(AsyncWebServerResponse *rsp, int code, const char *content_type) {
|
void AsyncWebServerRequest::init_response_(AsyncWebServerResponse *rsp, int code, const char *content_type) {
|
||||||
httpd_resp_set_status(*this, code == 200 ? HTTPD_200
|
// Set status code - use constants for common codes to avoid string allocation
|
||||||
: code == 404 ? HTTPD_404
|
const char *status;
|
||||||
: code == 409 ? HTTPD_409
|
switch (code) {
|
||||||
: to_string(code).c_str());
|
case 200:
|
||||||
|
status = HTTPD_200;
|
||||||
|
break;
|
||||||
|
case 404:
|
||||||
|
status = HTTPD_404;
|
||||||
|
break;
|
||||||
|
case 409:
|
||||||
|
status = HTTPD_409;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
status = to_string(code).c_str();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
httpd_resp_set_status(*this, status);
|
||||||
|
|
||||||
if (content_type && *content_type) {
|
if (content_type && *content_type) {
|
||||||
httpd_resp_set_type(*this, content_type);
|
httpd_resp_set_type(*this, content_type);
|
||||||
@@ -291,11 +304,14 @@ void AsyncWebServerRequest::requestAuthentication(const char *realm) const {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
AsyncWebParameter *AsyncWebServerRequest::getParam(const std::string &name) {
|
AsyncWebParameter *AsyncWebServerRequest::getParam(const std::string &name) {
|
||||||
auto find = this->params_.find(name);
|
// Check cache first - only successful lookups are cached
|
||||||
if (find != this->params_.end()) {
|
for (auto *param : this->params_) {
|
||||||
return find->second;
|
if (param->name() == name) {
|
||||||
|
return param;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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_, 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);
|
||||||
@@ -304,11 +320,14 @@ AsyncWebParameter *AsyncWebServerRequest::getParam(const std::string &name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncWebParameter *param = nullptr;
|
// Don't cache misses to prevent memory exhaustion from malicious requests
|
||||||
if (val.has_value()) {
|
// with thousands of non-existent parameter lookups
|
||||||
param = new AsyncWebParameter(val.value()); // NOLINT(cppcoreguidelines-owning-memory)
|
if (!val.has_value()) {
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
this->params_.insert({name, param});
|
|
||||||
|
auto *param = new AsyncWebParameter(name, val.value()); // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
|
this->params_.push_back(param);
|
||||||
return param;
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,10 +24,12 @@ namespace web_server_idf {
|
|||||||
|
|
||||||
class AsyncWebParameter {
|
class AsyncWebParameter {
|
||||||
public:
|
public:
|
||||||
AsyncWebParameter(std::string value) : value_(std::move(value)) {}
|
AsyncWebParameter(std::string name, std::string value) : name_(std::move(name)), value_(std::move(value)) {}
|
||||||
|
const std::string &name() const { return this->name_; }
|
||||||
const std::string &value() const { return this->value_; }
|
const std::string &value() const { return this->value_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
std::string name_;
|
||||||
std::string value_;
|
std::string value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -168,7 +170,10 @@ class AsyncWebServerRequest {
|
|||||||
protected:
|
protected:
|
||||||
httpd_req_t *req_;
|
httpd_req_t *req_;
|
||||||
AsyncWebServerResponse *rsp_{};
|
AsyncWebServerResponse *rsp_{};
|
||||||
std::map<std::string, AsyncWebParameter *> params_;
|
// Use vector instead of map/unordered_map: most requests have 0-3 params, so linear search
|
||||||
|
// is faster than tree/hash overhead. AsyncWebParameter stores both name and value to avoid
|
||||||
|
// duplicate storage. Only successful lookups are cached to prevent memory exhaustion attacks.
|
||||||
|
std::vector<AsyncWebParameter *> params_;
|
||||||
std::string post_query_;
|
std::string post_query_;
|
||||||
AsyncWebServerRequest(httpd_req_t *req) : req_(req) {}
|
AsyncWebServerRequest(httpd_req_t *req) : req_(req) {}
|
||||||
AsyncWebServerRequest(httpd_req_t *req, std::string post_query) : req_(req), post_query_(std::move(post_query)) {}
|
AsyncWebServerRequest(httpd_req_t *req, std::string post_query) : req_(req), post_query_(std::move(post_query)) {}
|
||||||
|
Reference in New Issue
Block a user