feat(esp_http_client): Event to signal last header download

When parsing ND-JSON streams, this is needed to indicate the
point when the ND-JSON stream is considered open, which
occurs just after the last HTTP_EVENT_ON_HEADER.

ND-JSON stream clients cannot rely on the first HTTP_EVENT_ON_DATA,
since that is only triggered by an event, which are optional and
may never be sent, or only sent well after the last HTTP_EVENT_ON_HEADER.

Closes #15952
This commit is contained in:
Richard Allen
2025-05-16 12:54:15 -05:00
parent a74725a31b
commit 30758d9beb
9 changed files with 36 additions and 16 deletions

View File

@@ -623,6 +623,9 @@ esp_err_t http_event_handle(esp_http_client_event_t *evt)
case HTTP_EVENT_ON_HEADER:
ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER");
break;
case HTTP_EVENT_ON_HEADERS_COMPLETE:
ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADERS_COMPLETE");
break;
case HTTP_EVENT_ON_DATA:
esp_rom_md5_update(&md5_context, evt->data, evt->data_len);
break;

View File

@@ -289,6 +289,8 @@ static int http_on_headers_complete(http_parser *parser)
client->response->data_process = 0;
ESP_LOGD(TAG, "http_on_headers_complete, status=%d, offset=%d, nread=%" PRId32, parser->status_code, client->response->data_offset, parser->nread);
client->state = HTTP_STATE_RES_COMPLETE_HEADER;
http_dispatch_event(client, HTTP_EVENT_ON_HEADERS_COMPLETE, NULL, 0);
http_dispatch_event_to_event_loop(HTTP_EVENT_ON_HEADERS_COMPLETE, &client, sizeof(esp_http_client_handle_t));
if (client->connection_info.method == HTTP_METHOD_HEAD) {
/* In a HTTP_RESPONSE parser returning '1' from on_headers_complete will tell the
parser that it should not expect a body. This is used when receiving a response

View File

@@ -39,6 +39,7 @@ typedef enum {
HTTP_EVENT_HEADER_SENT = HTTP_EVENT_HEADERS_SENT, /*!< This header has been kept for backward compatibility
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_HEADERS_COMPLETE, /*!< Occurs when all headers are received on the client side */
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_DISCONNECTED, /*!< The connection has been disconnected */

View File

@@ -126,14 +126,15 @@ Diagnostic information could be helpful to gain insights into a problem. In the
Expected data types for different HTTP Client events in the event loop are as follows:
- 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``
- 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_HEADERS_COMPLETE: ``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.

View File

@@ -126,14 +126,15 @@ ESP HTTP 客户端诊断信息
事件循环中不同 HTTP 客户端事件的预期数据类型如下所示:
- 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``
- 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_HEADERS_COMPLETE: ``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``
在无法接收到 :cpp:enumerator:`HTTP_EVENT_DISCONNECTED <esp_http_client_event_id_t::HTTP_EVENT_DISCONNECTED>` 之前,与事件数据一起接收到的 :cpp:type:`esp_http_client_handle_t` 将始终有效。这个句柄主要是为了区分不同的客户端连接,无法用于其他目的,因为它可能会随着客户端连接状态的变化而改变。

View File

@@ -74,6 +74,9 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
case HTTP_EVENT_ON_HEADER:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_HEADERS_COMPLETE:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADERS_COMPLETE");
break;
case HTTP_EVENT_ON_DATA:
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
/* Check if buffer is null, if yes, initialize it */

View File

@@ -65,6 +65,9 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
case HTTP_EVENT_ON_HEADER:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_HEADERS_COMPLETE:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADERS_COMPLETE");
break;
case HTTP_EVENT_ON_DATA:
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
// Clean the buffer in case of a new request

View File

@@ -68,6 +68,9 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
case HTTP_EVENT_ON_HEADER:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_HEADERS_COMPLETE:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADERS_COMPLETE");
break;
case HTTP_EVENT_ON_DATA:
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
break;

View File

@@ -60,6 +60,9 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
case HTTP_EVENT_ON_HEADER:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_HEADERS_COMPLETE:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADERS_COMPLETE");
break;
case HTTP_EVENT_ON_DATA:
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
break;