From 45fc796cced522492e95e58e7a944668fc5954af Mon Sep 17 00:00:00 2001 From: TD-er Date: Fri, 5 Jul 2024 21:55:22 +0200 Subject: [PATCH] Fix timeout in WebServer::_uploadReadByte and set timeout handleClient() Fixes: #9990 --- libraries/WebServer/src/Parsing.cpp | 38 +++++++++++++++++++++++---- libraries/WebServer/src/WebServer.cpp | 4 +-- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/libraries/WebServer/src/Parsing.cpp b/libraries/WebServer/src/Parsing.cpp index 200244e6848..453cae1e6e0 100644 --- a/libraries/WebServer/src/Parsing.cpp +++ b/libraries/WebServer/src/Parsing.cpp @@ -345,13 +345,41 @@ void WebServer::_uploadWriteByte(uint8_t b) { int WebServer::_uploadReadByte(NetworkClient &client) { int res = client.read(); - + if (res < 0) { - while (!client.available() && client.connected()) { - delay(2); - } + // keep trying until you either read a valid byte or timeout + const unsigned long startMillis = millis(); + const long timeoutIntervalMillis = client.getTimeout(); + bool timedOut = false; + for(;;) { + if (!client.connected()) return -1; + // loosely modeled after blinkWithoutDelay pattern + while(!timedOut && !client.available() && client.connected()){ + delay(2); + timedOut = (millis() - startMillis) >= timeoutIntervalMillis; + } - res = client.read(); + res = client.read(); + if(res >= 0) { + return res; // exit on a valid read + } + // NOTE: it is possible to get here and have all of the following + // assertions hold true + // + // -- client.available() > 0 + // -- client.connected == true + // -- res == -1 + // + // a simple retry strategy overcomes this which is to say the + // assertion is not permanent, but the reason that this works + // is elusive, and possibly indicative of a more subtle underlying + // issue + + timedOut = (millis() - startMillis) >= timeoutIntervalMillis; + if (timedOut) { + return res; // exit on a timeout + } + } } return res; diff --git a/libraries/WebServer/src/WebServer.cpp b/libraries/WebServer/src/WebServer.cpp index 92623b79c01..3996d3bdb0e 100644 --- a/libraries/WebServer/src/WebServer.cpp +++ b/libraries/WebServer/src/WebServer.cpp @@ -432,10 +432,8 @@ void WebServer::handleClient() { case HC_WAIT_READ: // Wait for data from client to become available if (_currentClient.available()) { + _currentClient.setTimeout(HTTP_MAX_SEND_WAIT); /* / 1000 removed, WifiClient setTimeout changed to ms */ if (_parseRequest(_currentClient)) { - // because HTTP_MAX_SEND_WAIT is expressed in milliseconds, - // it must be divided by 1000 - _currentClient.setTimeout(HTTP_MAX_SEND_WAIT); /* / 1000 removed, WifiClient setTimeout changed to ms */ _contentLength = CONTENT_LENGTH_NOT_SET; _handleRequest();