forked from espressif/esp-idf
Merge branch 'feature/esp_http_client_esp_events' into 'master'
esp_http_client: Add support for esp_events See merge request espressif/esp-idf!21113
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
if(NOT ${IDF_TARGET} STREQUAL "linux")
|
if(NOT ${IDF_TARGET} STREQUAL "linux")
|
||||||
set(req lwip)
|
set(req lwip esp_event)
|
||||||
|
else()
|
||||||
|
set(req linux)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS "esp_http_client.c"
|
idf_component_register(SRCS "esp_http_client.c"
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
#include "esp_transport_ssl.h"
|
#include "esp_transport_ssl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ESP_EVENT_DEFINE_BASE(ESP_HTTP_CLIENT_EVENT);
|
||||||
|
|
||||||
static const char *TAG = "HTTP_CLIENT";
|
static const char *TAG = "HTTP_CLIENT";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -183,6 +185,14 @@ static esp_err_t http_dispatch_event(esp_http_client_t *client, esp_http_client_
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void http_dispatch_event_to_event_loop(int32_t event_id, const void* event_data, size_t event_data_size)
|
||||||
|
{
|
||||||
|
esp_err_t err = esp_event_post(ESP_HTTP_CLIENT_EVENT, event_id, event_data, event_data_size, portMAX_DELAY);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to post https_ota event: %"PRId32", error: %s", event_id, esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int http_on_message_begin(http_parser *parser)
|
static int http_on_message_begin(http_parser *parser)
|
||||||
{
|
{
|
||||||
esp_http_client_t *client = parser->data;
|
esp_http_client_t *client = parser->data;
|
||||||
@@ -211,6 +221,7 @@ static int http_on_header_event(esp_http_client_handle_t client)
|
|||||||
client->event.header_key = client->current_header_key;
|
client->event.header_key = client->current_header_key;
|
||||||
client->event.header_value = client->current_header_value;
|
client->event.header_value = client->current_header_value;
|
||||||
http_dispatch_event(client, HTTP_EVENT_ON_HEADER, NULL, 0);
|
http_dispatch_event(client, HTTP_EVENT_ON_HEADER, NULL, 0);
|
||||||
|
http_dispatch_event_to_event_loop(HTTP_EVENT_ON_HEADER, &client, sizeof(esp_http_client_handle_t));
|
||||||
free(client->current_header_key);
|
free(client->current_header_key);
|
||||||
free(client->current_header_value);
|
free(client->current_header_value);
|
||||||
client->current_header_key = NULL;
|
client->current_header_key = NULL;
|
||||||
@@ -293,6 +304,10 @@ static int http_on_body(http_parser *parser, const char *at, size_t length)
|
|||||||
client->response->data_process += length;
|
client->response->data_process += length;
|
||||||
client->response->buffer->raw_len += length;
|
client->response->buffer->raw_len += length;
|
||||||
http_dispatch_event(client, HTTP_EVENT_ON_DATA, (void *)at, length);
|
http_dispatch_event(client, HTTP_EVENT_ON_DATA, (void *)at, length);
|
||||||
|
esp_http_client_on_data_t evt_data = {};
|
||||||
|
evt_data.data_process = client->response->data_process;
|
||||||
|
evt_data.client = client;
|
||||||
|
http_dispatch_event_to_event_loop(HTTP_EVENT_ON_DATA, &evt_data, sizeof(esp_http_client_on_data_t));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -891,6 +906,11 @@ static esp_err_t esp_http_check_response(esp_http_client_handle_t client)
|
|||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
esp_http_client_redirect_event_data_t evt_data = {
|
||||||
|
.status_code = client->response->status_code,
|
||||||
|
.client = client,
|
||||||
|
};
|
||||||
|
http_dispatch_event_to_event_loop(HTTP_EVENT_REDIRECT, &evt_data, sizeof(esp_http_client_redirect_event_data_t));
|
||||||
break;
|
break;
|
||||||
case HttpStatus_Unauthorized:
|
case HttpStatus_Unauthorized:
|
||||||
esp_http_client_add_auth(client);
|
esp_http_client_add_auth(client);
|
||||||
@@ -1138,6 +1158,7 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
|
|||||||
|
|
||||||
if (rlen < 0 && ridx == 0 && !esp_http_client_is_complete_data_received(client)) {
|
if (rlen < 0 && ridx == 0 && !esp_http_client_is_complete_data_received(client)) {
|
||||||
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
|
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));
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
return ridx;
|
return ridx;
|
||||||
@@ -1172,6 +1193,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
|||||||
return ESP_ERR_HTTP_EAGAIN;
|
return ESP_ERR_HTTP_EAGAIN;
|
||||||
}
|
}
|
||||||
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
|
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));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
/* falls through */
|
/* falls through */
|
||||||
@@ -1181,6 +1203,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
|||||||
return ESP_ERR_HTTP_EAGAIN;
|
return ESP_ERR_HTTP_EAGAIN;
|
||||||
}
|
}
|
||||||
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
|
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));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
/* falls through */
|
/* falls through */
|
||||||
@@ -1190,6 +1213,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
|||||||
return ESP_ERR_HTTP_EAGAIN;
|
return ESP_ERR_HTTP_EAGAIN;
|
||||||
}
|
}
|
||||||
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
|
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));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
/* falls through */
|
/* falls through */
|
||||||
@@ -1209,9 +1233,11 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
|||||||
ESP_LOGW(TAG, "Close connection due to FIN received");
|
ESP_LOGW(TAG, "Close connection due to FIN received");
|
||||||
esp_http_client_close(client);
|
esp_http_client_close(client);
|
||||||
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
|
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));
|
||||||
return ESP_ERR_HTTP_CONNECTION_CLOSED;
|
return ESP_ERR_HTTP_CONNECTION_CLOSED;
|
||||||
}
|
}
|
||||||
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
|
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));
|
||||||
return ESP_ERR_HTTP_FETCH_HEADER;
|
return ESP_ERR_HTTP_FETCH_HEADER;
|
||||||
}
|
}
|
||||||
/* falls through */
|
/* falls through */
|
||||||
@@ -1222,6 +1248,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
|||||||
if ((err = esp_http_check_response(client)) != ESP_OK) {
|
if ((err = esp_http_check_response(client)) != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Error response");
|
ESP_LOGE(TAG, "Error response");
|
||||||
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
|
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));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
while (client->response->is_chunked && !client->is_chunk_complete) {
|
while (client->response->is_chunked && !client->is_chunk_complete) {
|
||||||
@@ -1243,6 +1270,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
http_dispatch_event(client, HTTP_EVENT_ON_FINISH, NULL, 0);
|
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;
|
client->response->buffer->raw_len = 0;
|
||||||
if (!http_should_keep_alive(client->parser)) {
|
if (!http_should_keep_alive(client->parser)) {
|
||||||
@@ -1340,6 +1368,7 @@ static esp_err_t esp_http_client_connect(esp_http_client_handle_t client)
|
|||||||
}
|
}
|
||||||
client->state = HTTP_STATE_CONNECTED;
|
client->state = HTTP_STATE_CONNECTED;
|
||||||
http_dispatch_event(client, HTTP_EVENT_ON_CONNECTED, NULL, 0);
|
http_dispatch_event(client, HTTP_EVENT_ON_CONNECTED, NULL, 0);
|
||||||
|
http_dispatch_event_to_event_loop(HTTP_EVENT_ON_CONNECTED, &client, sizeof(esp_http_client_handle_t));
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@@ -1439,6 +1468,7 @@ static esp_err_t esp_http_client_request_send(esp_http_client_handle_t client, i
|
|||||||
client->data_written_index = 0;
|
client->data_written_index = 0;
|
||||||
client->data_write_left = client->post_len;
|
client->data_write_left = client->post_len;
|
||||||
http_dispatch_event(client, HTTP_EVENT_HEADERS_SENT, NULL, 0);
|
http_dispatch_event(client, HTTP_EVENT_HEADERS_SENT, NULL, 0);
|
||||||
|
http_dispatch_event_to_event_loop(HTTP_EVENT_HEADERS_SENT, &client, sizeof(esp_http_client_handle_t));
|
||||||
client->state = HTTP_STATE_REQ_COMPLETE_HEADER;
|
client->state = HTTP_STATE_REQ_COMPLETE_HEADER;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@@ -1477,10 +1507,12 @@ esp_err_t esp_http_client_open(esp_http_client_handle_t client, int write_len)
|
|||||||
esp_err_t err;
|
esp_err_t err;
|
||||||
if ((err = esp_http_client_connect(client)) != ESP_OK) {
|
if ((err = esp_http_client_connect(client)) != ESP_OK) {
|
||||||
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
|
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));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if ((err = esp_http_client_request_send(client, write_len)) != ESP_OK) {
|
if ((err = esp_http_client_request_send(client, write_len)) != ESP_OK) {
|
||||||
http_dispatch_event(client, HTTP_EVENT_ERROR, esp_transport_get_error_handle(client->transport), 0);
|
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));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@@ -1510,6 +1542,7 @@ esp_err_t esp_http_client_close(esp_http_client_handle_t client)
|
|||||||
{
|
{
|
||||||
if (client->state >= HTTP_STATE_INIT) {
|
if (client->state >= HTTP_STATE_INIT) {
|
||||||
http_dispatch_event(client, HTTP_EVENT_DISCONNECTED, esp_transport_get_error_handle(client->transport), 0);
|
http_dispatch_event(client, HTTP_EVENT_DISCONNECTED, esp_transport_get_error_handle(client->transport), 0);
|
||||||
|
http_dispatch_event_to_event_loop(HTTP_EVENT_DISCONNECTED, &client, sizeof(esp_http_client_handle_t));
|
||||||
client->state = HTTP_STATE_INIT;
|
client->state = HTTP_STATE_INIT;
|
||||||
return esp_transport_close(client->transport);
|
return esp_transport_close(client->transport);
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,9 @@ extern "C" {
|
|||||||
|
|
||||||
#define DEFAULT_HTTP_BUF_SIZE (512)
|
#define DEFAULT_HTTP_BUF_SIZE (512)
|
||||||
|
|
||||||
|
#include "esp_event.h"
|
||||||
|
ESP_EVENT_DECLARE_BASE(ESP_HTTP_CLIENT_EVENT);
|
||||||
|
|
||||||
typedef struct esp_http_client *esp_http_client_handle_t;
|
typedef struct esp_http_client *esp_http_client_handle_t;
|
||||||
typedef struct esp_http_client_event *esp_http_client_event_handle_t;
|
typedef struct esp_http_client_event *esp_http_client_event_handle_t;
|
||||||
|
|
||||||
@@ -50,6 +53,21 @@ typedef struct esp_http_client_event {
|
|||||||
char *header_value; /*!< For HTTP_EVENT_ON_HEADER event_id, it's store current http header value */
|
char *header_value; /*!< For HTTP_EVENT_ON_HEADER event_id, it's store current http header value */
|
||||||
} esp_http_client_event_t;
|
} esp_http_client_event_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Argument structure for HTTP_EVENT_ON_DATA event
|
||||||
|
*/
|
||||||
|
typedef struct esp_http_client_on_data {
|
||||||
|
esp_http_client_handle_t client; /*!< Client handle */
|
||||||
|
int64_t data_process; /*!< Total data processed */
|
||||||
|
} esp_http_client_on_data_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Argument structure for HTTP_EVENT_REDIRECT event
|
||||||
|
*/
|
||||||
|
typedef struct esp_http_client_redirect_event_data {
|
||||||
|
esp_http_client_handle_t client; /*!< Client handle */
|
||||||
|
int status_code; /*!< Status Code */
|
||||||
|
} esp_http_client_redirect_event_data_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HTTP Client transport
|
* @brief HTTP Client transport
|
||||||
|
@@ -3,5 +3,6 @@ if(NOT "${target}" STREQUAL "linux")
|
|||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
idf_component_register(INCLUDE_DIRS include
|
idf_component_register(SRCS esp_event_stubs.c
|
||||||
|
INCLUDE_DIRS include ${IDF_PATH}/components/esp_event/include
|
||||||
REQUIRED_IDF_TARGETS linux)
|
REQUIRED_IDF_TARGETS linux)
|
||||||
|
18
components/linux/esp_event_stubs.c
Normal file
18
components/linux/esp_event_stubs.c
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
|
||||||
|
esp_err_t esp_event_loop_create_default(void)
|
||||||
|
{
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_event_post(esp_event_base_t event_base, int32_t event_id,
|
||||||
|
const void* event_data, size_t event_data_size, TickType_t ticks_to_wait)
|
||||||
|
{
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
@@ -110,6 +110,33 @@ Examples of Authentication Configuration
|
|||||||
.auth_type = HTTP_AUTH_TYPE_BASIC,
|
.auth_type = HTTP_AUTH_TYPE_BASIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Event Handling
|
||||||
|
--------------
|
||||||
|
|
||||||
|
ESP HTTP Client supports event handling by triggering an event handler corresponding to the event which took place.
|
||||||
|
:cpp:enum:`esp_http_client_event_id_t` contains all the events which could occur while performing an HTTP request using the ESP HTTP Client.
|
||||||
|
|
||||||
|
To enable event handling, you just need to set a callback function using the :cpp:member:`esp_http_client_config_t::event_handler` member.
|
||||||
|
|
||||||
|
ESP HTTP Client Diagnostic Information
|
||||||
|
--------------------------------------
|
||||||
|
Diagnostic information could be helpful to gain insights into a problem. In the case of ESP HTTP Client, this diagnostic information can be collected by registering an event handler with :doc:`the Event Loop library <../system/esp_event>`.
|
||||||
|
This feature has been added by keeping in mind the `ESP Insights <https://github.com/espressif/esp-insights>`_ framework which collects the diagnostic information. However, this feature can also be used without any dependency on ESP Insights framework for the diagnostic purpose.
|
||||||
|
Event handler can be registered to the event loop using the :cpp:func:`esp_event_handler_register` function.
|
||||||
|
|
||||||
|
Expected data types for different HTTP Client events in the event loop:
|
||||||
|
|
||||||
|
- HTTP_EVENT_ERROR : ``esp_http_client_handle_t``
|
||||||
|
- HTTP_EVENT_ON_CONNECTED : ``esp_http_client_handle_t``
|
||||||
|
- HTTP_EVENT_HEADERS_SENT : ``esp_http_client_handle_t``
|
||||||
|
- HTTP_EVENT_ON_HEADER : ``esp_http_client_handle_t``
|
||||||
|
- HTTP_EVENT_ON_DATA : ``esp_http_client_on_data_t``
|
||||||
|
- HTTP_EVENT_ON_FINISH : ``esp_http_client_handle_t``
|
||||||
|
- HTTP_EVENT_DISCONNECTED : ``esp_http_client_handle_t``
|
||||||
|
- HTTP_EVENT_REDIRECT : ``esp_http_client_redirect_event_data_t``
|
||||||
|
|
||||||
|
The :cpp:type:`esp_http_client_handle_t` received along with the event data will be valid until :cpp:enumerator:`HTTP_EVENT_DISCONNECTED <esp_http_client_event_id_t::HTTP_EVENT_DISCONNECTED>` is not received. This handle has been sent primarily to differentiate between different client
|
||||||
|
connections and must not be used for any other purpose (as it may change based on client connection state).
|
||||||
|
|
||||||
API Reference
|
API Reference
|
||||||
-------------
|
-------------
|
||||||
|
@@ -6,14 +6,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
|
||||||
extern void app_main(void);
|
extern void app_main(void);
|
||||||
|
|
||||||
esp_err_t esp_event_loop_create_default(void)
|
|
||||||
{
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t esp_netif_init(void)
|
esp_err_t esp_netif_init(void)
|
||||||
{
|
{
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
Reference in New Issue
Block a user