mirror of
https://github.com/esphome/esphome.git
synced 2026-05-30 23:54:04 +08:00
[web_server_idf] Always enable LRU purge to prevent socket exhaustion (#12481)
This commit is contained in:
committed by
Jonathan Swoboda
parent
2e9ddd967c
commit
c85b1b8609
@@ -65,12 +65,6 @@ void CaptivePortal::start() {
|
|||||||
this->base_->init();
|
this->base_->init();
|
||||||
if (!this->initialized_) {
|
if (!this->initialized_) {
|
||||||
this->base_->add_handler(this);
|
this->base_->add_handler(this);
|
||||||
#ifdef USE_ESP32
|
|
||||||
// Enable LRU socket purging to handle captive portal detection probe bursts
|
|
||||||
// OS captive portal detection makes many simultaneous HTTP requests which can
|
|
||||||
// exhaust sockets. LRU purging automatically closes oldest idle connections.
|
|
||||||
this->base_->get_server()->set_lru_purge_enable(true);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
network::IPAddress ip = wifi::global_wifi_component->wifi_soft_ap_ip();
|
network::IPAddress ip = wifi::global_wifi_component->wifi_soft_ap_ip();
|
||||||
|
|||||||
@@ -40,10 +40,6 @@ class CaptivePortal : public AsyncWebHandler, public Component {
|
|||||||
void end() {
|
void end() {
|
||||||
this->active_ = false;
|
this->active_ = false;
|
||||||
this->disable_loop(); // Stop processing DNS requests
|
this->disable_loop(); // Stop processing DNS requests
|
||||||
#ifdef USE_ESP32
|
|
||||||
// Disable LRU socket purging now that captive portal is done
|
|
||||||
this->base_->get_server()->set_lru_purge_enable(false);
|
|
||||||
#endif
|
|
||||||
this->base_->deinit();
|
this->base_->deinit();
|
||||||
if (this->dns_server_ != nullptr) {
|
if (this->dns_server_ != nullptr) {
|
||||||
this->dns_server_->stop();
|
this->dns_server_->stop();
|
||||||
|
|||||||
@@ -117,18 +117,6 @@ void AsyncWebServer::end() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncWebServer::set_lru_purge_enable(bool enable) {
|
|
||||||
if (this->lru_purge_enable_ == enable) {
|
|
||||||
return; // No change needed
|
|
||||||
}
|
|
||||||
this->lru_purge_enable_ = enable;
|
|
||||||
// If server is already running, restart it with new config
|
|
||||||
if (this->server_) {
|
|
||||||
this->end();
|
|
||||||
this->begin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsyncWebServer::begin() {
|
void AsyncWebServer::begin() {
|
||||||
if (this->server_) {
|
if (this->server_) {
|
||||||
this->end();
|
this->end();
|
||||||
@@ -136,8 +124,11 @@ void AsyncWebServer::begin() {
|
|||||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||||
config.server_port = this->port_;
|
config.server_port = this->port_;
|
||||||
config.uri_match_fn = [](const char * /*unused*/, const char * /*unused*/, size_t /*unused*/) { return true; };
|
config.uri_match_fn = [](const char * /*unused*/, const char * /*unused*/, size_t /*unused*/) { return true; };
|
||||||
// Enable LRU purging if requested (e.g., by captive portal to handle probe bursts)
|
// Always enable LRU purging to handle socket exhaustion gracefully.
|
||||||
config.lru_purge_enable = this->lru_purge_enable_;
|
// When max sockets is reached, the oldest connection is closed to make room for new ones.
|
||||||
|
// This prevents "httpd_accept_conn: error in accept (23)" errors.
|
||||||
|
// See: https://github.com/esphome/esphome/issues/12464
|
||||||
|
config.lru_purge_enable = true;
|
||||||
// Use custom close function that shuts down before closing to prevent lwIP race conditions
|
// Use custom close function that shuts down before closing to prevent lwIP race conditions
|
||||||
config.close_fn = AsyncWebServer::safe_close_with_shutdown;
|
config.close_fn = AsyncWebServer::safe_close_with_shutdown;
|
||||||
if (httpd_start(&this->server_, &config) == ESP_OK) {
|
if (httpd_start(&this->server_, &config) == ESP_OK) {
|
||||||
|
|||||||
@@ -199,13 +199,11 @@ class AsyncWebServer {
|
|||||||
return *handler;
|
return *handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_lru_purge_enable(bool enable);
|
|
||||||
httpd_handle_t get_server() { return this->server_; }
|
httpd_handle_t get_server() { return this->server_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint16_t port_{};
|
uint16_t port_{};
|
||||||
httpd_handle_t server_{};
|
httpd_handle_t server_{};
|
||||||
bool lru_purge_enable_{false};
|
|
||||||
static esp_err_t request_handler(httpd_req_t *r);
|
static esp_err_t request_handler(httpd_req_t *r);
|
||||||
static esp_err_t request_post_handler(httpd_req_t *r);
|
static esp_err_t request_post_handler(httpd_req_t *r);
|
||||||
esp_err_t request_handler_(AsyncWebServerRequest *request) const;
|
esp_err_t request_handler_(AsyncWebServerRequest *request) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user