From 322c54c945e80008de113b20e17a9b1cd45648d3 Mon Sep 17 00:00:00 2001 From: Jeroen88 Date: Sun, 2 Jun 2019 16:28:01 +0200 Subject: [PATCH 1/6] Fix persistance issue found, see ESP8266 issue #6152 --- libraries/HTTPClient/src/HTTPClient.cpp | 3 +++ libraries/HTTPClient/src/HTTPClient.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/HTTPClient/src/HTTPClient.cpp b/libraries/HTTPClient/src/HTTPClient.cpp index 8b832988045..ab632342d81 100644 --- a/libraries/HTTPClient/src/HTTPClient.cpp +++ b/libraries/HTTPClient/src/HTTPClient.cpp @@ -1080,6 +1080,8 @@ int HTTPClient::handleHeaderResponse() return HTTPC_ERROR_NOT_CONNECTED; } + _canReuse = !_useHTTP10; + String transferEncoding; _returnCode = -1; _size = -1; @@ -1098,6 +1100,7 @@ int HTTPClient::handleHeaderResponse() if(headerLine.startsWith("HTTP/1.")) { _returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt(); + _canReuse = (_returnCode != '0'); } else if(headerLine.indexOf(':')) { String headerName = headerLine.substring(0, headerLine.indexOf(':')); String headerValue = headerLine.substring(headerLine.indexOf(':') + 1); diff --git a/libraries/HTTPClient/src/HTTPClient.h b/libraries/HTTPClient/src/HTTPClient.h index 745f6e6426f..45f6e3f4311 100644 --- a/libraries/HTTPClient/src/HTTPClient.h +++ b/libraries/HTTPClient/src/HTTPClient.h @@ -217,7 +217,7 @@ class HTTPClient String _host; uint16_t _port = 0; int32_t _connectTimeout = -1; - bool _reuse = false; + bool _reuse = true; uint16_t _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT; bool _useHTTP10 = false; bool _secure = false; From 7e7301928152f56feb18455ceb75e216ef1c560b Mon Sep 17 00:00:00 2001 From: Jeroen88 Date: Thu, 6 Jun 2019 17:51:10 +0200 Subject: [PATCH 2/6] Correcting the parsing of the header for HTTP1.0 --- libraries/HTTPClient/src/HTTPClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/HTTPClient/src/HTTPClient.cpp b/libraries/HTTPClient/src/HTTPClient.cpp index ab632342d81..bc5735011d6 100644 --- a/libraries/HTTPClient/src/HTTPClient.cpp +++ b/libraries/HTTPClient/src/HTTPClient.cpp @@ -1099,8 +1099,8 @@ int HTTPClient::handleHeaderResponse() log_v("RX: '%s'", headerLine.c_str()); if(headerLine.startsWith("HTTP/1.")) { + _canReuse = (headerLine[sizeof "HTTP/1."] != '0'); _returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt(); - _canReuse = (_returnCode != '0'); } else if(headerLine.indexOf(':')) { String headerName = headerLine.substring(0, headerLine.indexOf(':')); String headerValue = headerLine.substring(headerLine.indexOf(':') + 1); From 33fbad4015a1bd4e4171ece60cdbc694f565ceda Mon Sep 17 00:00:00 2001 From: Jeroen88 Date: Thu, 6 Jun 2019 21:48:42 +0200 Subject: [PATCH 3/6] Send 'Connection: Close' header in case of HTTP1.0 --- libraries/HTTPClient/src/HTTPClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/HTTPClient/src/HTTPClient.cpp b/libraries/HTTPClient/src/HTTPClient.cpp index bc5735011d6..b6dd623541b 100644 --- a/libraries/HTTPClient/src/HTTPClient.cpp +++ b/libraries/HTTPClient/src/HTTPClient.cpp @@ -1046,7 +1046,7 @@ bool HTTPClient::sendHeader(const char * type) header += String(F("\r\nUser-Agent: ")) + _userAgent + F("\r\nConnection: "); - if(_reuse) { + if(_reuse && !_useHTTP10) { header += F("keep-alive"); } else { header += F("close"); From 0e23c8b9e143fdb1a74da7e13112162b2e3f1785 Mon Sep 17 00:00:00 2001 From: Jeroen88 Date: Thu, 6 Jun 2019 22:06:10 +0200 Subject: [PATCH 4/6] Let reuse connection depend on protocol used: HTTP1.0 or HTTP1.1 --- libraries/HTTPClient/src/HTTPClient.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/HTTPClient/src/HTTPClient.cpp b/libraries/HTTPClient/src/HTTPClient.cpp index b6dd623541b..24ca1b7e986 100644 --- a/libraries/HTTPClient/src/HTTPClient.cpp +++ b/libraries/HTTPClient/src/HTTPClient.cpp @@ -456,6 +456,7 @@ void HTTPClient::setTimeout(uint16_t timeout) void HTTPClient::useHTTP10(bool useHTTP10) { _useHTTP10 = useHTTP10; + _reuse = !useHTTP10; } /** @@ -1046,7 +1047,7 @@ bool HTTPClient::sendHeader(const char * type) header += String(F("\r\nUser-Agent: ")) + _userAgent + F("\r\nConnection: "); - if(_reuse && !_useHTTP10) { + if(_reuse) { header += F("keep-alive"); } else { header += F("close"); From 6e1503046ca9982a355bb5913eaf0d6dcafd426d Mon Sep 17 00:00:00 2001 From: Jeroen88 Date: Sat, 6 Jul 2019 13:52:59 +0200 Subject: [PATCH 5/6] Fixed reuse, added null ptr checks, added check for _trainsportTraits in connect() in case _client was set null --- libraries/HTTPClient/src/HTTPClient.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/libraries/HTTPClient/src/HTTPClient.cpp b/libraries/HTTPClient/src/HTTPClient.cpp index 24ca1b7e986..1f35381e640 100644 --- a/libraries/HTTPClient/src/HTTPClient.cpp +++ b/libraries/HTTPClient/src/HTTPClient.cpp @@ -195,6 +195,11 @@ bool HTTPClient::begin(String url, const char* CAcert) } _secure = true; _transportTraits = TransportTraitsPtr(new TLSTraits(CAcert)); + if(!_transportTraits) { + log_e("could not create transport traits"); + return false; + } + return true; } @@ -215,6 +220,11 @@ bool HTTPClient::begin(String url) return begin(url, (const char*)NULL); } _transportTraits = TransportTraitsPtr(new TransportTraits()); + if(!_transportTraits) { + log_e("could not create transport traits"); + return false; + } + return true; } #endif // HTTPCLIENT_1_1_COMPATIBLE @@ -981,14 +991,19 @@ bool HTTPClient::connect(void) } #ifdef HTTPCLIENT_1_1_COMPATIBLE - if(!_client) { + if(_transportTraits && !_client) { _tcpDeprecated = _transportTraits->create(); + if(!_tcpDeprecated) { + log_e("failed to create client"); + return false; + } _client = _tcpDeprecated.get(); } #endif if (!_client) { log_d("HTTPClient::begin was not called or returned error"); +Serial.println("HERE"); return false; } @@ -1100,7 +1115,9 @@ int HTTPClient::handleHeaderResponse() log_v("RX: '%s'", headerLine.c_str()); if(headerLine.startsWith("HTTP/1.")) { - _canReuse = (headerLine[sizeof "HTTP/1."] != '0'); + if(_canReuse) { + _canReuse = (headerLine[sizeof "HTTP/1." - 1] != '0'); + } _returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt(); } else if(headerLine.indexOf(':')) { String headerName = headerLine.substring(0, headerLine.indexOf(':')); From 4acb79e7574222e3e89147659b27567f5b743297 Mon Sep 17 00:00:00 2001 From: Jeroen88 Date: Tue, 6 Aug 2019 10:31:43 +0200 Subject: [PATCH 6/6] Fix reuse connection issues, similar to ESP8266 PR #6176 --- libraries/HTTPClient/src/HTTPClient.cpp | 34 ++++++++++++++++--------- libraries/HTTPClient/src/HTTPClient.h | 2 +- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/libraries/HTTPClient/src/HTTPClient.cpp b/libraries/HTTPClient/src/HTTPClient.cpp index 1f35381e640..f4b0ae54654 100644 --- a/libraries/HTTPClient/src/HTTPClient.cpp +++ b/libraries/HTTPClient/src/HTTPClient.cpp @@ -1,3 +1,4 @@ +#include /** * HTTPClient.cpp * @@ -343,7 +344,8 @@ bool HTTPClient::begin(String host, uint16_t port, String uri, const char* CAcer */ void HTTPClient::end(void) { - disconnect(); + disconnect(false); + clear(); } @@ -352,7 +354,7 @@ void HTTPClient::end(void) * disconnect * close the TCP socket */ -void HTTPClient::disconnect() +void HTTPClient::disconnect(bool preserveClient) { if(connected()) { if(_client->available() > 0) { @@ -367,7 +369,9 @@ void HTTPClient::disconnect() } else { log_d("tcp stop\n"); _client->stop(); - _client = nullptr; + if(!preserveClient) { + _client = nullptr; + } #ifdef HTTPCLIENT_1_1_COMPATIBLE if(_tcpDeprecated) { _transportTraits.reset(nullptr); @@ -827,7 +831,8 @@ int HTTPClient::writeToStream(Stream * stream) return returnError(HTTPC_ERROR_ENCODING); } - end(); +// end(); + disconnect(true); return ret; } @@ -981,9 +986,12 @@ bool HTTPClient::hasHeader(const char* name) */ bool HTTPClient::connect(void) { - if(connected()) { - log_d("already connected, try reuse!"); + if(_reuse) { + log_d("already connected, reusing connection"); + } else { + log_d("already connected, try reuse!"); + } while(_client->available() > 0) { _client->read(); } @@ -1003,7 +1011,6 @@ bool HTTPClient::connect(void) if (!_client) { log_d("HTTPClient::begin was not called or returned error"); -Serial.println("HERE"); return false; } @@ -1096,11 +1103,12 @@ int HTTPClient::handleHeaderResponse() return HTTPC_ERROR_NOT_CONNECTED; } - _canReuse = !_useHTTP10; + clear(); + + _canReuse = _reuse; String transferEncoding; - _returnCode = -1; - _size = -1; + _transferEncoding = HTTPC_TE_IDENTITY; unsigned long lastDataTime = millis(); @@ -1128,8 +1136,10 @@ int HTTPClient::handleHeaderResponse() _size = headerValue.toInt(); } - if(headerName.equalsIgnoreCase("Connection")) { - _canReuse = headerValue.equalsIgnoreCase("keep-alive"); + if(_canReuse && headerName.equalsIgnoreCase("Connection")) { + if(headerValue.indexOf("close") >= 0 && headerValue.indexOf("keep-alive") < 0) { + _canReuse = false; + } } if(headerName.equalsIgnoreCase("Transfer-Encoding")) { diff --git a/libraries/HTTPClient/src/HTTPClient.h b/libraries/HTTPClient/src/HTTPClient.h index 45f6e3f4311..e089bb54973 100644 --- a/libraries/HTTPClient/src/HTTPClient.h +++ b/libraries/HTTPClient/src/HTTPClient.h @@ -197,7 +197,7 @@ class HTTPClient }; bool beginInternal(String url, const char* expectedProtocol); - void disconnect(); + void disconnect(bool preserveClient = false); void clear(); int returnError(int error); bool connect(void);