mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
esp_http_client: Add support for esp_events
This commit is contained in:
parent
745c06626d
commit
674fd8feb8
@ -1,5 +1,7 @@
|
||||
if(NOT ${IDF_TARGET} STREQUAL "linux")
|
||||
set(req lwip)
|
||||
set(req lwip esp_event)
|
||||
else()
|
||||
set(req esp_stubs)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "esp_http_client.c"
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "esp_transport_ssl.h"
|
||||
#endif
|
||||
|
||||
ESP_EVENT_DEFINE_BASE(ESP_HTTP_CLIENT_EVENT);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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_value = client->current_header_value;
|
||||
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_value);
|
||||
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->buffer->raw_len += 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;
|
||||
}
|
||||
|
||||
@ -891,6 +906,11 @@ static esp_err_t esp_http_check_response(esp_http_client_handle_t client)
|
||||
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;
|
||||
case HttpStatus_Unauthorized:
|
||||
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)) {
|
||||
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 ridx;
|
||||
@ -1172,6 +1193,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
||||
return ESP_ERR_HTTP_EAGAIN;
|
||||
}
|
||||
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;
|
||||
}
|
||||
/* falls through */
|
||||
@ -1181,6 +1203,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
||||
return ESP_ERR_HTTP_EAGAIN;
|
||||
}
|
||||
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;
|
||||
}
|
||||
/* falls through */
|
||||
@ -1190,6 +1213,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
||||
return ESP_ERR_HTTP_EAGAIN;
|
||||
}
|
||||
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;
|
||||
}
|
||||
/* 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_http_client_close(client);
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
/* 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) {
|
||||
ESP_LOGE(TAG, "Error response");
|
||||
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;
|
||||
}
|
||||
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_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)) {
|
||||
@ -1340,6 +1368,7 @@ static esp_err_t esp_http_client_connect(esp_http_client_handle_t client)
|
||||
}
|
||||
client->state = HTTP_STATE_CONNECTED;
|
||||
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;
|
||||
}
|
||||
@ -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_write_left = client->post_len;
|
||||
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;
|
||||
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;
|
||||
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_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
|
||||
return err;
|
||||
}
|
||||
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_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
|
||||
return err;
|
||||
}
|
||||
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) {
|
||||
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;
|
||||
return esp_transport_close(client->transport);
|
||||
}
|
||||
|
@ -18,6 +18,9 @@ extern "C" {
|
||||
|
||||
#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_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 */
|
||||
} 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
|
||||
|
@ -110,6 +110,33 @@ Examples of Authentication Configuration
|
||||
.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
|
||||
-------------
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <stdlib.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_event.h"
|
||||
|
||||
extern void app_main(void);
|
||||
|
||||
@ -14,6 +15,12 @@ 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;
|
||||
}
|
||||
|
||||
esp_err_t esp_netif_init(void)
|
||||
{
|
||||
return ESP_OK;
|
||||
|
@ -5,4 +5,13 @@
|
||||
*/
|
||||
#include "esp_err.h"
|
||||
|
||||
typedef const char* esp_event_base_t; /**< unique pointer to a subsystem that exposes events */
|
||||
typedef unsigned long TickType_t;
|
||||
|
||||
#define ESP_EVENT_DECLARE_BASE(id) extern esp_event_base_t id
|
||||
#define ESP_EVENT_DEFINE_BASE(id) esp_event_base_t id = #id
|
||||
|
||||
esp_err_t esp_event_loop_create_default(void);
|
||||
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user