]> granicus.if.org Git - esp-idf/commitdiff
esp_http_client: fixed http chunked encoding packet loss & add check data before...
authorTuan <tuanpm@live.com>
Wed, 27 Jun 2018 07:21:16 +0000 (14:21 +0700)
committerbot <bot@espressif.com>
Wed, 1 Aug 2018 07:14:36 +0000 (07:14 +0000)
- 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

components/esp_http_client/esp_http_client.c
components/esp_http_client/lib/transport_ssl.c

index f504ba1d211114aebf84a4d69c910929ff67b2e7..2e2b25c536462bcb6563e39eb1a8747342814505 100644 (file)
@@ -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;
index 8a3c49c0ffdf3f93502c5bf84f4d5b3811d3270a..bb07c92455ec7ef9d2e05ae5a35cd9bb4c948b74 100644 (file)
@@ -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;
 }