Преглед изворни кода

Merge branch 'bugfix/fix_truncated_headers_for_esp_http_client' into 'master'

esp_http_client: Fix header truncated when responded header length over buffer_size

Closes IDFGH-4315

See merge request espressif/esp-idf!12327
Mahavir Jain пре 5 година
родитељ
комит
d8f2a57154

+ 21 - 13
components/esp_http_client/esp_http_client.c

@@ -206,10 +206,26 @@ static int http_on_status(http_parser *parser, const char *at, size_t length)
     return 0;
     return 0;
 }
 }
 
 
+static int http_on_header_event(esp_http_client_handle_t client)
+{
+    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;
+    }
+    return 0;
+}
+
 static int http_on_header_field(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;
     esp_http_client_t *client = parser->data;
-    http_utils_assign_string(&client->current_header_key, at, length);
+    http_on_header_event(client);
+    http_utils_append_string(&client->current_header_key, at, length);
 
 
     return 0;
     return 0;
 }
 }
@@ -221,29 +237,21 @@ static int http_on_header_value(http_parser *parser, const char *at, size_t leng
         return 0;
         return 0;
     }
     }
     if (strcasecmp(client->current_header_key, "Location") == 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
     } else if (strcasecmp(client->current_header_key, "Transfer-Encoding") == 0
                && memcmp(at, "chunked", length) == 0) {
                && memcmp(at, "chunked", length) == 0) {
         client->response->is_chunked = true;
         client->response->is_chunked = true;
     } else if (strcasecmp(client->current_header_key, "WWW-Authenticate") == 0) {
     } 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;
     return 0;
 }
 }
 
 
 static int http_on_headers_complete(http_parser *parser)
 static int http_on_headers_complete(http_parser *parser)
 {
 {
     esp_http_client_handle_t client = parser->data;
     esp_http_client_handle_t client = parser->data;
+    http_on_header_event(client);
     client->response->status_code = parser->status_code;
     client->response->status_code = parser->status_code;
     client->response->data_offset = parser->nread;
     client->response->data_offset = parser->nread;
     client->response->content_length = parser->content_length;
     client->response->content_length = parser->content_length;

+ 24 - 0
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;
     return old_str;
 }
 }
 
 
+char *http_utils_append_string(char **str, const char *new_str, int len)
+{
+    int l = len;
+    int old_len = 0;
+    char *old_str = *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;
+    }
+    return old_str;
+}
+
 void http_utils_trim_whitespace(char **str)
 void http_utils_trim_whitespace(char **str)
 {
 {
     char *end, *start;
     char *end, *start;

+ 13 - 1
components/esp_http_client/lib/include/http_utils.h

@@ -22,7 +22,7 @@
  *
  *
  * @param      str      pointer to string pointer
  * @param      str      pointer to string pointer
  * @param      new_str  assign this tring to str
  * @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
  * @return
  *  - new_str pointer
  *  - new_str pointer
@@ -30,6 +30,18 @@
  */
  */
 char *http_utils_assign_string(char **str, const char *new_str, int len);
 char *http_utils_assign_string(char **str, const char *new_str, int len);
 
 
+/**
+ * @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  append this string to str
+ * @param      len      length of string, less than 0 if new_str is zero terminated
+ *
+ * @return
+ *  - *str pointer
+ */
+char *http_utils_append_string(char **str, const char *new_str, int len);
+
 /**
 /**
  * @brief      Remove white space at begin and end of string
  * @brief      Remove white space at begin and end of string
  *
  *