From 0e5655694c844f93e1fdd044d873c2661cb00742 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 20 Feb 2019 04:33:31 +0100 Subject: Fix HTTPClient keep alive with chunked encoding. We need to consume the trailer part and final CRLF after last chunk as per RFC 7230 section 4.1: ``` chunked-body = *chunk last-chunk trailer-part CRLF ``` We do not return the trailer part, just consume it allowing following requests to work as expected when using keep alive. --- core/io/http_client.cpp | 30 ++++++++++++++++++++++++++++-- core/io/http_client.h | 1 + 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index abf4dd200e..e5c6d2a4f2 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -278,6 +278,7 @@ void HTTPClient::close() { body_size = -1; body_left = 0; chunk_left = 0; + chunk_trailer_part = 0; read_until_eof = false; response_num = 0; handshaking = false; @@ -421,6 +422,7 @@ Error HTTPClient::poll() { chunked = false; body_left = 0; chunk_left = 0; + chunk_trailer_part = false; read_until_eof = false; response_str.clear(); response_headers.clear(); @@ -511,7 +513,30 @@ PoolByteArray HTTPClient::read_response_body_chunk() { while (true) { - if (chunk_left == 0) { + if (chunk_trailer_part) { + // We need to consume the trailer part too or keep-alive will break + uint8_t b; + int rec = 0; + err = _get_http_data(&b, 1, rec); + + if (rec == 0) + break; + + chunk.push_back(b); + int cs = chunk.size(); + if ((cs >= 2 && chunk[cs - 2] == '\r' && chunk[cs - 1] == '\n')) { + if (cs == 2) { + // Finally over + chunk_trailer_part = false; + status = STATUS_CONNECTED; + chunk.clear(); + break; + } else { + // We do not process nor return the trailer data + chunk.clear(); + } + } + } else if (chunk_left == 0) { // Reading length uint8_t b; int rec = 0; @@ -556,7 +581,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() { if (len == 0) { // End reached! - status = STATUS_CONNECTED; + chunk_trailer_part = true; chunk.clear(); break; } @@ -695,6 +720,7 @@ HTTPClient::HTTPClient() { body_left = 0; read_until_eof = false; chunk_left = 0; + chunk_trailer_part = false; response_num = 0; ssl = false; blocking = false; diff --git a/core/io/http_client.h b/core/io/http_client.h index 1ad44d5f01..85ee1959a2 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -172,6 +172,7 @@ private: bool chunked; Vector chunk; int chunk_left; + bool chunk_trailer_part; int body_size; int body_left; bool read_until_eof; -- cgit v1.2.3