mirror of
https://github.com/esphome/esphome.git
synced 2026-01-21 02:19:10 -07:00
Compare commits
5 Commits
dev
...
idf_no_hea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ec6c37c01 | ||
|
|
eb24156f8c | ||
|
|
e81345de53 | ||
|
|
dd03c717a5 | ||
|
|
cc393ce893 |
@@ -96,10 +96,16 @@ void CaptivePortal::start() {
|
||||
}
|
||||
|
||||
void CaptivePortal::handleRequest(AsyncWebServerRequest *req) {
|
||||
if (req->url() == ESPHOME_F("/config.json")) {
|
||||
#ifdef USE_ESP32
|
||||
char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
|
||||
StringRef url = req->url_to(url_buf);
|
||||
#else
|
||||
const auto &url = req->url();
|
||||
#endif
|
||||
if (url == ESPHOME_F("/config.json")) {
|
||||
this->handle_config(req);
|
||||
return;
|
||||
} else if (req->url() == ESPHOME_F("/wifisave")) {
|
||||
} else if (url == ESPHOME_F("/wifisave")) {
|
||||
this->handle_wifisave(req);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -41,12 +41,14 @@ class PrometheusHandler : public AsyncWebHandler, public Component {
|
||||
void add_label_name(EntityBase *obj, const std::string &value) { relabel_map_name_.insert({obj, value}); }
|
||||
|
||||
bool canHandle(AsyncWebServerRequest *request) const override {
|
||||
if (request->method() == HTTP_GET) {
|
||||
if (request->url() == "/metrics")
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (request->method() != HTTP_GET)
|
||||
return false;
|
||||
#ifdef USE_ESP32
|
||||
char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
|
||||
return request->url_to(url_buf) == "/metrics";
|
||||
#else
|
||||
return request->url() == ESPHOME_F("/metrics");
|
||||
#endif
|
||||
}
|
||||
|
||||
void handleRequest(AsyncWebServerRequest *req) override;
|
||||
|
||||
@@ -32,8 +32,15 @@ class OTARequestHandler : public AsyncWebHandler {
|
||||
void handleUpload(AsyncWebServerRequest *request, const PlatformString &filename, size_t index, uint8_t *data,
|
||||
size_t len, bool final) override;
|
||||
bool canHandle(AsyncWebServerRequest *request) const override {
|
||||
// Check if this is an OTA update request
|
||||
bool is_ota_request = request->url() == "/update" && request->method() == HTTP_POST;
|
||||
if (request->method() != HTTP_POST)
|
||||
return false;
|
||||
// Check if this is an OTA update request
|
||||
#ifdef USE_ESP32
|
||||
char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
|
||||
bool is_ota_request = request->url_to(url_buf) == "/update";
|
||||
#else
|
||||
bool is_ota_request = request->url() == ESPHOME_F("/update");
|
||||
#endif
|
||||
|
||||
#if defined(USE_WEBSERVER_OTA_DISABLED) && defined(USE_CAPTIVE_PORTAL)
|
||||
// IMPORTANT: USE_WEBSERVER_OTA_DISABLED only disables OTA for the web_server component
|
||||
|
||||
@@ -2175,7 +2175,12 @@ std::string WebServer::update_json_(update::UpdateEntity *obj, JsonDetail start_
|
||||
#endif
|
||||
|
||||
bool WebServer::canHandle(AsyncWebServerRequest *request) const {
|
||||
#ifdef USE_ESP32
|
||||
char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
|
||||
StringRef url = request->url_to(url_buf);
|
||||
#else
|
||||
const auto &url = request->url();
|
||||
#endif
|
||||
const auto method = request->method();
|
||||
|
||||
// Static URL checks - use ESPHOME_F to keep strings in flash on ESP8266
|
||||
@@ -2311,30 +2316,35 @@ bool WebServer::canHandle(AsyncWebServerRequest *request) const {
|
||||
return false;
|
||||
}
|
||||
void WebServer::handleRequest(AsyncWebServerRequest *request) {
|
||||
#ifdef USE_ESP32
|
||||
char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
|
||||
StringRef url = request->url_to(url_buf);
|
||||
#else
|
||||
const auto &url = request->url();
|
||||
#endif
|
||||
|
||||
// Handle static routes first
|
||||
if (url == "/") {
|
||||
if (url == ESPHOME_F("/")) {
|
||||
this->handle_index_request(request);
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(USE_ESP32) && defined(USE_ARDUINO)
|
||||
if (url == "/events") {
|
||||
if (url == ESPHOME_F("/events")) {
|
||||
this->events_.add_new_client(this, request);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_WEBSERVER_CSS_INCLUDE
|
||||
if (url == "/0.css") {
|
||||
if (url == ESPHOME_F("/0.css")) {
|
||||
this->handle_css_request(request);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_WEBSERVER_JS_INCLUDE
|
||||
if (url == "/0.js") {
|
||||
if (url == ESPHOME_F("/0.js")) {
|
||||
this->handle_js_request(request);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -246,21 +246,16 @@ optional<std::string> AsyncWebServerRequest::get_header(const char *name) const
|
||||
return request_get_header(*this, name);
|
||||
}
|
||||
|
||||
std::string AsyncWebServerRequest::url() const {
|
||||
auto *query_start = strchr(this->req_->uri, '?');
|
||||
std::string result;
|
||||
if (query_start == nullptr) {
|
||||
result = this->req_->uri;
|
||||
} else {
|
||||
result = std::string(this->req_->uri, query_start - this->req_->uri);
|
||||
}
|
||||
StringRef AsyncWebServerRequest::url_to(std::span<char, URL_BUF_SIZE> buffer) const {
|
||||
const char *uri = this->req_->uri;
|
||||
const char *query_start = strchr(uri, '?');
|
||||
size_t uri_len = query_start ? static_cast<size_t>(query_start - uri) : strlen(uri);
|
||||
size_t copy_len = std::min(uri_len, URL_BUF_SIZE - 1);
|
||||
memcpy(buffer.data(), uri, copy_len);
|
||||
buffer[copy_len] = '\0';
|
||||
// Decode URL-encoded characters in-place (e.g., %20 -> space)
|
||||
// This matches AsyncWebServer behavior on Arduino
|
||||
if (!result.empty()) {
|
||||
size_t new_len = url_decode(&result[0]);
|
||||
result.resize(new_len);
|
||||
}
|
||||
return result;
|
||||
size_t decoded_len = url_decode(buffer.data());
|
||||
return StringRef(buffer.data(), decoded_len);
|
||||
}
|
||||
|
||||
std::string AsyncWebServerRequest::host() const { return this->get_header("Host").value(); }
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/string_ref.h"
|
||||
#include <esp_http_server.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -110,7 +112,15 @@ class AsyncWebServerRequest {
|
||||
~AsyncWebServerRequest();
|
||||
|
||||
http_method method() const { return static_cast<http_method>(this->req_->method); }
|
||||
std::string url() const;
|
||||
static constexpr size_t URL_BUF_SIZE = CONFIG_HTTPD_MAX_URI_LEN + 1; ///< Buffer size for url_to()
|
||||
/// Write URL (without query string) to buffer, returns StringRef pointing to buffer.
|
||||
/// URL is decoded (e.g., %20 -> space).
|
||||
StringRef url_to(std::span<char, URL_BUF_SIZE> buffer) const;
|
||||
/// Get URL as std::string. Prefer url_to() to avoid heap allocation.
|
||||
std::string url() const {
|
||||
char buffer[URL_BUF_SIZE];
|
||||
return std::string(this->url_to(buffer));
|
||||
}
|
||||
std::string host() const;
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
size_t contentLength() const { return this->req_->content_len; }
|
||||
@@ -306,7 +316,10 @@ class AsyncEventSource : public AsyncWebHandler {
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
bool canHandle(AsyncWebServerRequest *request) const override {
|
||||
return request->method() == HTTP_GET && request->url() == this->url_;
|
||||
if (request->method() != HTTP_GET)
|
||||
return false;
|
||||
char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
|
||||
return request->url_to(url_buf) == this->url_;
|
||||
}
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
void handleRequest(AsyncWebServerRequest *request) override;
|
||||
|
||||
Reference in New Issue
Block a user