From fadfc9de84a921af22625b28bc20e94ab570a56a Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Tue, 28 Mar 2023 23:18:11 +0200 Subject: [PATCH 01/21] honour stream timeout with ssl --- libraries/ESP8266WiFi/src/WiFiClient.cpp | 6 +++ .../src/WiFiClientSecureBearSSL.cpp | 13 +++++-- .../ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 39 ++++++++++++------- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index fb10209ec0..aa479a2d57 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -229,6 +229,7 @@ size_t WiFiClient::write(Stream& stream) return 0; } // core up to 2.7.4 was equivalent to this + _client->setTimeout(_timeout); return stream.sendAll(this); } @@ -266,11 +267,13 @@ int WiFiClient::read() int WiFiClient::read(uint8_t* buf, size_t size) { + _client->setTimeout(_timeout); return (int)_client->read((char*)buf, size); } int WiFiClient::read(char* buf, size_t size) { + _client->setTimeout(_timeout); return (int)_client->read(buf, size); } @@ -279,6 +282,7 @@ int WiFiClient::peek() if (!available()) return -1; + _client->setTimeout(_timeout); return _client->peek(); } @@ -300,6 +304,7 @@ size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length) { count = length; } + _client->setTimeout(_timeout); return _client->peekBytes((char *)buffer, count); } @@ -454,6 +459,7 @@ const char* WiFiClient::peekBuffer () // return number of byte accessible by peekBuffer() size_t WiFiClient::peekAvailable () { + _client->setTimeout(_timeout); return _client? _client->peekAvailable(): 0; } diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 53b606f8c3..689536f970 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -70,7 +70,8 @@ namespace BearSSL { void WiFiClientSecureCtx::_clear() { // TLS handshake may take more than the 5 second default timeout - _timeout = 15000; + _minimalTimeout = 15000; + _timeout = std::max(_userTimeout, _minimalTimeout); _sc = nullptr; _sc_svr = nullptr; @@ -246,7 +247,9 @@ void WiFiClientSecureCtx::_freeSSL() { _recvapp_len = 0; // This connection is toast _handshake_done = false; - _timeout = 15000; + + _minimalTimeout = 15000; + _timeout = std::max(_userTimeout, _minimalTimeout); } bool WiFiClientSecureCtx::_clientConnected() { @@ -484,6 +487,9 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { return -1; } + // _run_until() is called prior to inherited read/write methods + // -> refreshing _timeout here, which is also used by ancestors + _timeout = std::max(_userTimeout, _minimalTimeout); esp8266::polledTimeout::oneShotMs loopTimeout(_timeout); for (int no_work = 0; blocking || no_work < 2;) { @@ -1208,7 +1214,8 @@ bool WiFiClientSecureCtx::_connectSSL(const char* hostName) { _x509_knownkey = nullptr; // reduce timeout after successful handshake to fail fast if server stop accepting our data for whathever reason - if (ret) _timeout = 5000; + if (ret) _minimalTimeout = 5000; + _timeout = std::max(_userTimeout, _minimalTimeout); return ret; } diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index d78dad2972..7724b420a6 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -235,6 +235,11 @@ class WiFiClientSecureCtx : public WiFiClient { bool _installServerX509Validator(const X509List *client_CA_ta); // Setup X509 client cert validation, if supplied uint8_t *_streamLoad(Stream& stream, size_t size); + + // timeout management + unsigned long _userTimeout = 5000, _minimalTimeout = 0; + void setUpstreamTimeout (unsigned long timeout) { _userTimeout = timeout; } + }; // class WiFiClientSecureCtx @@ -263,25 +268,25 @@ class WiFiClientSecure : public WiFiClient { std::unique_ptr clone() const override { return std::unique_ptr(new WiFiClientSecure(*this)); } uint8_t status() override { return _ctx->status(); } - int connect(IPAddress ip, uint16_t port) override { return _ctx->connect(ip, port); } - int connect(const String& host, uint16_t port) override { return _ctx->connect(host, port); } - int connect(const char* name, uint16_t port) override { return _ctx->connect(name, port); } + int connect(IPAddress ip, uint16_t port) override { uto(); return _ctx->connect(ip, port); } + int connect(const String& host, uint16_t port) override { uto(); return _ctx->connect(host, port); } + int connect(const char* name, uint16_t port) override { uto(); return _ctx->connect(name, port); } uint8_t connected() override { return _ctx->connected(); } - size_t write(const uint8_t *buf, size_t size) override { return _ctx->write(buf, size); } - size_t write_P(PGM_P buf, size_t size) override { return _ctx->write_P(buf, size); } - size_t write(const char *buf) { return write((const uint8_t*)buf, strlen(buf)); } - size_t write_P(const char *buf) { return write_P((PGM_P)buf, strlen_P(buf)); } - size_t write(Stream& stream) /* Note this is not virtual */ { return _ctx->write(stream); } - int read(uint8_t *buf, size_t size) override { return _ctx->read(buf, size); } - int available() override { return _ctx->available(); } - int availableForWrite() override { return _ctx->availableForWrite(); } - int read() override { return _ctx->read(); } - int peek() override { return _ctx->peek(); } - size_t peekBytes(uint8_t *buffer, size_t length) override { return _ctx->peekBytes(buffer, length); } + size_t write(const uint8_t *buf, size_t size) override { uto(); return _ctx->write(buf, size); } + size_t write_P(PGM_P buf, size_t size) override { uto(); return _ctx->write_P(buf, size); } + size_t write(const char *buf) { uto(); return write((const uint8_t*)buf, strlen(buf)); } + size_t write_P(const char *buf) { uto(); return write_P((PGM_P)buf, strlen_P(buf)); } + size_t write(Stream& stream) /* Note this is not virtual */ { uto(); return _ctx->write(stream); } + int read(uint8_t *buf, size_t size) override { uto(); return _ctx->read(buf, size); } + int available() override { uto(); return _ctx->available(); } + int availableForWrite() override { uto(); return _ctx->availableForWrite(); } + int read() override { uto(); return _ctx->read(); } + int peek() override { uto(); return _ctx->peek(); } + size_t peekBytes(uint8_t *buffer, size_t length) override { uto(); return _ctx->peekBytes(buffer, length); } bool flush(unsigned int maxWaitMs) { return _ctx->flush(maxWaitMs); } bool stop(unsigned int maxWaitMs) { return _ctx->stop(maxWaitMs); } - void flush() override { (void)flush(0); } + void flush() override { uto(); (void)flush(0); } void stop() override { (void)stop(0); } IPAddress remoteIP() override { return _ctx->remoteIP(); } @@ -375,6 +380,10 @@ class WiFiClientSecure : public WiFiClient { _ctx(new WiFiClientSecureCtx(client, chain, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta, tls_min, tls_max)) { } + // set _ctx user timeout according to Arduino's Stream::_timeout + // (set/getTimeout are not virtual: no easy way to propagate value) + inline void uto () { _ctx->setUpstreamTimeout(_timeout); } + }; // class WiFiClientSecure }; // namespace BearSSL From c6b2311956540af2a962adca3e786ac2933f32c2 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Wed, 29 Mar 2023 01:44:09 +0200 Subject: [PATCH 02/21] fix timeout propagation --- .../ESP8266HTTPClient/src/ESP8266HTTPClient.cpp | 16 ++++++++++++---- .../ESP8266HTTPClient/src/ESP8266HTTPClient.h | 4 +--- .../ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp | 5 +++-- .../ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 2 +- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index 429fc7c23f..020e7154f6 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -86,6 +86,10 @@ bool HTTPClient::begin(WiFiClient &client, const String& url) { _port = (protocol == "https" ? 443 : 80); _client = client.clone(); + if (_deferredTimeout) { + _client->setTimeout(_deferredTimeout); + } + return beginInternal(url, protocol.c_str()); } @@ -109,6 +113,10 @@ bool HTTPClient::begin(WiFiClient &client, const String& host, uint16_t port, co } _client = client.clone(); + if (_deferredTimeout) { + _client->setTimeout(_deferredTimeout); + } + clear(); @@ -308,10 +316,12 @@ void HTTPClient::setAuthorization(String auth) */ void HTTPClient::setTimeout(uint16_t timeout) { - _tcpTimeout = timeout; if(connected()) { _client->setTimeout(timeout); } + else { + _deferredTimeout = timeout; + } } /** @@ -794,8 +804,6 @@ bool HTTPClient::connect(void) return false; } - _client->setTimeout(_tcpTimeout); - if(!_client->connect(_host.c_str(), _port)) { DEBUG_HTTPCLIENT("[HTTP-Client] failed connect to %s:%u\n", _host.c_str(), _port); return false; @@ -978,7 +986,7 @@ int HTTPClient::handleHeaderResponse() } } else { - if((millis() - lastDataTime) > _tcpTimeout) { + if((millis() - lastDataTime) > _client.get()->getTimeout()) { return HTTPC_ERROR_READ_TIMEOUT; } esp_yield(); diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h index f510c02a15..b084fefe1a 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h @@ -42,8 +42,6 @@ #define DEBUG_HTTPCLIENT(...) do { (void)0; } while (0) #endif -#define HTTPCLIENT_DEFAULT_TCP_TIMEOUT (5000) - /// HTTP client errors #define HTTPC_ERROR_CONNECTION_FAILED (-1) #define HTTPC_ERROR_SEND_HEADER_FAILED (-2) @@ -250,7 +248,7 @@ class HTTPClient String _host; uint16_t _port = 0; bool _reuse = true; - uint16_t _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT; + uint16_t _deferredTimeout = 0; bool _useHTTP10 = false; String _uri; diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 689536f970..f6f5cd2bd7 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -465,8 +465,9 @@ size_t WiFiClientSecureCtx::peekBytes(uint8_t *buffer, size_t length) { return 0; } + _timeout = std::max(_userTimeout, _minimalTimeout); _startMillis = millis(); - while ((_pollRecvBuffer() < (int) length) && ((millis() - _startMillis) < 5000)) { + while ((_pollRecvBuffer() < (int)length) && ((millis() - _startMillis) < _timeout)) { yield(); } @@ -1214,7 +1215,7 @@ bool WiFiClientSecureCtx::_connectSSL(const char* hostName) { _x509_knownkey = nullptr; // reduce timeout after successful handshake to fail fast if server stop accepting our data for whathever reason - if (ret) _minimalTimeout = 5000; + if (ret) _minimalTimeout = 0; _timeout = std::max(_userTimeout, _minimalTimeout); return ret; diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index 7724b420a6..45a460f6a9 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -260,7 +260,7 @@ class WiFiClientSecure : public WiFiClient { public: WiFiClientSecure():_ctx(new WiFiClientSecureCtx()) { _owned = _ctx.get(); } - WiFiClientSecure(const WiFiClientSecure &rhs): WiFiClient(), _ctx(rhs._ctx) { if (_ctx) _owned = _ctx.get(); } + WiFiClientSecure(const WiFiClientSecure &rhs): WiFiClient(), _ctx(rhs._ctx) { if (_ctx) _owned = _ctx.get(); _timeout = rhs._timeout; } ~WiFiClientSecure() override { _ctx = nullptr; } WiFiClientSecure& operator=(const WiFiClientSecure&) = default; From d62ac3a23e03c3c0a98fecdd3ce4d4bd0a6677e6 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Wed, 29 Mar 2023 01:45:44 +0200 Subject: [PATCH 03/21] style --- libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index 020e7154f6..8c24acae33 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -90,7 +90,6 @@ bool HTTPClient::begin(WiFiClient &client, const String& url) { _client->setTimeout(_deferredTimeout); } - return beginInternal(url, protocol.c_str()); } @@ -117,7 +116,6 @@ bool HTTPClient::begin(WiFiClient &client, const String& host, uint16_t port, co _client->setTimeout(_deferredTimeout); } - clear(); _host = host; From 74cabd107da3d2c767c9d0533e7e0560ffc4f04f Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Thu, 30 Mar 2023 01:38:10 +0200 Subject: [PATCH 04/21] reduce footprint, add WiFiClientSecure::setNegociationTimeout(ms) --- .../src/ESP8266HTTPClient.cpp | 6 +- .../src/WiFiClientSecureBearSSL.cpp | 35 ++++++---- .../ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 65 +++++++++++-------- 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index 8c24acae33..f4b1e1f237 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -110,7 +110,7 @@ bool HTTPClient::begin(WiFiClient &client, const String& host, uint16_t port, co _canReuse = false; disconnect(true); } - + _client = client.clone(); if (_deferredTimeout) { _client->setTimeout(_deferredTimeout); @@ -491,7 +491,7 @@ int HTTPClient::sendRequest(const char * type, const uint8_t * payload, size_t s // redirect = false; if ( - _followRedirects != HTTPC_DISABLE_FOLLOW_REDIRECTS && + _followRedirects != HTTPC_DISABLE_FOLLOW_REDIRECTS && redirectCount < _redirectLimit && _location.length() > 0 ) { @@ -504,7 +504,7 @@ int HTTPClient::sendRequest(const char * type, const uint8_t * payload, size_t s // (the RFC require user to accept the redirection) _followRedirects == HTTPC_FORCE_FOLLOW_REDIRECTS || // allow GET and HEAD methods without force - !strcmp(type, "GET") || + !strcmp(type, "GET") || !strcmp(type, "HEAD") ) { redirectCount += 1; diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index f6f5cd2bd7..a2fcf21021 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -70,8 +70,8 @@ namespace BearSSL { void WiFiClientSecureCtx::_clear() { // TLS handshake may take more than the 5 second default timeout - _minimalTimeout = 15000; - _timeout = std::max(_userTimeout, _minimalTimeout); + _negociationTimeout = _userFacingStream? _userFacingStream->getNegociationTimeout(): 15000; + updateStreamTimeout(); _sc = nullptr; _sc_svr = nullptr; @@ -104,7 +104,7 @@ void WiFiClientSecureCtx::_clearAuthenticationSettings() { } -WiFiClientSecureCtx::WiFiClientSecureCtx() : WiFiClient() { +WiFiClientSecureCtx::WiFiClientSecureCtx(const WiFiClientSecure* alter) : WiFiClient(), _userFacingStream(alter) { _clear(); _clearAuthenticationSettings(); _certStore = nullptr; // Don't want to remove cert store on a clear, should be long lived @@ -122,10 +122,11 @@ WiFiClientSecureCtx::~WiFiClientSecureCtx() { stack_thunk_del_ref(); } -WiFiClientSecureCtx::WiFiClientSecureCtx(ClientContext* client, +WiFiClientSecureCtx::WiFiClientSecureCtx(const WiFiClientSecure* alter, + ClientContext* client, const X509List *chain, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, - const X509List *client_CA_ta, int tls_min, int tls_max) { + const X509List *client_CA_ta, int tls_min, int tls_max):_userFacingStream(alter) { _clear(); _clearAuthenticationSettings(); stack_thunk_add_ref(); @@ -142,11 +143,12 @@ WiFiClientSecureCtx::WiFiClientSecureCtx(ClientContext* client, } } -WiFiClientSecureCtx::WiFiClientSecureCtx(ClientContext *client, +WiFiClientSecureCtx::WiFiClientSecureCtx(const WiFiClientSecure* alter, + ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, - const X509List *client_CA_ta, int tls_min, int tls_max) { + const X509List *client_CA_ta, int tls_min, int tls_max): _userFacingStream(alter) { _clear(); _clearAuthenticationSettings(); stack_thunk_add_ref(); @@ -248,8 +250,8 @@ void WiFiClientSecureCtx::_freeSSL() { // This connection is toast _handshake_done = false; - _minimalTimeout = 15000; - _timeout = std::max(_userTimeout, _minimalTimeout); + _negociationTimeout = _userFacingStream? _userFacingStream->getNegociationTimeout(): 15000; + updateStreamTimeout(); } bool WiFiClientSecureCtx::_clientConnected() { @@ -465,7 +467,7 @@ size_t WiFiClientSecureCtx::peekBytes(uint8_t *buffer, size_t length) { return 0; } - _timeout = std::max(_userTimeout, _minimalTimeout); + updateStreamTimeout(); _startMillis = millis(); while ((_pollRecvBuffer() < (int)length) && ((millis() - _startMillis) < _timeout)) { yield(); @@ -490,7 +492,7 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { // _run_until() is called prior to inherited read/write methods // -> refreshing _timeout here, which is also used by ancestors - _timeout = std::max(_userTimeout, _minimalTimeout); + updateStreamTimeout(); esp8266::polledTimeout::oneShotMs loopTimeout(_timeout); for (int no_work = 0; blocking || no_work < 2;) { @@ -1215,8 +1217,8 @@ bool WiFiClientSecureCtx::_connectSSL(const char* hostName) { _x509_knownkey = nullptr; // reduce timeout after successful handshake to fail fast if server stop accepting our data for whathever reason - if (ret) _minimalTimeout = 0; - _timeout = std::max(_userTimeout, _minimalTimeout); + if (ret) _negociationTimeout = 0; + updateStreamTimeout(); return ret; } @@ -1682,4 +1684,9 @@ bool WiFiClientSecure::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint1 return _SendAbort(probe, supportsLen); } -}; +void WiFiClientSecureCtx::updateStreamTimeout () +{ + _timeout = std::max(_userFacingStream? _userFacingStream->getTimeout(): 5000, _negociationTimeout); +} + +}; // namespace BearSSL diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index 45a460f6a9..299499fb8f 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -31,9 +31,11 @@ namespace BearSSL { +class WiFiClientSecure; + class WiFiClientSecureCtx : public WiFiClient { public: - WiFiClientSecureCtx(); + WiFiClientSecureCtx(const WiFiClientSecure* alter); WiFiClientSecureCtx(const WiFiClientSecureCtx &rhs) = delete; ~WiFiClientSecureCtx() override; @@ -216,10 +218,12 @@ class WiFiClientSecureCtx : public WiFiClient { // Methods for handling server.available() call which returns a client connection. friend class WiFiClientSecure; // access to private context constructors - WiFiClientSecureCtx(ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type, + WiFiClientSecureCtx(const WiFiClientSecure* alter, + ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, const X509List *client_CA_ta, int tls_min, int tls_max); - WiFiClientSecureCtx(ClientContext* client, const X509List *chain, const PrivateKey *sk, + WiFiClientSecureCtx(const WiFiClientSecure* alter, + ClientContext* client, const X509List *chain, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, const X509List *client_CA_ta, int tls_min, int tls_max); @@ -237,8 +241,10 @@ class WiFiClientSecureCtx : public WiFiClient { uint8_t *_streamLoad(Stream& stream, size_t size); // timeout management - unsigned long _userTimeout = 5000, _minimalTimeout = 0; - void setUpstreamTimeout (unsigned long timeout) { _userTimeout = timeout; } + unsigned long _negociationTimeout = 0; // negociation timeout + const WiFiClientSecure* _userFacingStream = nullptr; // user-facing WiFiClientSecure + void setStream (const WiFiClientSecure* upStream) { _userFacingStream = upStream; } + void updateStreamTimeout (); }; // class WiFiClientSecureCtx @@ -259,8 +265,10 @@ class WiFiClientSecure : public WiFiClient { public: - WiFiClientSecure():_ctx(new WiFiClientSecureCtx()) { _owned = _ctx.get(); } - WiFiClientSecure(const WiFiClientSecure &rhs): WiFiClient(), _ctx(rhs._ctx) { if (_ctx) _owned = _ctx.get(); _timeout = rhs._timeout; } + WiFiClientSecure():_ctx(new WiFiClientSecureCtx(this)) { _owned = _ctx.get(); } + WiFiClientSecure(const WiFiClientSecure &rhs): _ctx(rhs._ctx), _userNegociationTimeout(rhs._userNegociationTimeout) { + if (_ctx) { _owned = _ctx.get(); _ctx->setStream(this); } + } ~WiFiClientSecure() override { _ctx = nullptr; } WiFiClientSecure& operator=(const WiFiClientSecure&) = default; @@ -268,25 +276,25 @@ class WiFiClientSecure : public WiFiClient { std::unique_ptr clone() const override { return std::unique_ptr(new WiFiClientSecure(*this)); } uint8_t status() override { return _ctx->status(); } - int connect(IPAddress ip, uint16_t port) override { uto(); return _ctx->connect(ip, port); } - int connect(const String& host, uint16_t port) override { uto(); return _ctx->connect(host, port); } - int connect(const char* name, uint16_t port) override { uto(); return _ctx->connect(name, port); } + int connect(IPAddress ip, uint16_t port) override { return _ctx->connect(ip, port); } + int connect(const String& host, uint16_t port) override { return _ctx->connect(host, port); } + int connect(const char* name, uint16_t port) override { return _ctx->connect(name, port); } uint8_t connected() override { return _ctx->connected(); } - size_t write(const uint8_t *buf, size_t size) override { uto(); return _ctx->write(buf, size); } - size_t write_P(PGM_P buf, size_t size) override { uto(); return _ctx->write_P(buf, size); } - size_t write(const char *buf) { uto(); return write((const uint8_t*)buf, strlen(buf)); } - size_t write_P(const char *buf) { uto(); return write_P((PGM_P)buf, strlen_P(buf)); } - size_t write(Stream& stream) /* Note this is not virtual */ { uto(); return _ctx->write(stream); } - int read(uint8_t *buf, size_t size) override { uto(); return _ctx->read(buf, size); } - int available() override { uto(); return _ctx->available(); } - int availableForWrite() override { uto(); return _ctx->availableForWrite(); } - int read() override { uto(); return _ctx->read(); } - int peek() override { uto(); return _ctx->peek(); } - size_t peekBytes(uint8_t *buffer, size_t length) override { uto(); return _ctx->peekBytes(buffer, length); } + size_t write(const uint8_t *buf, size_t size) override { return _ctx->write(buf, size); } + size_t write_P(PGM_P buf, size_t size) override { return _ctx->write_P(buf, size); } + size_t write(const char *buf) { return write((const uint8_t*)buf, strlen(buf)); } + size_t write_P(const char *buf) { return write_P((PGM_P)buf, strlen_P(buf)); } + size_t write(Stream& stream) /* Note this is not virtual */ { return _ctx->write(stream); } + int read(uint8_t *buf, size_t size) override { return _ctx->read(buf, size); } + int available() override { return _ctx->available(); } + int availableForWrite() override { return _ctx->availableForWrite(); } + int read() override { return _ctx->read(); } + int peek() override { return _ctx->peek(); } + size_t peekBytes(uint8_t *buffer, size_t length) override { return _ctx->peekBytes(buffer, length); } bool flush(unsigned int maxWaitMs) { return _ctx->flush(maxWaitMs); } bool stop(unsigned int maxWaitMs) { return _ctx->stop(maxWaitMs); } - void flush() override { uto(); (void)flush(0); } + void flush() override { (void)flush(0); } void stop() override { (void)stop(0); } IPAddress remoteIP() override { return _ctx->remoteIP(); } @@ -363,27 +371,28 @@ class WiFiClientSecure : public WiFiClient { // consume bytes after use (see peekBuffer) virtual void peekConsume (size_t consume) override { return _ctx->peekConsume(consume); } + // allowing to change timeout during negociation + void setNegociationTimeout (unsigned long timeout) { _userNegociationTimeout = timeout; } + unsigned long getNegociationTimeout () const { return _userNegociationTimeout; } + private: std::shared_ptr _ctx; + unsigned long _userNegociationTimeout = 15000; // negociation timeout initializer // Methods for handling server.available() call which returns a client connection. friend class WiFiServerSecure; // Server needs to access these constructors WiFiClientSecure(ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, const X509List *client_CA_ta, int tls_min, int tls_max): - _ctx(new WiFiClientSecureCtx(client, chain, cert_issuer_key_type, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta, tls_min, tls_max)) { + _ctx(new WiFiClientSecureCtx(this, client, chain, cert_issuer_key_type, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta, tls_min, tls_max)) { } WiFiClientSecure(ClientContext* client, const X509List *chain, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, const X509List *client_CA_ta, int tls_min, int tls_max): - _ctx(new WiFiClientSecureCtx(client, chain, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta, tls_min, tls_max)) { + _ctx(new WiFiClientSecureCtx(this, client, chain, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta, tls_min, tls_max)) { } - // set _ctx user timeout according to Arduino's Stream::_timeout - // (set/getTimeout are not virtual: no easy way to propagate value) - inline void uto () { _ctx->setUpstreamTimeout(_timeout); } - }; // class WiFiClientSecure }; // namespace BearSSL From 1efc1de602a628317573e7129648de6676d65674 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Thu, 30 Mar 2023 01:45:17 +0200 Subject: [PATCH 05/21] show api in example, wait for ntp --- .../BasicHttpsClient/BasicHttpsClient.ino | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino index bcb69d9641..2aee7f6941 100644 --- a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino +++ b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino @@ -41,11 +41,26 @@ void loop() { std::unique_ptr client(new BearSSL::WiFiClientSecure); +#if 1 // 1=secure, 0=insecure + client->setFingerprint(fingerprint_sni_cloudflaressl_com); + + // date needs to be setup + time_t now; + while (time(&now) < 24 * 3600) { + Serial.println("waiting for NTP time to be set..."); + delay(1000); + } + Serial.printf("date: %s", ctime(&now)); + +#else // Or, if you happy to ignore the SSL certificate, then use the following line instead: - // client->setInsecure(); + client->setInsecure(); +#endif HTTPClient https; + https.setTimeout(4000); // or: client->setTimeout(4000); + client->setNegociationTimeout(10000); Serial.print("[HTTPS] begin...\n"); if (https.begin(*client, jigsaw_host, jigsaw_port)) { // HTTPS From fa0051126889d5f79ed76a1f12096a54d76236c3 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Thu, 30 Mar 2023 02:04:02 +0200 Subject: [PATCH 06/21] ditto --- .../examples/BasicHttpsClient/BasicHttpsClient.ino | 1 + libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino index 2aee7f6941..0338389718 100644 --- a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino +++ b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino @@ -46,6 +46,7 @@ void loop() { client->setFingerprint(fingerprint_sni_cloudflaressl_com); // date needs to be setup + configTime("UTC", "pool.ntp.org"); time_t now; while (time(&now) < 24 * 3600) { Serial.println("waiting for NTP time to be set..."); diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index 299499fb8f..6f5b295034 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -266,7 +266,7 @@ class WiFiClientSecure : public WiFiClient { public: WiFiClientSecure():_ctx(new WiFiClientSecureCtx(this)) { _owned = _ctx.get(); } - WiFiClientSecure(const WiFiClientSecure &rhs): _ctx(rhs._ctx), _userNegociationTimeout(rhs._userNegociationTimeout) { + WiFiClientSecure(const WiFiClientSecure &rhs): WiFiClient(), _ctx(rhs._ctx), _userNegociationTimeout(rhs._userNegociationTimeout) { if (_ctx) { _owned = _ctx.get(); _ctx->setStream(this); } } ~WiFiClientSecure() override { _ctx = nullptr; } From ed0d6faee7870e7b1c8f293f3829869c42f4345e Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Thu, 30 Mar 2023 02:04:51 +0200 Subject: [PATCH 07/21] style --- .../examples/BasicHttpsClient/BasicHttpsClient.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino index 0338389718..3671535233 100644 --- a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino +++ b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino @@ -41,7 +41,7 @@ void loop() { std::unique_ptr client(new BearSSL::WiFiClientSecure); -#if 1 // 1=secure, 0=insecure +#if 1 // 1=secure, 0=insecure client->setFingerprint(fingerprint_sni_cloudflaressl_com); @@ -60,7 +60,7 @@ void loop() { #endif HTTPClient https; - https.setTimeout(4000); // or: client->setTimeout(4000); + https.setTimeout(4000); // or: client->setTimeout(4000); client->setNegociationTimeout(10000); Serial.print("[HTTPS] begin...\n"); From cc1951aff6f6519f7a4718e3ee26735681e44a94 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Sat, 1 Apr 2023 18:36:07 +0200 Subject: [PATCH 08/21] get rid of pointer, reverting to first proposal --- .../BasicHttpsClient/BasicHttpsClient.ino | 9 +- .../src/WiFiClientSecureBearSSL.cpp | 48 +++++------ .../ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 82 ++++++++++--------- 3 files changed, 71 insertions(+), 68 deletions(-) diff --git a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino index 459f8357c0..5454560c21 100644 --- a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino +++ b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino @@ -61,7 +61,14 @@ void loop() { HTTPClient https; https.setTimeout(4000); // or: client->setTimeout(4000); - client->setNegociationTimeout(10000); + client->setHandshakeTimeout(10000); + +#if 1 + constexpr int sslbufsize = 1024; + bool mfln = client->probeMaxFragmentLength(jigsaw_host, jigsaw_port, sslbufsize); + Serial.printf("Can reduce SSL footprint to %d bytes in RAM: %s\n", sslbufsize, mfln ? "yes" : "no"); + if (mfln) { client->setBufferSizes(sslbufsize, sslbufsize); } +#endif Serial.print("[HTTPS] begin...\n"); if (https.begin(*client, jigsaw_host, jigsaw_port)) { // HTTPS diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 38bba8c226..08f4d1e49b 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -69,10 +69,6 @@ extern "C" { namespace BearSSL { void WiFiClientSecureCtx::_clear() { - // TLS handshake may take more than the 5 second default timeout - _negociationTimeout = _userFacingStream? _userFacingStream->getNegociationTimeout(): 15000; - updateStreamTimeout(); - _sc = nullptr; _sc_svr = nullptr; _eng = nullptr; @@ -84,7 +80,7 @@ void WiFiClientSecureCtx::_clear() { _now = 0; // You can override or ensure time() is correct w/configTime _ta = nullptr; setBufferSizes(16384, 512); // Minimum safe - _handshake_done = false; + _set_handshake_done(false); // refreshes _timeout _recvapp_buf = nullptr; _recvapp_len = 0; _oom_err = false; @@ -104,7 +100,7 @@ void WiFiClientSecureCtx::_clearAuthenticationSettings() { } -WiFiClientSecureCtx::WiFiClientSecureCtx(const WiFiClientSecure* alter) : WiFiClient(), _userFacingStream(alter) { +WiFiClientSecureCtx::WiFiClientSecureCtx() : WiFiClient() { _clear(); _clearAuthenticationSettings(); _certStore = nullptr; // Don't want to remove cert store on a clear, should be long lived @@ -122,11 +118,10 @@ WiFiClientSecureCtx::~WiFiClientSecureCtx() { stack_thunk_del_ref(); } -WiFiClientSecureCtx::WiFiClientSecureCtx(const WiFiClientSecure* alter, - ClientContext* client, +WiFiClientSecureCtx::WiFiClientSecureCtx(ClientContext* client, const X509List *chain, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, - const X509List *client_CA_ta, int tls_min, int tls_max):_userFacingStream(alter) { + const X509List *client_CA_ta, int tls_min, int tls_max) { _clear(); _clearAuthenticationSettings(); stack_thunk_add_ref(); @@ -143,12 +138,11 @@ WiFiClientSecureCtx::WiFiClientSecureCtx(const WiFiClientSecure* alter, } } -WiFiClientSecureCtx::WiFiClientSecureCtx(const WiFiClientSecure* alter, - ClientContext *client, +WiFiClientSecureCtx::WiFiClientSecureCtx(ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, - const X509List *client_CA_ta, int tls_min, int tls_max): _userFacingStream(alter) { + const X509List *client_CA_ta, int tls_min, int tls_max) { _clear(); _clearAuthenticationSettings(); stack_thunk_add_ref(); @@ -207,7 +201,13 @@ bool WiFiClientSecureCtx::stop(unsigned int maxWaitMs) { } bool WiFiClientSecureCtx::flush(unsigned int maxWaitMs) { + auto savedNormal = _normalTimeout; + auto savedHandshake = _handshakeTimeout; + _normalTimeout = maxWaitMs; + _handshakeTimeout = maxWaitMs; (void) _run_until(BR_SSL_SENDAPP); + _normalTimeout = savedNormal; + _handshakeTimeout = savedHandshake; return WiFiClient::flush(maxWaitMs); } @@ -248,10 +248,7 @@ void WiFiClientSecureCtx::_freeSSL() { _recvapp_buf = nullptr; _recvapp_len = 0; // This connection is toast - _handshake_done = false; - - _negociationTimeout = _userFacingStream? _userFacingStream->getNegociationTimeout(): 15000; - updateStreamTimeout(); + _set_handshake_done(false); // refreshes _timeout } bool WiFiClientSecureCtx::_clientConnected() { @@ -466,7 +463,7 @@ size_t WiFiClientSecureCtx::peekBytes(uint8_t *buffer, size_t length) { return 0; } - updateStreamTimeout(); + _updateStreamTimeout(); _startMillis = millis(); while ((_pollRecvBuffer() < (int)length) && ((millis() - _startMillis) < _timeout)) { yield(); @@ -491,8 +488,8 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { // _run_until() is called prior to inherited read/write methods // -> refreshing _timeout here, which is also used by ancestors - updateStreamTimeout(); - esp8266::polledTimeout::oneShotMs loopTimeout(_timeout); + DEBUG_BSSL("_run_until starts, timeout=%lu\n", _updateStreamTimeout()); + esp8266::polledTimeout::oneShotMs loopTimeout(_updateStreamTimeout()); for (int no_work = 0; blocking || no_work < 2;) { optimistic_yield(100); @@ -611,7 +608,7 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { } bool WiFiClientSecureCtx::_wait_for_handshake() { - _handshake_done = false; + _set_handshake_done(false); // refreshes _timeout while (!_handshake_done && _clientConnected()) { int ret = _run_until(BR_SSL_SENDAPP); if (ret < 0) { @@ -619,7 +616,7 @@ bool WiFiClientSecureCtx::_wait_for_handshake() { break; } if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { - _handshake_done = true; + _set_handshake_done(true); // refreshes _timeout } optimistic_yield(1000); } @@ -1215,9 +1212,7 @@ bool WiFiClientSecureCtx::_connectSSL(const char* hostName) { _x509_insecure = nullptr; _x509_knownkey = nullptr; - // reduce timeout after successful handshake to fail fast if server stop accepting our data for whathever reason - if (ret) _negociationTimeout = 0; - updateStreamTimeout(); + // _timeout has been refreshed to normal operation as _handshake_done turned to true return ret; } @@ -1683,9 +1678,4 @@ bool WiFiClientSecure::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint1 return _SendAbort(probe, supportsLen); } -void WiFiClientSecureCtx::updateStreamTimeout () -{ - _timeout = std::max(_userFacingStream? _userFacingStream->getTimeout(): 5000, _negociationTimeout); -} - }; // namespace BearSSL diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index 6f5b295034..f03792ee5b 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -35,7 +35,7 @@ class WiFiClientSecure; class WiFiClientSecureCtx : public WiFiClient { public: - WiFiClientSecureCtx(const WiFiClientSecure* alter); + WiFiClientSecureCtx(); WiFiClientSecureCtx(const WiFiClientSecureCtx &rhs) = delete; ~WiFiClientSecureCtx() override; @@ -149,6 +149,10 @@ class WiFiClientSecureCtx : public WiFiClient { // consume bytes after use (see peekBuffer) virtual void peekConsume (size_t consume) override; + void setNormalTimeout (unsigned long timeout) { _normalTimeout = timeout; } + void setHandshakeTimeout (unsigned long timeout) { _handshakeTimeout = timeout; } + unsigned long getHandshakeTimeout () const { return _handshakeTimeout; } + protected: bool _connectSSL(const char *hostName); // Do initial SSL handshake @@ -218,12 +222,10 @@ class WiFiClientSecureCtx : public WiFiClient { // Methods for handling server.available() call which returns a client connection. friend class WiFiClientSecure; // access to private context constructors - WiFiClientSecureCtx(const WiFiClientSecure* alter, - ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type, + WiFiClientSecureCtx(ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, const X509List *client_CA_ta, int tls_min, int tls_max); - WiFiClientSecureCtx(const WiFiClientSecure* alter, - ClientContext* client, const X509List *chain, const PrivateKey *sk, + WiFiClientSecureCtx(ClientContext* client, const X509List *chain, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, const X509List *client_CA_ta, int tls_min, int tls_max); @@ -241,10 +243,11 @@ class WiFiClientSecureCtx : public WiFiClient { uint8_t *_streamLoad(Stream& stream, size_t size); // timeout management - unsigned long _negociationTimeout = 0; // negociation timeout - const WiFiClientSecure* _userFacingStream = nullptr; // user-facing WiFiClientSecure - void setStream (const WiFiClientSecure* upStream) { _userFacingStream = upStream; } - void updateStreamTimeout (); + + unsigned long _updateStreamTimeout () { return _timeout = _handshake_done? _normalTimeout: _handshakeTimeout; } + void _set_handshake_done (bool handshake_done) { _handshake_done = handshake_done; _updateStreamTimeout(); } + + unsigned long _normalTimeout = 5000, _handshakeTimeout = 15000; }; // class WiFiClientSecureCtx @@ -265,10 +268,8 @@ class WiFiClientSecure : public WiFiClient { public: - WiFiClientSecure():_ctx(new WiFiClientSecureCtx(this)) { _owned = _ctx.get(); } - WiFiClientSecure(const WiFiClientSecure &rhs): WiFiClient(), _ctx(rhs._ctx), _userNegociationTimeout(rhs._userNegociationTimeout) { - if (_ctx) { _owned = _ctx.get(); _ctx->setStream(this); } - } + WiFiClientSecure():_ctx(new WiFiClientSecureCtx()) { _owned = _ctx.get(); } + WiFiClientSecure(const WiFiClientSecure &rhs): WiFiClient(), _ctx(rhs._ctx) { if (_ctx) _owned = _ctx.get(); } ~WiFiClientSecure() override { _ctx = nullptr; } WiFiClientSecure& operator=(const WiFiClientSecure&) = default; @@ -276,24 +277,24 @@ class WiFiClientSecure : public WiFiClient { std::unique_ptr clone() const override { return std::unique_ptr(new WiFiClientSecure(*this)); } uint8_t status() override { return _ctx->status(); } - int connect(IPAddress ip, uint16_t port) override { return _ctx->connect(ip, port); } - int connect(const String& host, uint16_t port) override { return _ctx->connect(host, port); } - int connect(const char* name, uint16_t port) override { return _ctx->connect(name, port); } - - uint8_t connected() override { return _ctx->connected(); } - size_t write(const uint8_t *buf, size_t size) override { return _ctx->write(buf, size); } - size_t write_P(PGM_P buf, size_t size) override { return _ctx->write_P(buf, size); } - size_t write(const char *buf) { return write((const uint8_t*)buf, strlen(buf)); } - size_t write_P(const char *buf) { return write_P((PGM_P)buf, strlen_P(buf)); } - size_t write(Stream& stream) /* Note this is not virtual */ { return _ctx->write(stream); } - int read(uint8_t *buf, size_t size) override { return _ctx->read(buf, size); } - int available() override { return _ctx->available(); } - int availableForWrite() override { return _ctx->availableForWrite(); } - int read() override { return _ctx->read(); } - int peek() override { return _ctx->peek(); } - size_t peekBytes(uint8_t *buffer, size_t length) override { return _ctx->peekBytes(buffer, length); } - bool flush(unsigned int maxWaitMs) { return _ctx->flush(maxWaitMs); } - bool stop(unsigned int maxWaitMs) { return _ctx->stop(maxWaitMs); } + int connect(IPAddress ip, uint16_t port) override { uto(); return _ctx->connect(ip, port); } + int connect(const String& host, uint16_t port) override { uto(); return _ctx->connect(host, port); } + int connect(const char* name, uint16_t port) override { uto(); return _ctx->connect(name, port); } + + uint8_t connected() override { uto(); return _ctx->connected(); } + size_t write(const uint8_t *buf, size_t size) override { uto(); return _ctx->write(buf, size); } + size_t write_P(PGM_P buf, size_t size) override { uto(); return _ctx->write_P(buf, size); } + size_t write(const char *buf) { uto(); return write((const uint8_t*)buf, strlen(buf)); } + size_t write_P(const char *buf) { uto(); return write_P((PGM_P)buf, strlen_P(buf)); } + size_t write(Stream& stream) /* Note this is not virtual */ { uto(); return _ctx->write(stream); } + int read(uint8_t *buf, size_t size) override { uto(); return _ctx->read(buf, size); } + int available() override { uto(); return _ctx->available(); } + int availableForWrite() override { uto(); return _ctx->availableForWrite(); } + int read() override { uto(); return _ctx->read(); } + int peek() override { uto(); return _ctx->peek(); } + size_t peekBytes(uint8_t *buffer, size_t length) override { uto(); return _ctx->peekBytes(buffer, length); } + bool flush(unsigned int maxWaitMs) { uto(); return _ctx->flush(maxWaitMs); } + bool stop(unsigned int maxWaitMs) { uto(); return _ctx->stop(maxWaitMs); } void flush() override { (void)flush(0); } void stop() override { (void)stop(0); } @@ -362,7 +363,7 @@ class WiFiClientSecure : public WiFiClient { virtual bool hasPeekBufferAPI () const override { return true; } // return number of byte accessible by peekBuffer() - virtual size_t peekAvailable () override { return _ctx->available(); } + virtual size_t peekAvailable () override { return available(); } // return a pointer to available data buffer (size = peekAvailable()) // semantic forbids any kind of read() before calling peekConsume() @@ -371,28 +372,33 @@ class WiFiClientSecure : public WiFiClient { // consume bytes after use (see peekBuffer) virtual void peekConsume (size_t consume) override { return _ctx->peekConsume(consume); } - // allowing to change timeout during negociation - void setNegociationTimeout (unsigned long timeout) { _userNegociationTimeout = timeout; } - unsigned long getNegociationTimeout () const { return _userNegociationTimeout; } + // allowing user to set timeout used during handshake + void setHandshakeTimeout (unsigned long timeout) { _ctx->setHandshakeTimeout(timeout); } + unsigned long getHandshakeTimeout () const { return _ctx->getHandshakeTimeout(); } private: std::shared_ptr _ctx; - unsigned long _userNegociationTimeout = 15000; // negociation timeout initializer // Methods for handling server.available() call which returns a client connection. friend class WiFiServerSecure; // Server needs to access these constructors WiFiClientSecure(ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, const X509List *client_CA_ta, int tls_min, int tls_max): - _ctx(new WiFiClientSecureCtx(this, client, chain, cert_issuer_key_type, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta, tls_min, tls_max)) { + _ctx(new WiFiClientSecureCtx(client, chain, cert_issuer_key_type, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta, tls_min, tls_max)) { } WiFiClientSecure(ClientContext* client, const X509List *chain, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, const X509List *client_CA_ta, int tls_min, int tls_max): - _ctx(new WiFiClientSecureCtx(this, client, chain, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta, tls_min, tls_max)) { + _ctx(new WiFiClientSecureCtx(client, chain, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta, tls_min, tls_max)) { } + // (because Stream::setTimeout() is not virtual,) + // forward user timeout from Stream:: to SSL context + // this is internally called on every user operations + inline void uto () { _ctx->setNormalTimeout(_timeout); } + + }; // class WiFiClientSecure }; // namespace BearSSL From 4702c9367132d1c875e7624f9cf8c146f94308c0 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Sat, 1 Apr 2023 19:26:28 +0200 Subject: [PATCH 09/21] typos --- libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp | 2 +- libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index 5ba51869b5..b42b505796 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -222,7 +222,7 @@ void HTTPClient::disconnect(bool preserveClient) } if(_reuse && _canReuse) { - DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp keep open for reuse\n"); + DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp kept open for reuse\n"); } else { DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp stop\n"); if(_client) { diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index f03792ee5b..0e998db307 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -31,8 +31,6 @@ namespace BearSSL { -class WiFiClientSecure; - class WiFiClientSecureCtx : public WiFiClient { public: WiFiClientSecureCtx(); From e3aa6fe2a49cd2c670313034deffb57c985b2472 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Sat, 1 Apr 2023 23:49:42 +0200 Subject: [PATCH 10/21] make setTimeout virtual -> reduce footprint --- cores/esp8266/Stream.h | 2 +- .../src/WiFiClientSecureBearSSL.cpp | 5 ++ .../ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 47 +++++++++---------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/cores/esp8266/Stream.h b/cores/esp8266/Stream.h index f39bb423f2..322ada96d5 100644 --- a/cores/esp8266/Stream.h +++ b/cores/esp8266/Stream.h @@ -65,7 +65,7 @@ class Stream: public Print { // parsing methods - void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + virtual void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second unsigned long getTimeout () const { return _timeout; } bool find(const char *target); // reads data from the stream until the target string is found diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 08f4d1e49b..d0bfc8b99e 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -1678,4 +1678,9 @@ bool WiFiClientSecure::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint1 return _SendAbort(probe, supportsLen); } +void WiFiClientSecure::setTimeout (unsigned long timeout) +{ + _ctx->setNormalTimeout(timeout); +} + }; // namespace BearSSL diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index 0e998db307..08b1c84c9a 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -275,24 +275,24 @@ class WiFiClientSecure : public WiFiClient { std::unique_ptr clone() const override { return std::unique_ptr(new WiFiClientSecure(*this)); } uint8_t status() override { return _ctx->status(); } - int connect(IPAddress ip, uint16_t port) override { uto(); return _ctx->connect(ip, port); } - int connect(const String& host, uint16_t port) override { uto(); return _ctx->connect(host, port); } - int connect(const char* name, uint16_t port) override { uto(); return _ctx->connect(name, port); } - - uint8_t connected() override { uto(); return _ctx->connected(); } - size_t write(const uint8_t *buf, size_t size) override { uto(); return _ctx->write(buf, size); } - size_t write_P(PGM_P buf, size_t size) override { uto(); return _ctx->write_P(buf, size); } - size_t write(const char *buf) { uto(); return write((const uint8_t*)buf, strlen(buf)); } - size_t write_P(const char *buf) { uto(); return write_P((PGM_P)buf, strlen_P(buf)); } - size_t write(Stream& stream) /* Note this is not virtual */ { uto(); return _ctx->write(stream); } - int read(uint8_t *buf, size_t size) override { uto(); return _ctx->read(buf, size); } - int available() override { uto(); return _ctx->available(); } - int availableForWrite() override { uto(); return _ctx->availableForWrite(); } - int read() override { uto(); return _ctx->read(); } - int peek() override { uto(); return _ctx->peek(); } - size_t peekBytes(uint8_t *buffer, size_t length) override { uto(); return _ctx->peekBytes(buffer, length); } - bool flush(unsigned int maxWaitMs) { uto(); return _ctx->flush(maxWaitMs); } - bool stop(unsigned int maxWaitMs) { uto(); return _ctx->stop(maxWaitMs); } + int connect(IPAddress ip, uint16_t port) override { return _ctx->connect(ip, port); } + int connect(const String& host, uint16_t port) override { return _ctx->connect(host, port); } + int connect(const char* name, uint16_t port) override { return _ctx->connect(name, port); } + + uint8_t connected() override { return _ctx->connected(); } + size_t write(const uint8_t *buf, size_t size) override { return _ctx->write(buf, size); } + size_t write_P(PGM_P buf, size_t size) override { return _ctx->write_P(buf, size); } + size_t write(const char *buf) { return write((const uint8_t*)buf, strlen(buf)); } + size_t write_P(const char *buf) { return write_P((PGM_P)buf, strlen_P(buf)); } + size_t write(Stream& stream) /* Note this is not virtual */ { return _ctx->write(stream); } + int read(uint8_t *buf, size_t size) override { return _ctx->read(buf, size); } + int available() override { return _ctx->available(); } + int availableForWrite() override { return _ctx->availableForWrite(); } + int read() override { return _ctx->read(); } + int peek() override { return _ctx->peek(); } + size_t peekBytes(uint8_t *buffer, size_t length) override { return _ctx->peekBytes(buffer, length); } + bool flush(unsigned int maxWaitMs) { return _ctx->flush(maxWaitMs); } + bool stop(unsigned int maxWaitMs) { return _ctx->stop(maxWaitMs); } void flush() override { (void)flush(0); } void stop() override { (void)stop(0); } @@ -361,7 +361,7 @@ class WiFiClientSecure : public WiFiClient { virtual bool hasPeekBufferAPI () const override { return true; } // return number of byte accessible by peekBuffer() - virtual size_t peekAvailable () override { return available(); } + virtual size_t peekAvailable () override { return _ctx->available(); } // return a pointer to available data buffer (size = peekAvailable()) // semantic forbids any kind of read() before calling peekConsume() @@ -370,6 +370,9 @@ class WiFiClientSecure : public WiFiClient { // consume bytes after use (see peekBuffer) virtual void peekConsume (size_t consume) override { return _ctx->peekConsume(consume); } + // override setTimeout and forward to context + virtual void setTimeout (unsigned long timeout) override; + // allowing user to set timeout used during handshake void setHandshakeTimeout (unsigned long timeout) { _ctx->setHandshakeTimeout(timeout); } unsigned long getHandshakeTimeout () const { return _ctx->getHandshakeTimeout(); } @@ -391,12 +394,6 @@ class WiFiClientSecure : public WiFiClient { _ctx(new WiFiClientSecureCtx(client, chain, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta, tls_min, tls_max)) { } - // (because Stream::setTimeout() is not virtual,) - // forward user timeout from Stream:: to SSL context - // this is internally called on every user operations - inline void uto () { _ctx->setNormalTimeout(_timeout); } - - }; // class WiFiClientSecure }; // namespace BearSSL From d9118bb9e3e3516d7fc976f0b79f1400e1874b39 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Sat, 1 Apr 2023 23:50:55 +0200 Subject: [PATCH 11/21] normalTimeout -> runtimeTimeout --- libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp | 6 +++--- libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index d0bfc8b99e..f0d326be04 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -201,12 +201,12 @@ bool WiFiClientSecureCtx::stop(unsigned int maxWaitMs) { } bool WiFiClientSecureCtx::flush(unsigned int maxWaitMs) { - auto savedNormal = _normalTimeout; + auto savedNormal = _runtimeTimeout; auto savedHandshake = _handshakeTimeout; - _normalTimeout = maxWaitMs; + _runtimeTimeout = maxWaitMs; _handshakeTimeout = maxWaitMs; (void) _run_until(BR_SSL_SENDAPP); - _normalTimeout = savedNormal; + _runtimeTimeout = savedNormal; _handshakeTimeout = savedHandshake; return WiFiClient::flush(maxWaitMs); } diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index 08b1c84c9a..c0d8415000 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -147,7 +147,7 @@ class WiFiClientSecureCtx : public WiFiClient { // consume bytes after use (see peekBuffer) virtual void peekConsume (size_t consume) override; - void setNormalTimeout (unsigned long timeout) { _normalTimeout = timeout; } + void setNormalTimeout (unsigned long timeout) { _runtimeTimeout = timeout; } void setHandshakeTimeout (unsigned long timeout) { _handshakeTimeout = timeout; } unsigned long getHandshakeTimeout () const { return _handshakeTimeout; } @@ -242,10 +242,10 @@ class WiFiClientSecureCtx : public WiFiClient { // timeout management - unsigned long _updateStreamTimeout () { return _timeout = _handshake_done? _normalTimeout: _handshakeTimeout; } + unsigned long _updateStreamTimeout () { return _timeout = _handshake_done? _runtimeTimeout: _handshakeTimeout; } void _set_handshake_done (bool handshake_done) { _handshake_done = handshake_done; _updateStreamTimeout(); } - unsigned long _normalTimeout = 5000, _handshakeTimeout = 15000; + unsigned long _runtimeTimeout = 5000, _handshakeTimeout = 15000; }; // class WiFiClientSecureCtx From a199c8dbda901055d73b51d255a1944e791aff7b Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Sat, 1 Apr 2023 23:53:04 +0200 Subject: [PATCH 12/21] ditto --- libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp | 6 +++--- libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index f0d326be04..a3b2cfb9bd 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -201,12 +201,12 @@ bool WiFiClientSecureCtx::stop(unsigned int maxWaitMs) { } bool WiFiClientSecureCtx::flush(unsigned int maxWaitMs) { - auto savedNormal = _runtimeTimeout; + auto savedRuntime = _runtimeTimeout; auto savedHandshake = _handshakeTimeout; _runtimeTimeout = maxWaitMs; _handshakeTimeout = maxWaitMs; (void) _run_until(BR_SSL_SENDAPP); - _runtimeTimeout = savedNormal; + _runtimeTimeout = savedRuntime; _handshakeTimeout = savedHandshake; return WiFiClient::flush(maxWaitMs); } @@ -1680,7 +1680,7 @@ bool WiFiClientSecure::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint1 void WiFiClientSecure::setTimeout (unsigned long timeout) { - _ctx->setNormalTimeout(timeout); + _ctx->setRuntimeTimeout(timeout); } }; // namespace BearSSL diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index c0d8415000..8eff38ff55 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -147,7 +147,7 @@ class WiFiClientSecureCtx : public WiFiClient { // consume bytes after use (see peekBuffer) virtual void peekConsume (size_t consume) override; - void setNormalTimeout (unsigned long timeout) { _runtimeTimeout = timeout; } + void setRuntimeTimeout (unsigned long timeout) { _runtimeTimeout = timeout; } void setHandshakeTimeout (unsigned long timeout) { _handshakeTimeout = timeout; } unsigned long getHandshakeTimeout () const { return _handshakeTimeout; } From d3240777c64b9be2fa146d0ac070a215e8f36e26 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Sun, 2 Apr 2023 00:04:08 +0200 Subject: [PATCH 13/21] WiFiClient updated too --- libraries/ESP8266WiFi/src/WiFiClient.cpp | 15 +++++++-------- libraries/ESP8266WiFi/src/WiFiClient.h | 1 + .../ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp | 2 ++ .../ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index aa479a2d57..3a691e19a6 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -216,7 +216,6 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size) { return 0; } - _client->setTimeout(_timeout); return _client->write((const char*)buf, size); } @@ -229,7 +228,6 @@ size_t WiFiClient::write(Stream& stream) return 0; } // core up to 2.7.4 was equivalent to this - _client->setTimeout(_timeout); return stream.sendAll(this); } @@ -239,7 +237,6 @@ size_t WiFiClient::write_P(PGM_P buf, size_t size) { return 0; } - _client->setTimeout(_timeout); StreamConstPtr nopeek(buf, size); return nopeek.sendAll(this); } @@ -267,13 +264,11 @@ int WiFiClient::read() int WiFiClient::read(uint8_t* buf, size_t size) { - _client->setTimeout(_timeout); return (int)_client->read((char*)buf, size); } int WiFiClient::read(char* buf, size_t size) { - _client->setTimeout(_timeout); return (int)_client->read(buf, size); } @@ -282,7 +277,6 @@ int WiFiClient::peek() if (!available()) return -1; - _client->setTimeout(_timeout); return _client->peek(); } @@ -304,7 +298,6 @@ size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length) { count = length; } - _client->setTimeout(_timeout); return _client->peekBytes((char *)buffer, count); } @@ -459,7 +452,6 @@ const char* WiFiClient::peekBuffer () // return number of byte accessible by peekBuffer() size_t WiFiClient::peekAvailable () { - _client->setTimeout(_timeout); return _client? _client->peekAvailable(): 0; } @@ -469,3 +461,10 @@ void WiFiClient::peekConsume (size_t consume) if (_client) _client->peekConsume(consume); } + +void WiFiClient::setTimeout (unsigned long timeout) +{ + Client::setTimeout(timeout); + if (_client) + _client->setTimeout(timeout); +} diff --git a/libraries/ESP8266WiFi/src/WiFiClient.h b/libraries/ESP8266WiFi/src/WiFiClient.h index 41ec5d8547..21e7a709ac 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.h +++ b/libraries/ESP8266WiFi/src/WiFiClient.h @@ -64,6 +64,7 @@ class WiFiClient : public Client, public SList { // - https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rh-copy virtual std::unique_ptr clone() const; + virtual void setTimeout (unsigned long timeout) override; virtual uint8_t status(); virtual int connect(IPAddress ip, uint16_t port) override; virtual int connect(const char *host, uint16_t port) override; diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index a3b2cfb9bd..5567ea0ae4 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -1680,6 +1680,8 @@ bool WiFiClientSecure::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint1 void WiFiClientSecure::setTimeout (unsigned long timeout) { + WiFiClient::setTimeout(timeout); + if (_ctx) _ctx->setRuntimeTimeout(timeout); } diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index 8eff38ff55..298cb3c1d2 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -242,7 +242,7 @@ class WiFiClientSecureCtx : public WiFiClient { // timeout management - unsigned long _updateStreamTimeout () { return _timeout = _handshake_done? _runtimeTimeout: _handshakeTimeout; } + unsigned long _updateStreamTimeout () { setTimeout(_handshake_done? _runtimeTimeout: _handshakeTimeout); return getTimeout(); } void _set_handshake_done (bool handshake_done) { _handshake_done = handshake_done; _updateStreamTimeout(); } unsigned long _runtimeTimeout = 5000, _handshakeTimeout = 15000; From 3d796a12acb3f2a27655198569bbb693314365ae Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Sun, 2 Apr 2023 00:56:10 +0200 Subject: [PATCH 14/21] tcp context needs updated timeout for write function --- libraries/ESP8266WiFi/src/WiFiClient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index 3a691e19a6..42120e99ad 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -216,6 +216,7 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size) { return 0; } + _client->setTimeout(_timeout); // context write uses timeout return _client->write((const char*)buf, size); } From b0c75acf031bc54a8ca3edef0af203e3651d6739 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Sun, 2 Apr 2023 01:28:32 +0200 Subject: [PATCH 15/21] run_until global timeout needs reset on r/w --- libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 5567ea0ae4..1af863aa8a 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -545,6 +545,7 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { br_ssl_engine_sendrec_ack(_eng, wlen); } no_work = 0; + loopTimeout.reset(); continue; } @@ -588,6 +589,7 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { br_ssl_engine_recvrec_ack(_eng, rlen); } no_work = 0; + loopTimeout.reset(); continue; } } From 7735f373e303a55f00db2acf48d99e2aad85635e Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Sun, 2 Apr 2023 01:41:32 +0200 Subject: [PATCH 16/21] add a runtime warning when compiled at 80MHz --- libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 1af863aa8a..1d86070959 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -610,6 +610,13 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { } bool WiFiClientSecureCtx::_wait_for_handshake() { + +#if defined(DEBUG_ESP_PORT) + if constexpr (F_CPU != 160000000L) { + DEBUG_ESP_PORT.printf_P((PGM_P)PSTR("BSSL: Please enable 160MHz build\n")); + } +#endif + _set_handshake_done(false); // refreshes _timeout while (!_handshake_done && _clientConnected()) { int ret = _run_until(BR_SSL_SENDAPP); From ae64f5b7711e51206fcc44e8e0512aa7931a0535 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Sun, 2 Apr 2023 01:48:22 +0200 Subject: [PATCH 17/21] add an https client example comment for MFLN --- .../examples/BasicHttpsClient/BasicHttpsClient.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino index 5454560c21..a9b980e6d0 100644 --- a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino +++ b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino @@ -63,12 +63,11 @@ void loop() { https.setTimeout(4000); // or: client->setTimeout(4000); client->setHandshakeTimeout(10000); -#if 1 + // Try to reduce RAM footprint when SSL server allows it constexpr int sslbufsize = 1024; bool mfln = client->probeMaxFragmentLength(jigsaw_host, jigsaw_port, sslbufsize); Serial.printf("Can reduce SSL footprint to %d bytes in RAM: %s\n", sslbufsize, mfln ? "yes" : "no"); if (mfln) { client->setBufferSizes(sslbufsize, sslbufsize); } -#endif Serial.print("[HTTPS] begin...\n"); if (https.begin(*client, jigsaw_host, jigsaw_port)) { // HTTPS From e5ea7b30e45d4b12385ef95ee10e4cc12ed1c70a Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Tue, 4 Apr 2023 19:06:48 +0200 Subject: [PATCH 18/21] introduce wall time --- .../BasicHttpsClient/BasicHttpsClient.ino | 4 +- .../src/ESP8266HTTPClient.cpp | 24 +++-------- .../ESP8266HTTPClient/src/ESP8266HTTPClient.h | 15 +++++-- .../src/WiFiClientSecureBearSSL.cpp | 41 +++++++++---------- .../ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 19 +++------ 5 files changed, 44 insertions(+), 59 deletions(-) diff --git a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino index a9b980e6d0..7b7e2117d9 100644 --- a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino +++ b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino @@ -60,8 +60,8 @@ void loop() { #endif HTTPClient https; - https.setTimeout(4000); // or: client->setTimeout(4000); - client->setHandshakeTimeout(10000); + https.setWalTime(10000); // do not exceed 10s while getting data + client->setWallTime(20000); // do not exceed 20s during handshake // Try to reduce RAM footprint when SSL server allows it constexpr int sslbufsize = 1024; diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index b42b505796..3e1a345e70 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -86,9 +86,6 @@ bool HTTPClient::begin(WiFiClient &client, const String& url) { _port = (protocol == "https" ? 443 : 80); _client = client.clone(); - if (_deferredTimeout) { - _client->setTimeout(_deferredTimeout); - } return beginInternal(url, protocol.c_str()); } @@ -112,9 +109,6 @@ bool HTTPClient::begin(WiFiClient &client, const String& host, uint16_t port, co } _client = client.clone(); - if (_deferredTimeout) { - _client->setTimeout(_deferredTimeout); - } clear(); @@ -309,17 +303,12 @@ void HTTPClient::setAuthorization(String auth) } /** - * set the timeout for the TCP connection + * set the wall time for operations * @param timeout unsigned int */ -void HTTPClient::setTimeout(uint16_t timeout) +void HTTPClient::setWallTime(unsigned long wallTime) { - if(connected()) { - _client->setTimeout(timeout); - } - else { - _deferredTimeout = timeout; - } + _wallTime.reset(wallTime?: esp8266::polledTimeout::oneShotMs::neverExpires); } /** @@ -885,7 +874,6 @@ bool HTTPClient::sendHeader(const char * type) */ int HTTPClient::handleHeaderResponse() { - if(!connected()) { return HTTPC_ERROR_NOT_CONNECTED; } @@ -897,7 +885,7 @@ int HTTPClient::handleHeaderResponse() String transferEncoding; _transferEncoding = HTTPC_TE_IDENTITY; - unsigned long lastDataTime = millis(); + _wallTime.reset(); while(connected()) { size_t len = _client->available(); @@ -905,8 +893,6 @@ int HTTPClient::handleHeaderResponse() int headerSeparator = -1; String headerLine = _client->readStringUntil('\n'); - lastDataTime = millis(); - DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] RX: '%s'\n", headerLine.c_str()); if (headerLine.startsWith(F("HTTP/1."))) { @@ -984,7 +970,7 @@ int HTTPClient::handleHeaderResponse() } } else { - if((millis() - lastDataTime) > _client.get()->getTimeout()) { + if(_wallTime) { return HTTPC_ERROR_READ_TIMEOUT; } esp_yield(); diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h index f116387bb2..97a34d44d0 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -42,6 +43,8 @@ #define DEBUG_HTTPCLIENT(...) do { (void)0; } while (0) #endif +#define HTTPCLIENT_DEFAULT_TCP_TIMEOUT (5000) + /// HTTP client errors #define HTTPC_ERROR_CONNECTION_FAILED (-1) #define HTTPC_ERROR_SEND_HEADER_FAILED (-2) @@ -150,7 +153,7 @@ typedef std::unique_ptr TransportTraitsPtr; class HTTPClient { public: - HTTPClient() = default; + HTTPClient(): _wallTime(HTTPCLIENT_DEFAULT_TCP_TIMEOUT) {}; ~HTTPClient() = default; HTTPClient(HTTPClient&&) = default; HTTPClient& operator=(HTTPClient&&) = default; @@ -175,7 +178,8 @@ class HTTPClient void setAuthorization(const char * user, const char * password); void setAuthorization(const char * auth); void setAuthorization(String auth); - void setTimeout(uint16_t timeout); + void setWallTime(unsigned long wallTime); + [[deprecated("use setWallTime() instead")]] void setTimeout(unsigned long wallTime) { setWallTime(wallTime); } // Redirections void setFollowRedirects(followRedirects_t follow); @@ -254,7 +258,7 @@ class HTTPClient String _host; uint16_t _port = 0; bool _reuse = true; - uint16_t _deferredTimeout = 0; + esp8266::polledTimeout::oneShotMs _wallTime; bool _useHTTP10 = false; String _uri; @@ -312,6 +316,7 @@ int HTTPClient::writeToStream(S * output) } } else if(_transferEncoding == HTTPC_TE_CHUNKED) { int size = 0; + _wallTime.reset(); while(1) { if(!connected()) { return returnError(HTTPC_ERROR_CONNECTION_LOST); @@ -358,6 +363,10 @@ int HTTPClient::writeToStream(S * output) return returnError(HTTPC_ERROR_READ_TIMEOUT); } + if (_wallTime) { + return returnError(HTTPC_ERROR_READ_TIMEOUT); + } + esp_yield(); } } else { diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 1d86070959..84737ef283 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -31,7 +31,6 @@ extern "C" { } #include "debug.h" #include "ESP8266WiFi.h" -#include "PolledTimeout.h" #include "WiFiClient.h" #include "WiFiClientSecureBearSSL.h" #include "StackThunk.h" @@ -68,6 +67,8 @@ extern "C" { namespace BearSSL { +constexpr auto defaultWallTime = 10000UL; + void WiFiClientSecureCtx::_clear() { _sc = nullptr; _sc_svr = nullptr; @@ -80,7 +81,7 @@ void WiFiClientSecureCtx::_clear() { _now = 0; // You can override or ensure time() is correct w/configTime _ta = nullptr; setBufferSizes(16384, 512); // Minimum safe - _set_handshake_done(false); // refreshes _timeout + _handshake_done = false; _recvapp_buf = nullptr; _recvapp_len = 0; _oom_err = false; @@ -100,7 +101,7 @@ void WiFiClientSecureCtx::_clearAuthenticationSettings() { } -WiFiClientSecureCtx::WiFiClientSecureCtx() : WiFiClient() { +WiFiClientSecureCtx::WiFiClientSecureCtx() : WiFiClient(), _wallTime(defaultWallTime) { _clear(); _clearAuthenticationSettings(); _certStore = nullptr; // Don't want to remove cert store on a clear, should be long lived @@ -121,7 +122,7 @@ WiFiClientSecureCtx::~WiFiClientSecureCtx() { WiFiClientSecureCtx::WiFiClientSecureCtx(ClientContext* client, const X509List *chain, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, - const X509List *client_CA_ta, int tls_min, int tls_max) { + const X509List *client_CA_ta, int tls_min, int tls_max): _wallTime(defaultWallTime) { _clear(); _clearAuthenticationSettings(); stack_thunk_add_ref(); @@ -142,7 +143,7 @@ WiFiClientSecureCtx::WiFiClientSecureCtx(ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache, - const X509List *client_CA_ta, int tls_min, int tls_max) { + const X509List *client_CA_ta, int tls_min, int tls_max): _wallTime(defaultWallTime) { _clear(); _clearAuthenticationSettings(); stack_thunk_add_ref(); @@ -201,13 +202,10 @@ bool WiFiClientSecureCtx::stop(unsigned int maxWaitMs) { } bool WiFiClientSecureCtx::flush(unsigned int maxWaitMs) { - auto savedRuntime = _runtimeTimeout; - auto savedHandshake = _handshakeTimeout; - _runtimeTimeout = maxWaitMs; - _handshakeTimeout = maxWaitMs; + auto savedTimeout = _timeout; + _timeout = std::max(1U, maxWaitMs); (void) _run_until(BR_SSL_SENDAPP); - _runtimeTimeout = savedRuntime; - _handshakeTimeout = savedHandshake; + _timeout = savedTimeout; return WiFiClient::flush(maxWaitMs); } @@ -248,7 +246,7 @@ void WiFiClientSecureCtx::_freeSSL() { _recvapp_buf = nullptr; _recvapp_len = 0; // This connection is toast - _set_handshake_done(false); // refreshes _timeout + _handshake_done = false; } bool WiFiClientSecureCtx::_clientConnected() { @@ -463,7 +461,6 @@ size_t WiFiClientSecureCtx::peekBytes(uint8_t *buffer, size_t length) { return 0; } - _updateStreamTimeout(); _startMillis = millis(); while ((_pollRecvBuffer() < (int)length) && ((millis() - _startMillis) < _timeout)) { yield(); @@ -486,10 +483,7 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { return -1; } - // _run_until() is called prior to inherited read/write methods - // -> refreshing _timeout here, which is also used by ancestors - DEBUG_BSSL("_run_until starts, timeout=%lu\n", _updateStreamTimeout()); - esp8266::polledTimeout::oneShotMs loopTimeout(_updateStreamTimeout()); + esp8266::polledTimeout::oneShotMs loopTimeout(_timeout); for (int no_work = 0; blocking || no_work < 2;) { optimistic_yield(100); @@ -617,7 +611,8 @@ bool WiFiClientSecureCtx::_wait_for_handshake() { } #endif - _set_handshake_done(false); // refreshes _timeout + _wallTime.reset(); + _handshake_done = false; while (!_handshake_done && _clientConnected()) { int ret = _run_until(BR_SSL_SENDAPP); if (ret < 0) { @@ -625,7 +620,11 @@ bool WiFiClientSecureCtx::_wait_for_handshake() { break; } if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { - _set_handshake_done(true); // refreshes _timeout + _handshake_done = true; + } + if (_wallTime) { + DEBUG_BSSL("handshake too long\n"); + break; } optimistic_yield(1000); } @@ -1221,8 +1220,6 @@ bool WiFiClientSecureCtx::_connectSSL(const char* hostName) { _x509_insecure = nullptr; _x509_knownkey = nullptr; - // _timeout has been refreshed to normal operation as _handshake_done turned to true - return ret; } @@ -1691,7 +1688,7 @@ void WiFiClientSecure::setTimeout (unsigned long timeout) { WiFiClient::setTimeout(timeout); if (_ctx) - _ctx->setRuntimeTimeout(timeout); + _ctx->setTimeout(timeout); } }; // namespace BearSSL diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index 298cb3c1d2..d3156cbf6e 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -28,6 +28,7 @@ #include #include "BearSSLHelpers.h" #include "CertStoreBearSSL.h" +#include "PolledTimeout.h" namespace BearSSL { @@ -147,9 +148,8 @@ class WiFiClientSecureCtx : public WiFiClient { // consume bytes after use (see peekBuffer) virtual void peekConsume (size_t consume) override; - void setRuntimeTimeout (unsigned long timeout) { _runtimeTimeout = timeout; } - void setHandshakeTimeout (unsigned long timeout) { _handshakeTimeout = timeout; } - unsigned long getHandshakeTimeout () const { return _handshakeTimeout; } + // install a wall-time used during handshake + void setWallTime (unsigned long wallTime) { _wallTime.reset(wallTime?: esp8266::polledTimeout::oneShotMs::neverExpires); } protected: bool _connectSSL(const char *hostName); // Do initial SSL handshake @@ -240,13 +240,7 @@ class WiFiClientSecureCtx : public WiFiClient { uint8_t *_streamLoad(Stream& stream, size_t size); - // timeout management - - unsigned long _updateStreamTimeout () { setTimeout(_handshake_done? _runtimeTimeout: _handshakeTimeout); return getTimeout(); } - void _set_handshake_done (bool handshake_done) { _handshake_done = handshake_done; _updateStreamTimeout(); } - - unsigned long _runtimeTimeout = 5000, _handshakeTimeout = 15000; - + esp8266::polledTimeout::oneShotMs _wallTime; }; // class WiFiClientSecureCtx @@ -373,9 +367,8 @@ class WiFiClientSecure : public WiFiClient { // override setTimeout and forward to context virtual void setTimeout (unsigned long timeout) override; - // allowing user to set timeout used during handshake - void setHandshakeTimeout (unsigned long timeout) { _ctx->setHandshakeTimeout(timeout); } - unsigned long getHandshakeTimeout () const { return _ctx->getHandshakeTimeout(); } + // install a wall-time used during handshake + void setWallTime (unsigned long wallTime) { _ctx->setWallTime(wallTime); } private: std::shared_ptr _ctx; From 1e0cfff7cab808fe14a053748585d092aeea6b0a Mon Sep 17 00:00:00 2001 From: david gauchard Date: Tue, 4 Apr 2023 19:16:14 +0200 Subject: [PATCH 19/21] typo --- .../examples/BasicHttpsClient/BasicHttpsClient.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino index 7b7e2117d9..3eb3c59acc 100644 --- a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino +++ b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino @@ -60,7 +60,7 @@ void loop() { #endif HTTPClient https; - https.setWalTime(10000); // do not exceed 10s while getting data + https.setWallTime(10000); // do not exceed 10s while getting data client->setWallTime(20000); // do not exceed 20s during handshake // Try to reduce RAM footprint when SSL server allows it From 19420e0513d612507759f36bb9158626375e4f3d Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Tue, 4 Apr 2023 23:27:13 +0200 Subject: [PATCH 20/21] fix CI --- libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp | 2 +- libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp index 9cd5d62801..532cfc8fb0 100755 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp @@ -164,7 +164,7 @@ HTTPUpdateResult ESP8266HTTPUpdate::handleUpdate(HTTPClient& http, const String& // use HTTP/1.0 for update since the update handler not support any transfer Encoding http.useHTTP10(true); - http.setTimeout(_httpClientTimeout); + http.setWallTime(_httpClientWallTime); http.setFollowRedirects(_followRedirects); http.setUserAgent(F("ESP8266-http-Update")); http.addHeader(F("x-ESP8266-Chip-ID"), String(ESP.getChipId())); diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h index 803988d3be..39eb88f128 100755 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h @@ -132,9 +132,8 @@ class ESP8266HTTPUpdate int getLastError(void); String getLastErrorString(void); - void setClientTimeout(int timeout) { - _httpClientTimeout = timeout; - } + [[deprecated("use setWallTime()")]] void setClientTimeout(int wallTime) { setWallTime(wallTime); } + void setWallTime(int wallTime) { _httpWallTime = wallTime; } protected: t_httpUpdate_return handleUpdate(HTTPClient& http, const String& currentVersion, bool spiffs = false); bool runUpdate(Stream& in, uint32_t size, const String& md5, int command = U_FLASH); From ac9d961789ad59defe0531747140b05805615918 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Wed, 5 Apr 2023 01:06:07 +0200 Subject: [PATCH 21/21] fixing --- .../ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino | 2 +- libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp | 8 ++++---- libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino b/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino index b9da7f8cb4..ed7f38f61b 100644 --- a/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino +++ b/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino @@ -27,7 +27,7 @@ void setup() { Serial.println(); - ESPhttpUpdate.setClientTimeout(2000); // default was 8000 + ESPhttpUpdate.setWallTime(2000); // default was 8000 WiFi.mode(WIFI_STA); WiFiMulti.addAP(APSSID, APPSK); diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp index 532cfc8fb0..256d971560 100755 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp @@ -28,12 +28,12 @@ #include ESP8266HTTPUpdate::ESP8266HTTPUpdate(void) - : _httpClientTimeout(8000) + : _httpWallTime(8000) { } -ESP8266HTTPUpdate::ESP8266HTTPUpdate(int httpClientTimeout) - : _httpClientTimeout(httpClientTimeout) +ESP8266HTTPUpdate::ESP8266HTTPUpdate(int httpWallTime) + : _httpWallTime(httpWallTime) { } @@ -164,7 +164,7 @@ HTTPUpdateResult ESP8266HTTPUpdate::handleUpdate(HTTPClient& http, const String& // use HTTP/1.0 for update since the update handler not support any transfer Encoding http.useHTTP10(true); - http.setWallTime(_httpClientWallTime); + http.setWallTime(_httpWallTime); http.setFollowRedirects(_followRedirects); http.setUserAgent(F("ESP8266-http-Update")); http.addHeader(F("x-ESP8266-Chip-ID"), String(ESP.getChipId())); diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h index 39eb88f128..45ae03349f 100755 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h @@ -153,7 +153,7 @@ class ESP8266HTTPUpdate String _auth; String _md5Sum; private: - int _httpClientTimeout; + unsigned long _httpWallTime; followRedirects_t _followRedirects = HTTPC_DISABLE_FOLLOW_REDIRECTS; // Callbacks