diff --git a/components/esp_common/src/esp_err_to_name.c b/components/esp_common/src/esp_err_to_name.c index 0c517cb725..bf4c3b7d7e 100644 --- a/components/esp_common/src/esp_err_to_name.c +++ b/components/esp_common/src/esp_err_to_name.c @@ -659,6 +659,10 @@ static const esp_err_msg_t esp_err_msg_table[] = { # endif # ifdef ESP_ERR_HTTP_NOT_MODIFIED ERR_TBL_IT(ESP_ERR_HTTP_NOT_MODIFIED), /* 28681 0x7009 HTTP 304 Not Modified, no update available */ +# endif +# ifdef ESP_ERR_HTTP_RANGE_NOT_SATISFIABLE + ERR_TBL_IT(ESP_ERR_HTTP_RANGE_NOT_SATISFIABLE), /* 28682 0x700a HTTP 416 Range Not Satisfiable, + requested range in header is incorrect */ # endif // components/esp-tls/esp_tls_errors.h # ifdef ESP_ERR_ESP_TLS_BASE diff --git a/components/esp_http_client/include/esp_http_client.h b/components/esp_http_client/include/esp_http_client.h index 0d0137af86..fb2bd5b6ee 100644 --- a/components/esp_http_client/include/esp_http_client.h +++ b/components/esp_http_client/include/esp_http_client.h @@ -227,6 +227,7 @@ typedef enum { HttpStatus_Unauthorized = 401, HttpStatus_Forbidden = 403, HttpStatus_NotFound = 404, + HttpStatus_RangeNotSatisfiable = 416, /* 5xx - Server Error */ HttpStatus_InternalError = 500 @@ -242,6 +243,7 @@ typedef enum { #define ESP_ERR_HTTP_EAGAIN (ESP_ERR_HTTP_BASE + 7) /*!< Mapping of errno EAGAIN to esp_err_t */ #define ESP_ERR_HTTP_CONNECTION_CLOSED (ESP_ERR_HTTP_BASE + 8) /*!< Read FIN from peer and the connection closed */ #define ESP_ERR_HTTP_NOT_MODIFIED (ESP_ERR_HTTP_BASE + 9) /*!< HTTP 304 Not Modified, no update available */ +#define ESP_ERR_HTTP_RANGE_NOT_SATISFIABLE (ESP_ERR_HTTP_BASE + 10) /*!< HTTP 416 Range Not Satisfiable, requested range in header is incorrect */ /** * @brief Start a HTTP session diff --git a/components/esp_https_ota/src/esp_https_ota.c b/components/esp_https_ota/src/esp_https_ota.c index 7660ea4b49..f771f3c54c 100644 --- a/components/esp_https_ota/src/esp_https_ota.c +++ b/components/esp_https_ota/src/esp_https_ota.c @@ -108,6 +108,9 @@ static esp_err_t _http_handle_response_code(esp_https_ota_t *https_ota_handle, i } else if (status_code == HttpStatus_NotModified) { ESP_LOGI(TAG, "OTA image not modified since last request (status code: %d)", status_code); return ESP_ERR_HTTP_NOT_MODIFIED; + } else if (status_code == HttpStatus_RangeNotSatisfiable) { + ESP_LOGI(TAG, "Requested range is incorrect (status code: %d)", status_code); + return ESP_ERR_HTTP_RANGE_NOT_SATISFIABLE; } else if (status_code == HttpStatus_Unauthorized) { if (https_ota_handle->max_authorization_retries == 0) { ESP_LOGE(TAG, "Reached max_authorization_retries (%d)", status_code); @@ -402,6 +405,28 @@ esp_err_t esp_https_ota_begin(const esp_https_ota_config_t *ota_config, esp_http } err = _http_connect(https_ota_handle); + if (err == ESP_ERR_HTTP_RANGE_NOT_SATISFIABLE && https_ota_handle->binary_file_len > 0) { + ESP_LOGE(TAG, "OTA resumption failed with err: %d", err); + ESP_LOGI(TAG, "Restarting download from beginning"); + https_ota_handle->binary_file_len = 0; + + // If range in request header is not satisfiable, restart download from beginning + esp_http_client_delete_header(https_ota_handle->http_client, "Range"); + + if (https_ota_handle->partial_http_download && https_ota_handle->image_length > https_ota_handle->max_http_request_size) { + char *header_val = NULL; + asprintf(&header_val, "bytes=0-%d", https_ota_handle->max_http_request_size - 1); + if (header_val == NULL) { + ESP_LOGE(TAG, "Failed to allocate memory for HTTP header"); + err = ESP_ERR_NO_MEM; + goto http_cleanup; + } + esp_http_client_set_header(https_ota_handle->http_client, "Range", header_val); + free(header_val); + } + err = _http_connect(https_ota_handle); + } + if (err != ESP_OK) { if (err != ESP_ERR_HTTP_NOT_MODIFIED) { ESP_LOGE(TAG, "Failed to establish HTTP connection");