Преглед на файлове

esp_http_client: fixed http chunked encoding packet loss & add check data before read for ssl transport
- A bug of the http client when it downloads a chunked encoding packet is greater than the http_client's buffer, http_parser will call the callback body more than once, and the client will only handle the last
- with ssl_read, need to check before read to avoid timeout blocked when no data for reading

Tuan преди 7 години
родител
ревизия
5589954800
променени са 2 файла, в които са добавени 18 реда и са изтрити 11 реда
  1. 12 7
      components/esp_http_client/esp_http_client.c
  2. 6 4
      components/esp_http_client/lib/transport_ssl.c

+ 12 - 7
components/esp_http_client/esp_http_client.c

@@ -38,6 +38,7 @@ typedef struct {
     int len;
     char *raw_data;
     int raw_len;
+    char *output_ptr;
 } esp_http_buffer_t;
 /**
  * private HTTP Data structure
@@ -232,9 +233,14 @@ static int http_on_body(http_parser *parser, const char *at, size_t length)
 {
     esp_http_client_t *client = parser->data;
     ESP_LOGD(TAG, "http_on_body %d", length);
-    client->response->buffer->raw_data = (char*)at;
-    client->response->buffer->raw_len = length;
+    client->response->buffer->raw_data = (char *)at;
+    if (client->response->buffer->output_ptr) {
+        memcpy(client->response->buffer->output_ptr, (char *)at, length);
+        client->response->buffer->output_ptr += length;
+    }
+
     client->response->data_process += length;
+    client->response->buffer->raw_len += length;
     http_dispatch_event(client, HTTP_EVENT_ON_DATA, (void *)at, length);
     return 0;
 }
@@ -743,14 +749,13 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
         if (rlen <= 0) {
             return ridx;
         }
+        res_buffer->output_ptr = buffer + ridx;
         http_parser_execute(client->parser, client->parser_settings, res_buffer->data, rlen);
+        ridx += res_buffer->raw_len;
+        need_read -= res_buffer->raw_len;
 
-        if (res_buffer->raw_len) {
-            memcpy(buffer + ridx, res_buffer->raw_data, res_buffer->raw_len);
-            ridx += res_buffer->raw_len;
-            need_read -= res_buffer->raw_len;
-        }
         res_buffer->raw_len = 0; //clear
+        res_buffer->output_ptr = NULL;
     }
 
     return ridx;

+ 6 - 4
components/esp_http_client/lib/transport_ssl.c

@@ -206,12 +206,14 @@ static int ssl_write(transport_handle_t t, const char *buffer, int len, int time
 
 static int ssl_read(transport_handle_t t, char *buffer, int len, int timeout_ms)
 {
-    int ret;
+    int poll = -1, ret;
     transport_ssl_t *ssl = transport_get_context_data(t);
-    ret = mbedtls_ssl_read(&ssl->ctx, (unsigned char *)buffer, len);
-    if (ret == 0) {
-        return -1;
+    if (mbedtls_ssl_get_bytes_avail(&ssl->ctx) <= 0) {
+        if ((poll = transport_poll_read(t, timeout_ms)) <= 0) {
+            return poll;
+        }
     }
+    ret = mbedtls_ssl_read(&ssl->ctx, (unsigned char *)buffer, len);
     return ret;
 }