From be08f6f2bb7ad41a6450d113b9b6a673ae4d9fdd Mon Sep 17 00:00:00 2001 From: Hrudaynath Dhabe Date: Fri, 2 Aug 2019 19:18:44 +0800 Subject: [PATCH] esp_http_client: Add support to check the binary length of the recieved stream and compare it with the size mentioned in the header. While downloading OTA firmware, if their is a Origin Respnse Timeout or the binary is only partially downloaded, OTA failure is observed. Checking binary size can also be helpful for simple http client applications. Closes https://github.com/espressif/esp-idf/issues/3004 --- components/esp_http_client/esp_http_client.c | 22 ++++++++++++++++++- .../esp_http_client/include/esp_http_client.h | 11 ++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c index 135766fd9..7a186f74b 100644 --- a/components/esp_http_client/esp_http_client.c +++ b/components/esp_http_client/esp_http_client.c @@ -796,6 +796,22 @@ static int esp_http_client_get_data(esp_http_client_handle_t client) return rlen; } +bool esp_http_client_is_complete_data_received(esp_http_client_handle_t client) +{ + if (client->response->is_chunked) { + if (!client->is_chunk_complete) { + ESP_LOGI(TAG, "Chunks were not completely read"); + return false; + } + } else { + if (client->response->data_process != client->response->content_length) { + ESP_LOGI(TAG, "Data processed %d != Data specified in content length %d", client->response->data_process, client->response->content_length); + return false; + } + } + return true; +} + int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len) { esp_http_buffer_t *res_buffer = client->response->buffer; @@ -819,7 +835,7 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len) } else { is_data_remain = client->response->data_process < client->response->content_length; } - ESP_LOGD(TAG, "is_data_remain=%d, is_chunked=%d", is_data_remain, client->response->is_chunked); + ESP_LOGD(TAG, "is_data_remain=%d, is_chunked=%d, content_length=%d", is_data_remain, client->response->is_chunked, client->response->content_length); if (!is_data_remain) { break; } @@ -827,10 +843,14 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len) if (byte_to_read > client->buffer_size_rx) { byte_to_read = client->buffer_size_rx; } + errno = 0; rlen = esp_transport_read(client->transport, res_buffer->data, byte_to_read, client->timeout_ms); ESP_LOGD(TAG, "need_read=%d, byte_to_read=%d, rlen=%d, ridx=%d", need_read, byte_to_read, rlen, ridx); if (rlen <= 0) { + if (errno != 0) { + ESP_LOGW(TAG, "esp_transport_read returned : %d and errno : %d ", rlen, errno); + } return ridx; } res_buffer->output_ptr = buffer + ridx; diff --git a/components/esp_http_client/include/esp_http_client.h b/components/esp_http_client/include/esp_http_client.h index 538e0c45e..2f35fc975 100644 --- a/components/esp_http_client/include/esp_http_client.h +++ b/components/esp_http_client/include/esp_http_client.h @@ -473,6 +473,17 @@ esp_err_t esp_http_client_set_redirection(esp_http_client_handle_t client); */ void esp_http_client_add_auth(esp_http_client_handle_t client); +/** + * @brief Checks if entire data in the response has been read without any error. + * + * @param[in] client The esp_http_client handle + * + * @return + * - true + * - false + */ +bool esp_http_client_is_complete_data_received(esp_http_client_handle_t client); + #ifdef __cplusplus } #endif