feat(esp_http_client): handle error while reading data from server

This commit updated API esp_http_cleint_perform() to handle error and
dispatched error  event if any error occured whiling reading data from server.
This commit is contained in:
nilesh.kale
2025-07-30 10:33:59 +05:30
committed by Nilesh Kale
parent 3ef41363cf
commit 73d8ad9083
3 changed files with 49 additions and 6 deletions

View File

@@ -666,6 +666,13 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# 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
# ifdef ESP_ERR_HTTP_READ_TIMEOUT
ERR_TBL_IT(ESP_ERR_HTTP_READ_TIMEOUT), /* 28683 0x700b HTTP data read timeout */
# endif
# ifdef ESP_ERR_HTTP_INCOMPLETE_DATA
ERR_TBL_IT(ESP_ERR_HTTP_INCOMPLETE_DATA), /* 28684 0x700c Incomplete data received, less than
Content-Length or last chunk */
# endif
// components/esp-tls/esp_tls_errors.h
# ifdef ESP_ERR_ESP_TLS_BASE

View File

@@ -1418,7 +1418,7 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
{
esp_err_t err;
esp_err_t err = ESP_FAIL;
do {
if (client->process_again) {
esp_http_client_prepare(client);
@@ -1493,23 +1493,53 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
return err;
}
while (client->response->is_chunked && !client->is_chunk_complete) {
if (esp_http_client_get_data(client) <= 0) {
int ret = esp_http_client_get_data(client);
if (ret <= 0) {
if (client->is_async && errno == EAGAIN) {
return ESP_ERR_HTTP_EAGAIN;
}
if (client->connection_info.method != HTTP_METHOD_HEAD && !client->is_chunk_complete) {
ESP_LOGE(TAG, "Incomplete chunked data received %d", ret);
if (ret == ESP_ERR_TCP_TRANSPORT_CONNECTION_TIMEOUT) {
err = ESP_ERR_HTTP_READ_TIMEOUT;
} else if (ret == ESP_ERR_TCP_TRANSPORT_CONNECTION_CLOSED_BY_FIN) {
err = ESP_ERR_HTTP_CONNECTION_CLOSED;
} else {
err = ESP_ERR_HTTP_INCOMPLETE_DATA;
}
}
ESP_LOGD(TAG, "Read finish or server requests close");
break;
}
}
while (client->response->data_process < client->response->content_length) {
if (esp_http_client_get_data(client) <= 0) {
int ret = esp_http_client_get_data(client);
if (ret <= 0) {
if (client->is_async && errno == EAGAIN) {
return ESP_ERR_HTTP_EAGAIN;
}
if (client->connection_info.method != HTTP_METHOD_HEAD && client->response->data_process < client->response->content_length) {
ESP_LOGE(TAG, "Incomlete data received, ret=%d, %"PRId64"/%"PRId64" bytes", ret, client->response->data_process, client->response->content_length);
if (ret == ESP_ERR_TCP_TRANSPORT_CONNECTION_TIMEOUT) {
err = ESP_ERR_HTTP_READ_TIMEOUT;
} else if (ret == ESP_ERR_TCP_TRANSPORT_CONNECTION_CLOSED_BY_FIN) {
err = ESP_ERR_HTTP_CONNECTION_CLOSED;
} else {
err = ESP_ERR_HTTP_INCOMPLETE_DATA;
}
}
ESP_LOGD(TAG, "Read finish or server requests close");
break;
}
}
if (err != ESP_OK) {
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
}
http_dispatch_event(client, HTTP_EVENT_ON_FINISH, NULL, 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ON_FINISH, &client, sizeof(esp_http_client_handle_t));
@@ -1527,8 +1557,9 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
default:
break;
}
} while (client->process_again);
return ESP_OK;
} while (client->process_again && err == ESP_OK);
return err;
}
int64_t esp_http_client_fetch_headers(esp_http_client_handle_t client)

View File

@@ -266,6 +266,8 @@ typedef enum {
#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 */
#define ESP_ERR_HTTP_READ_TIMEOUT (ESP_ERR_HTTP_BASE + 11) /*!< HTTP data read timeout */
#define ESP_ERR_HTTP_INCOMPLETE_DATA (ESP_ERR_HTTP_BASE + 12) /*!< Incomplete data received, less than Content-Length or last chunk */
/**
* @brief Start a HTTP session
@@ -306,6 +308,9 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
* - ESP_ERR_HTTP_CONNECTING is timed-out before connection is made
* - ESP_ERR_HTTP_WRITE_DATA is timed-out before request fully sent
* - ESP_ERR_HTTP_EAGAIN is timed-out before any data was ready
* - ESP_ERR_HTTP_READ_TIMEOUT if read operation times out
* - ESP_ERR_HTTP_INCOMPLETE_DATA if read operation returns less data than expected
* - ESP_ERR_HTTP_CONNECTION_CLOSED if server closes the connection
*/
esp_err_t esp_http_client_perform(esp_http_client_handle_t client);