From 5589954800880153c58bed6104656fa56177344c Mon Sep 17 00:00:00 2001 From: Tuan Date: Wed, 27 Jun 2018 14:21:16 +0700 Subject: [PATCH] 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 --- components/esp_http_client/esp_http_client.c | 19 ++++++++++++------- .../esp_http_client/lib/transport_ssl.c | 10 ++++++---- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c index f504ba1d2..2e2b25c53 100644 --- a/components/esp_http_client/esp_http_client.c +++ b/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; diff --git a/components/esp_http_client/lib/transport_ssl.c b/components/esp_http_client/lib/transport_ssl.c index 8a3c49c0f..bb07c9245 100644 --- a/components/esp_http_client/lib/transport_ssl.c +++ b/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; }