From df750d0d11ce31e793de06d0e00663c8e23a3680 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Tue, 29 Oct 2024 14:05:58 +1100 Subject: [PATCH] [http_request] Add enum for status codes (#7690) --- .../components/http_request/http_request.h | 57 +++++++++++++++++++ .../http_request/http_request_arduino.cpp | 2 +- .../http_request/http_request_idf.cpp | 17 ++---- .../http_request/ota/ota_http_request.cpp | 2 +- .../update/http_request_update.cpp | 2 +- 5 files changed, 65 insertions(+), 15 deletions(-) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index c01baf8644..d87d9b8a45 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -22,6 +22,63 @@ struct Header { const char *value; }; +// Some common HTTP status codes +enum HttpStatus { + HTTP_STATUS_OK = 200, + HTTP_STATUS_NO_CONTENT = 204, + HTTP_STATUS_PARTIAL_CONTENT = 206, + + /* 3xx - Redirection */ + HTTP_STATUS_MULTIPLE_CHOICES = 300, + HTTP_STATUS_MOVED_PERMANENTLY = 301, + HTTP_STATUS_FOUND = 302, + HTTP_STATUS_SEE_OTHER = 303, + HTTP_STATUS_NOT_MODIFIED = 304, + HTTP_STATUS_TEMPORARY_REDIRECT = 307, + HTTP_STATUS_PERMANENT_REDIRECT = 308, + + /* 4XX - CLIENT ERROR */ + HTTP_STATUS_BAD_REQUEST = 400, + HTTP_STATUS_UNAUTHORIZED = 401, + HTTP_STATUS_FORBIDDEN = 403, + HTTP_STATUS_NOT_FOUND = 404, + HTTP_STATUS_METHOD_NOT_ALLOWED = 405, + HTTP_STATUS_NOT_ACCEPTABLE = 406, + HTTP_STATUS_LENGTH_REQUIRED = 411, + + /* 5xx - Server Error */ + HTTP_STATUS_INTERNAL_ERROR = 500 +}; + +/** + * @brief Returns true if the HTTP status code is a redirect. + * + * @param status the HTTP status code to check + * @return true if the status code is a redirect, false otherwise + */ +inline bool is_redirect(int const status) { + switch (status) { + case HTTP_STATUS_MOVED_PERMANENTLY: + case HTTP_STATUS_FOUND: + case HTTP_STATUS_SEE_OTHER: + case HTTP_STATUS_TEMPORARY_REDIRECT: + case HTTP_STATUS_PERMANENT_REDIRECT: + return true; + default: + return false; + } +} + +/** + * @brief Checks if the given HTTP status code indicates a successful request. + * + * A successful request is one where the status code is in the range 200-299 + * + * @param status the HTTP status code to check + * @return true if the status code indicates a successful request, false otherwise + */ +inline bool is_success(int const status) { return status >= HTTP_STATUS_OK && status < HTTP_STATUS_MULTIPLE_CHOICES; } + class HttpRequestComponent; class HttpContainer : public Parented { diff --git a/esphome/components/http_request/http_request_arduino.cpp b/esphome/components/http_request/http_request_arduino.cpp index f000082034..af1eb6f459 100644 --- a/esphome/components/http_request/http_request_arduino.cpp +++ b/esphome/components/http_request/http_request_arduino.cpp @@ -113,7 +113,7 @@ std::shared_ptr HttpRequestArduino::start(std::string url, std::s return nullptr; } - if (container->status_code < 200 || container->status_code >= 300) { + if (!is_success(container->status_code)) { ESP_LOGE(TAG, "HTTP Request failed; URL: %s; Code: %d", url.c_str(), container->status_code); this->status_momentary_error("failed", 1000); // Still return the container, so it can be used to get the status code and error message diff --git a/esphome/components/http_request/http_request_idf.cpp b/esphome/components/http_request/http_request_idf.cpp index e47e1d488e..c6c567b620 100644 --- a/esphome/components/http_request/http_request_idf.cpp +++ b/esphome/components/http_request/http_request_idf.cpp @@ -6,7 +6,6 @@ #include "esphome/components/watchdog/watchdog.h" #include "esphome/core/application.h" -#include "esphome/core/defines.h" #include "esphome/core/log.h" #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE @@ -118,20 +117,14 @@ std::shared_ptr HttpRequestIDF::start(std::string url, std::strin return nullptr; } - auto is_ok = [](int code) { return code >= HttpStatus_Ok && code < HttpStatus_MultipleChoices; }; - container->content_length = esp_http_client_fetch_headers(client); container->status_code = esp_http_client_get_status_code(client); - if (is_ok(container->status_code)) { + if (is_success(container->status_code)) { container->duration_ms = millis() - start; return container; } if (this->follow_redirects_) { - auto is_redirect = [](int code) { - return code == HttpStatus_MovedPermanently || code == HttpStatus_Found || code == HttpStatus_SeeOther || - code == HttpStatus_TemporaryRedirect || code == HttpStatus_PermanentRedirect; - }; auto num_redirects = this->redirect_limit_; while (is_redirect(container->status_code) && num_redirects > 0) { err = esp_http_client_set_redirection(client); @@ -142,9 +135,9 @@ std::shared_ptr HttpRequestIDF::start(std::string url, std::strin return nullptr; } #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE - char url[256]{}; - if (esp_http_client_get_url(client, url, sizeof(url) - 1) == ESP_OK) { - ESP_LOGV(TAG, "redirecting to url: %s", url); + char redirect_url[256]{}; + if (esp_http_client_get_url(client, redirect_url, sizeof(redirect_url) - 1) == ESP_OK) { + ESP_LOGV(TAG, "redirecting to url: %s", redirect_url); } #endif err = esp_http_client_open(client, 0); @@ -157,7 +150,7 @@ std::shared_ptr HttpRequestIDF::start(std::string url, std::strin container->content_length = esp_http_client_fetch_headers(client); container->status_code = esp_http_client_get_status_code(client); - if (is_ok(container->status_code)) { + if (is_success(container->status_code)) { container->duration_ms = millis() - start; return container; } diff --git a/esphome/components/http_request/ota/ota_http_request.cpp b/esphome/components/http_request/ota/ota_http_request.cpp index f7c941da18..cec30d72ec 100644 --- a/esphome/components/http_request/ota/ota_http_request.cpp +++ b/esphome/components/http_request/ota/ota_http_request.cpp @@ -106,7 +106,7 @@ uint8_t OtaHttpRequestComponent::do_ota_() { auto container = this->parent_->get(url_with_auth); - if (container == nullptr || container->status_code != 200) { + if (container == nullptr || container->status_code != HTTP_STATUS_OK) { return OTA_CONNECTION_ERROR; } diff --git a/esphome/components/http_request/update/http_request_update.cpp b/esphome/components/http_request/update/http_request_update.cpp index 4d913f2158..0e0966c22b 100644 --- a/esphome/components/http_request/update/http_request_update.cpp +++ b/esphome/components/http_request/update/http_request_update.cpp @@ -31,7 +31,7 @@ void HttpRequestUpdate::setup() { void HttpRequestUpdate::update() { auto container = this->request_parent_->get(this->source_url_); - if (container == nullptr || container->status_code != 200) { + if (container == nullptr || container->status_code != HTTP_STATUS_OK) { std::string msg = str_sprintf("Failed to fetch manifest from %s", this->source_url_.c_str()); this->status_set_error(msg.c_str()); return;