From 7188eaaebfdc1d11c75ee29e00e1fce14f873dc8 Mon Sep 17 00:00:00 2001 From: Clickau Date: Thu, 7 Jan 2021 13:47:22 +0200 Subject: [PATCH 1/2] 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 8d008d6195..336a8089b7 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 * From c764c5989300e3c031b056d2e2e8d6ee9d20bf25 Mon Sep 17 00:00:00 2001 From: yuanjm Date: Sun, 7 Feb 2021 11:37:49 +0800 Subject: [PATCH 2/2] esp_http_client: Optimize code structure --- components/esp_http_client/esp_http_client.c | 23 +++++-------- components/esp_http_client/lib/http_utils.c | 34 +++++++++---------- .../esp_http_client/lib/include/http_utils.h | 11 +++--- 3 files changed, 30 insertions(+), 38 deletions(-) diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c index 336a8089b7..9c8c93c792 100644 --- a/components/esp_http_client/esp_http_client.c +++ b/components/esp_http_client/esp_http_client.c @@ -196,10 +196,8 @@ static int http_on_status(http_parser *parser, const char *at, size_t length) return 0; } -static int http_on_header_field(http_parser *parser, const char *at, size_t length) +static int http_on_header_event(esp_http_client_handle_t client) { - esp_http_client_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; @@ -210,7 +208,13 @@ static int http_on_header_field(http_parser *parser, const char *at, size_t leng client->current_header_key = NULL; client->current_header_value = NULL; } + return 0; +} +static int http_on_header_field(http_parser *parser, const char *at, size_t length) +{ + esp_http_client_t *client = parser->data; + http_on_header_event(client); http_utils_append_string(&client->current_header_key, at, length); return 0; @@ -237,18 +241,7 @@ static int http_on_header_value(http_parser *parser, const char *at, size_t leng 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; - } - + http_on_header_event(client); 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 9a4a5adc88..c6f2a79cee 100644 --- a/components/esp_http_client/lib/http_utils.c +++ b/components/esp_http_client/lib/http_utils.c @@ -63,25 +63,25 @@ char *http_utils_assign_string(char **str, const char *new_str, int len) char *http_utils_append_string(char **str, const char *new_str, int len) { - if (new_str == NULL) { - return NULL; - } + int l = len; + int old_len = 0; char *old_str = *str; - if (len <= 0) { - len = strlen(new_str); + if (new_str != NULL) { + if (l < 0) { + l = strlen(new_str); + } + if (old_str) { + old_len = strlen(old_str); + old_str = realloc(old_str, old_len + l + 1); + mem_check(old_str); + old_str[old_len + l] = 0; + } else { + old_str = calloc(1, l + 1); + mem_check(old_str); + } + memcpy(old_str + old_len, new_str, l); + *str = old_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; } diff --git a/components/esp_http_client/lib/include/http_utils.h b/components/esp_http_client/lib/include/http_utils.h index e7a21f5810..2f0f11cc5c 100644 --- a/components/esp_http_client/lib/include/http_utils.h +++ b/components/esp_http_client/lib/include/http_utils.h @@ -22,7 +22,7 @@ * * @param str pointer to string pointer * @param new_str assign this tring to str - * @param len length of string, 0 if new_str is zero terminated + * @param len length of string, less than 0 if new_str is zero terminated * * @return * - new_str pointer @@ -31,15 +31,14 @@ 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 + * @brief Realloc *str and append new_str to it if new_str is not NULL; return *str pointer if new_str is 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 + * @param new_str append this string to str + * @param len length of string, less than 0 if new_str is zero terminated * * @return - * - new_str pointer - * - NULL + * - *str pointer */ char *http_utils_append_string(char **str, const char *new_str, int len);