mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(esp_http_client): adds support to save response headers
Closes https://github.com/espressif/esp-idf/issues/17695
This commit is contained in:
@@ -48,4 +48,29 @@ menu "ESP HTTP client"
|
||||
default y
|
||||
help
|
||||
Migrate ESP HTTP Client to use PSA Crypto.
|
||||
|
||||
config ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
bool "Save response headers"
|
||||
default n
|
||||
help
|
||||
This option will enable saving of response headers in esp_http_client component.
|
||||
When enabled, upto ESP_HTTP_CLIENT_MAX_SAVED_RESPONSE_HEADERS headers are saved.
|
||||
Enabling this option will increase the memory footprint of the component.
|
||||
|
||||
config ESP_HTTP_CLIENT_MAX_SAVED_RESPONSE_HEADERS
|
||||
depends on ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
int "Maximum number of response headers"
|
||||
default 10
|
||||
help
|
||||
This config option helps in setting the maximum number of response headers that
|
||||
can be saved in esp_http_client component.
|
||||
|
||||
config ESP_HTTP_CLIENT_MAX_RESPONSE_HEADER_SIZE
|
||||
depends on ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
int "Maximum size of response header"
|
||||
default 128
|
||||
help
|
||||
This config option helps in setting the maximum size of response header that
|
||||
can be saved in esp_http_client component.
|
||||
Note that the same size is used for key and value in the response headers.
|
||||
endmenu
|
||||
|
||||
@@ -60,6 +60,9 @@ typedef struct {
|
||||
*/
|
||||
typedef struct {
|
||||
http_header_handle_t headers; /*!< http header */
|
||||
#if CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
int saved_response_header_count;
|
||||
#endif // CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
esp_http_buffer_t *buffer; /*!< data buffer as linked list */
|
||||
int status_code; /*!< status code (integer) */
|
||||
int64_t content_length; /*!< data length */
|
||||
@@ -249,6 +252,23 @@ static int http_on_header_event(esp_http_client_handle_t client)
|
||||
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));
|
||||
|
||||
#if CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
if (client->response->saved_response_header_count >= CONFIG_ESP_HTTP_CLIENT_MAX_SAVED_RESPONSE_HEADERS) {
|
||||
ESP_LOGW(TAG, "Response header limit (%d) exceeded", CONFIG_ESP_HTTP_CLIENT_MAX_SAVED_RESPONSE_HEADERS);
|
||||
} else {
|
||||
if (strlen(client->current_header_key) > CONFIG_ESP_HTTP_CLIENT_MAX_RESPONSE_HEADER_SIZE ||
|
||||
strlen(client->current_header_value) > CONFIG_ESP_HTTP_CLIENT_MAX_RESPONSE_HEADER_SIZE) {
|
||||
ESP_LOGW(TAG, "Header '%s' exceeds max size (%d): key=%zu, value=%zu",
|
||||
client->current_header_key, CONFIG_ESP_HTTP_CLIENT_MAX_RESPONSE_HEADER_SIZE,
|
||||
strlen(client->current_header_key), strlen(client->current_header_value));
|
||||
} else {
|
||||
http_header_set(client->response->headers, client->current_header_key, client->current_header_value);
|
||||
client->response->saved_response_header_count++;
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
|
||||
free(client->current_header_key);
|
||||
free(client->current_header_value);
|
||||
client->current_header_key = NULL;
|
||||
@@ -409,6 +429,17 @@ esp_err_t esp_http_client_get_header(esp_http_client_handle_t client, const char
|
||||
return http_header_get(client->request->headers, key, value);
|
||||
}
|
||||
|
||||
#if CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
esp_err_t esp_http_client_get_response_header(esp_http_client_handle_t client, const char *key, char **value)
|
||||
{
|
||||
if (client == NULL || client->response == NULL || client->response->headers == NULL || key == NULL || value == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return http_header_get(client->response->headers, key, value);
|
||||
}
|
||||
#endif // CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
|
||||
esp_err_t esp_http_client_delete_header(esp_http_client_handle_t client, const char *key)
|
||||
{
|
||||
if (client == NULL || client->request == NULL || client->request->headers == NULL || key == NULL) {
|
||||
@@ -725,6 +756,12 @@ esp_err_t esp_http_client_prepare(esp_http_client_handle_t client)
|
||||
free(client->auth_header);
|
||||
client->auth_header = NULL;
|
||||
}
|
||||
#if CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
if (client->response->headers != NULL) {
|
||||
http_header_clean(client->response->headers);
|
||||
}
|
||||
client->response->saved_response_header_count = 0;
|
||||
#endif // CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
http_parser_init(client->parser, HTTP_RESPONSE);
|
||||
if (client->connection_info.username) {
|
||||
if (client->connection_info.auth_type == HTTP_AUTH_TYPE_BASIC) {
|
||||
@@ -817,7 +854,9 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
|
||||
(client->request->headers = http_header_init()) &&
|
||||
(client->request->buffer = calloc(1, sizeof(esp_http_buffer_t))) &&
|
||||
(client->response = calloc(1, sizeof(esp_http_data_t))) &&
|
||||
#if CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
(client->response->headers = http_header_init()) &&
|
||||
#endif // CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
(client->response->buffer = calloc(1, sizeof(esp_http_buffer_t)))
|
||||
);
|
||||
|
||||
@@ -1068,7 +1107,9 @@ esp_err_t esp_http_client_cleanup(esp_http_client_handle_t client)
|
||||
free(client->request);
|
||||
}
|
||||
if (client->response) {
|
||||
#if CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
http_header_destroy(client->response->headers);
|
||||
#endif // CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
if (client->response->buffer) {
|
||||
free(client->response->buffer->data);
|
||||
esp_http_client_cached_buf_cleanup(client->response->buffer);
|
||||
@@ -1451,6 +1492,9 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
|
||||
http_dispatch_event_to_event_loop(HTTP_EVENT_ERROR, &client, sizeof(esp_http_client_handle_t));
|
||||
return err;
|
||||
}
|
||||
#if CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
client->response->saved_response_header_count = 0;
|
||||
#endif // CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS
|
||||
/* falls through */
|
||||
case HTTP_STATE_REQ_COMPLETE_HEADER:
|
||||
if ((err = esp_http_client_send_post_data(client)) != ESP_OK) {
|
||||
|
||||
@@ -444,11 +444,37 @@ esp_err_t esp_http_client_set_header(esp_http_client_handle_t client, const char
|
||||
* @param[out] value The header value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
* - ESP_OK: Header found
|
||||
* - ESP_ERR_INVALID_ARG: Invalid arguments
|
||||
* - ESP_ERR_NOT_FOUND: Header not found
|
||||
*/
|
||||
esp_err_t esp_http_client_get_header(esp_http_client_handle_t client, const char *key, char **value);
|
||||
|
||||
#if CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS || __DOXYGEN__
|
||||
/**
|
||||
* @brief Get a response header value by key
|
||||
* The value parameter will be set to NULL if there is no header which is same as
|
||||
* the key specified, otherwise the address of header value will be assigned to value parameter.
|
||||
* This function must be called after `esp_http_client_init`.
|
||||
*
|
||||
* @note Limitations:
|
||||
* - Only first CONFIG_ESP_HTTP_CLIENT_MAX_SAVED_RESPONSE_HEADERS (default: 10) headers are saved
|
||||
* - Headers exceeding CONFIG_ESP_HTTP_CLIENT_MAX_RESPONSE_HEADER_SIZE (default: 128) bytes are discarded
|
||||
* - Multi-value headers (e.g., Set-Cookie) only retain the last value
|
||||
* - Headers are case-insensitive for lookup but case-preserving for storage
|
||||
*
|
||||
* @param[in] client The esp_http_client handle
|
||||
* @param[in] key The header key
|
||||
* @param[out] value Pointer to store the header value. This pointer should not be freed by the user.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Header found
|
||||
* - ESP_ERR_INVALID_ARG: Invalid arguments
|
||||
* - ESP_ERR_NOT_FOUND: Header not found
|
||||
*/
|
||||
esp_err_t esp_http_client_get_response_header(esp_http_client_handle_t client, const char *key, char **value);
|
||||
#endif // CONFIG_ESP_HTTP_CLIENT_SAVE_RESPONSE_HEADERS || __DOXYGEN__
|
||||
|
||||
/**
|
||||
* @brief Get http request username.
|
||||
* The address of username buffer will be assigned to value parameter.
|
||||
|
||||
@@ -69,6 +69,7 @@ esp_err_t http_header_get(http_header_handle_t header, const char *key, char **v
|
||||
*value = item->value;
|
||||
} else {
|
||||
*value = NULL;
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
@@ -63,7 +63,7 @@ esp_err_t http_header_destroy(http_header_handle_t header);
|
||||
esp_err_t http_header_set(http_header_handle_t header, const char *key, const char *value);
|
||||
|
||||
/**
|
||||
* @brief Sample as `http_header_set` but the value can be formated
|
||||
* @brief Sample as `http_header_set` but the value can be formatted
|
||||
*
|
||||
* @param[in] header The header
|
||||
* @param[in] key The key
|
||||
@@ -84,7 +84,7 @@ int http_header_set_format(http_header_handle_t header, const char *key, const c
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
* - ESP_ERR_NOT_FOUND
|
||||
*/
|
||||
esp_err_t http_header_get(http_header_handle_t header, const char *key, char **value);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user