From e662ecb957e77e454e6ec3b463c324acd8614f98 Mon Sep 17 00:00:00 2001 From: Clickau Date: Thu, 7 Jan 2021 13:47:22 +0200 Subject: [PATCH] esp_http_client: fix truncated headers Signed-off-by: yuanjm Merges https://github.com/espressif/esp-idf/pull/6370 --- components/esp_http_client/esp_http_client.c | 41 +++++++++++++------ components/esp_http_client/lib/http_utils.c | 24 +++++++++++ .../esp_http_client/lib/include/http_utils.h | 13 ++++++ 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c index 5e819d7521..87f3f35685 100644 --- a/components/esp_http_client/esp_http_client.c +++ b/components/esp_http_client/esp_http_client.c @@ -199,7 +199,19 @@ static int http_on_status(http_parser *parser, const char *at, size_t length) static int http_on_header_field(http_parser *parser, const char *at, size_t length) { esp_http_client_t *client = parser->data; - http_utils_assign_string(&client->current_header_key, at, length); + + if (client->current_header_key != NULL && client->current_header_value != NULL) { + ESP_LOGD(TAG, "HEADER=%s:%s", client->current_header_key, client->current_header_value); + 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); + free(client->current_header_key); + free(client->current_header_value); + client->current_header_key = NULL; + client->current_header_value = NULL; + } + + http_utils_append_string(&client->current_header_key, at, length); return 0; } @@ -211,29 +223,32 @@ static int http_on_header_value(http_parser *parser, const char *at, size_t leng return 0; } if (strcasecmp(client->current_header_key, "Location") == 0) { - http_utils_assign_string(&client->location, at, length); + http_utils_append_string(&client->location, at, length); } else if (strcasecmp(client->current_header_key, "Transfer-Encoding") == 0 && memcmp(at, "chunked", length) == 0) { client->response->is_chunked = true; } else if (strcasecmp(client->current_header_key, "WWW-Authenticate") == 0) { - http_utils_assign_string(&client->auth_header, at, length); + http_utils_append_string(&client->auth_header, at, length); } - http_utils_assign_string(&client->current_header_value, at, length); - - ESP_LOGD(TAG, "HEADER=%s:%s", client->current_header_key, client->current_header_value); - 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); - free(client->current_header_key); - free(client->current_header_value); - client->current_header_key = NULL; - client->current_header_value = NULL; + http_utils_append_string(&client->current_header_value, at, length); return 0; } static int http_on_headers_complete(http_parser *parser) { esp_http_client_handle_t client = parser->data; + + if (client->current_header_key != NULL && client->current_header_value != NULL) { + ESP_LOGD(TAG, "HEADER=%s:%s", client->current_header_key, client->current_header_value); + 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); + free(client->current_header_key); + free(client->current_header_value); + client->current_header_key = NULL; + client->current_header_value = NULL; + } + client->response->status_code = parser->status_code; client->response->data_offset = parser->nread; client->response->content_length = parser->content_length; diff --git a/components/esp_http_client/lib/http_utils.c b/components/esp_http_client/lib/http_utils.c index 267e39e6d6..9a4a5adc88 100644 --- a/components/esp_http_client/lib/http_utils.c +++ b/components/esp_http_client/lib/http_utils.c @@ -61,6 +61,30 @@ char *http_utils_assign_string(char **str, const char *new_str, int len) return old_str; } +char *http_utils_append_string(char **str, const char *new_str, int len) +{ + if (new_str == NULL) { + return NULL; + } + char *old_str = *str; + if (len <= 0) { + len = strlen(new_str); + } + if (old_str) { + int old_len = strlen(old_str); + old_str = realloc(old_str, old_len + len + 1); + mem_check(old_str); + memcpy(old_str + old_len, new_str, len); + old_str[old_len + len] = 0; + } else { + old_str = calloc(1, len + 1); + mem_check(old_str); + memcpy(old_str, new_str, len); + } + *str = old_str; + return old_str; +} + void http_utils_trim_whitespace(char **str) { char *end, *start; diff --git a/components/esp_http_client/lib/include/http_utils.h b/components/esp_http_client/lib/include/http_utils.h index 14c3b10c4e..e7a21f5810 100644 --- a/components/esp_http_client/lib/include/http_utils.h +++ b/components/esp_http_client/lib/include/http_utils.h @@ -30,6 +30,19 @@ */ char *http_utils_assign_string(char **str, const char *new_str, int len); +/** + * @brief Realloc *str and append new_str to it, if not NULL; assign new_str to *str pointer if NULL + * + * @param str pointer to string pointer + * @param new_str assign this string to str + * @param len length of string, 0 if new_str is zero terminated + * + * @return + * - new_str pointer + * - NULL + */ +char *http_utils_append_string(char **str, const char *new_str, int len); + /** * @brief Remove white space at begin and end of string *