mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 10:00:57 +02:00
Merge branch 'fix/handle_error_and_dispatch_event_while_reading_data_from_server_v5.4' into 'release/v5.4'
feat(esp_http_client): handle error while reading data from server (v5.4) See merge request espressif/esp-idf!41325
This commit is contained in:
@@ -656,6 +656,20 @@ static const esp_err_msg_t esp_err_msg_table[] = {
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTP_CONNECTION_CLOSED
|
||||
ERR_TBL_IT(ESP_ERR_HTTP_CONNECTION_CLOSED), /* 28680 0x7008 Read FIN from peer and the connection closed */
|
||||
# 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
|
||||
# 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
|
||||
|
@@ -1334,7 +1334,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);
|
||||
@@ -1409,25 +1409,55 @@ 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, "Incomplete 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;
|
||||
}
|
||||
}
|
||||
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));
|
||||
|
||||
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));
|
||||
} else {
|
||||
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));
|
||||
}
|
||||
|
||||
client->response->buffer->raw_len = 0;
|
||||
if (!http_should_keep_alive(client->parser)) {
|
||||
@@ -1440,11 +1470,12 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
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)
|
||||
|
@@ -40,7 +40,7 @@ typedef enum {
|
||||
and will be deprecated in future versions esp-idf */
|
||||
HTTP_EVENT_ON_HEADER, /*!< Occurs when receiving each header sent from the server */
|
||||
HTTP_EVENT_ON_DATA, /*!< Occurs when receiving data from the server, possibly multiple portions of the packet */
|
||||
HTTP_EVENT_ON_FINISH, /*!< Occurs when finish a HTTP session */
|
||||
HTTP_EVENT_ON_FINISH, /*!< Occurs when complete data is received */
|
||||
HTTP_EVENT_DISCONNECTED, /*!< The connection has been disconnected */
|
||||
HTTP_EVENT_REDIRECT, /*!< Intercepting HTTP redirects to handle them manually */
|
||||
} esp_http_client_event_id_t;
|
||||
@@ -245,6 +245,10 @@ typedef enum {
|
||||
#define ESP_ERR_HTTP_CONNECTING (ESP_ERR_HTTP_BASE + 6) /*!< HTTP connection hasn't been established yet */
|
||||
#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 */
|
||||
#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
|
||||
@@ -282,6 +286,12 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
|
||||
* @return
|
||||
* - ESP_OK on successful
|
||||
* - ESP_FAIL on error
|
||||
* - 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);
|
||||
|
||||
|
Reference in New Issue
Block a user