From c6a7616de08733f739a3fbca20c1366955227974 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 30 Jan 2026 14:16:16 -0600 Subject: [PATCH] be explict --- esphome/components/http_request/http_request.h | 15 ++++++++++----- .../http_request/http_request_arduino.cpp | 2 ++ .../components/http_request/http_request_idf.cpp | 2 ++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index 8269c0b28e2..228aa681ac7 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -26,6 +26,7 @@ struct Header { enum HttpStatus { HTTP_STATUS_OK = 200, HTTP_STATUS_NO_CONTENT = 204, + HTTP_STATUS_RESET_CONTENT = 205, HTTP_STATUS_PARTIAL_CONTENT = 206, /* 3xx - Redirection */ @@ -199,19 +200,22 @@ class HttpContainer : public Parented { virtual void end() = 0; void set_secure(bool secure) { this->secure_ = secure; } + void set_chunked(bool chunked) { this->is_chunked_ = chunked; } size_t get_bytes_read() const { return this->bytes_read_; } - /// Check if all expected content has been read (only valid for non-chunked responses) - /// For chunked responses (content_length == 0 on ESP-IDF, SIZE_MAX on Arduino), returns false + /// Check if all expected content has been read + /// For chunked responses, returns false (completion detected via read() returning error/EOF) bool is_read_complete() const { // Per RFC 9112, these responses have no body: - // - 1xx (Informational), 204 No Content, 304 Not Modified + // - 1xx (Informational), 204 No Content, 205 Reset Content, 304 Not Modified if ((this->status_code >= 100 && this->status_code < 200) || this->status_code == HTTP_STATUS_NO_CONTENT || - this->status_code == HTTP_STATUS_NOT_MODIFIED) { + this->status_code == HTTP_STATUS_RESET_CONTENT || this->status_code == HTTP_STATUS_NOT_MODIFIED) { return true; } - return this->content_length > 0 && this->content_length < SIZE_MAX && this->bytes_read_ >= this->content_length; + // For non-chunked responses, complete when bytes_read >= content_length + // This handles both Content-Length: 0 and Content-Length: N cases + return !this->is_chunked_ && this->bytes_read_ >= this->content_length; } /** @@ -226,6 +230,7 @@ class HttpContainer : public Parented { protected: size_t bytes_read_{0}; bool secure_{false}; + bool is_chunked_{false}; ///< True if response uses chunked transfer encoding std::map> response_headers_{}; }; diff --git a/esphome/components/http_request/http_request_arduino.cpp b/esphome/components/http_request/http_request_arduino.cpp index 8f17622d2ba..2f12b58766b 100644 --- a/esphome/components/http_request/http_request_arduino.cpp +++ b/esphome/components/http_request/http_request_arduino.cpp @@ -150,6 +150,8 @@ std::shared_ptr HttpRequestArduino::perform(const std::string &ur int content_length = container->client_.getSize(); ESP_LOGD(TAG, "Content-Length: %d", content_length); container->content_length = (size_t) content_length; + // -1 (SIZE_MAX when cast to size_t) means chunked transfer encoding + container->set_chunked(content_length == -1); container->duration_ms = millis() - start; return container; diff --git a/esphome/components/http_request/http_request_idf.cpp b/esphome/components/http_request/http_request_idf.cpp index 7924e068805..bd12b7d1231 100644 --- a/esphome/components/http_request/http_request_idf.cpp +++ b/esphome/components/http_request/http_request_idf.cpp @@ -160,6 +160,7 @@ std::shared_ptr HttpRequestIDF::perform(const std::string &url, c // esp_http_client_fetch_headers() returns 0 for chunked transfer encoding (no Content-Length header). // The read() method handles content_length == 0 specially to support chunked responses. container->content_length = esp_http_client_fetch_headers(client); + container->set_chunked(esp_http_client_is_chunked_response(client)); container->feed_wdt(); container->status_code = esp_http_client_get_status_code(client); container->feed_wdt(); @@ -195,6 +196,7 @@ std::shared_ptr HttpRequestIDF::perform(const std::string &url, c container->feed_wdt(); container->content_length = esp_http_client_fetch_headers(client); + container->set_chunked(esp_http_client_is_chunked_response(client)); container->feed_wdt(); container->status_code = esp_http_client_get_status_code(client); container->feed_wdt();