mirror of
https://github.com/esphome/esphome.git
synced 2026-10-17 19:52:50 +00:00
[web_server] Do not match internal entities by URL unless include_internal is set (#20883)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
co-authored by
Claude Opus 5.5
J. Nick Koston
J. Nick Koston
parent
5ab92ed363
commit
cd6a34401b
@@ -203,6 +203,10 @@ static UrlMatch match_url(const char *url_ptr, size_t url_len, bool only_domain,
|
||||
EntityMatchResult UrlMatch::match_entity(EntityBase *entity) const {
|
||||
EntityMatchResult result{false, this->method.empty()};
|
||||
|
||||
// Internal entities are unreachable by URL unless include_internal is set, as with the native API and MQTT.
|
||||
if (!this->include_internal && entity->is_internal())
|
||||
return result;
|
||||
|
||||
#ifdef USE_DEVICES
|
||||
Device *entity_device = entity->get_device();
|
||||
bool url_has_device = !this->device_name.empty();
|
||||
@@ -2560,6 +2564,7 @@ void WebServer::handleRequest(AsyncWebServerRequest *request) {
|
||||
// Parse URL for component routing
|
||||
// Pass HTTP method to disambiguate 3-segment URLs (GET=sub-device state, POST=main device action)
|
||||
UrlMatch match = match_url(url.c_str(), url.length(), false, request->method() == HTTP_POST);
|
||||
match.include_internal = this->include_internal_;
|
||||
|
||||
// Route to appropriate handler based on domain
|
||||
// NOLINTNEXTLINE(readability-simplify-boolean-expr)
|
||||
|
||||
@@ -66,7 +66,8 @@ struct UrlMatch {
|
||||
#ifdef USE_DEVICES
|
||||
StringRef device_name; ///< Device name within URL, empty for main device
|
||||
#endif
|
||||
bool valid{false}; ///< Whether this match is valid
|
||||
bool valid{false}; ///< Whether this match is valid
|
||||
bool include_internal{false}; ///< Whether internal entities may match, the web server's include_internal
|
||||
|
||||
// Helper methods for string comparisons
|
||||
bool domain_equals(const char *str) const { return this->domain == str; }
|
||||
@@ -78,7 +79,7 @@ struct UrlMatch {
|
||||
bool method_equals(const __FlashStringHelper *str) const { return this->method == str; }
|
||||
#endif
|
||||
|
||||
/// Match entity by name
|
||||
/// Match entity by name; internal entities match only if include_internal is set
|
||||
/// Returns EntityMatchResult with match status and whether action segment is empty
|
||||
EntityMatchResult match_entity(EntityBase *entity) const;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user