Skip to content

Commit 6debc5c

Browse files
Fix timeout in WebServer::_uploadReadByte and handleClient() (espressif#9990) (espressif#9991)
* Fix timeout in WebServer::_uploadReadByte and set timeout handleClient() Fixes: espressif#9990 * Set HTTP_MAX_CLOSE_WAIT equal to other HTTP_xxx_WAIT values * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent 4e3523c commit 6debc5c

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

Diff for: libraries/WebServer/src/Parsing.cpp

+34-4
Original file line numberDiff line numberDiff line change
@@ -347,11 +347,41 @@ int WebServer::_uploadReadByte(NetworkClient &client) {
347347
int res = client.read();
348348

349349
if (res < 0) {
350-
while (!client.available() && client.connected()) {
351-
delay(2);
352-
}
350+
// keep trying until you either read a valid byte or timeout
351+
const unsigned long startMillis = millis();
352+
const long timeoutIntervalMillis = client.getTimeout();
353+
bool timedOut = false;
354+
for (;;) {
355+
if (!client.connected()) {
356+
return -1;
357+
}
358+
// loosely modeled after blinkWithoutDelay pattern
359+
while (!timedOut && !client.available() && client.connected()) {
360+
delay(2);
361+
timedOut = (millis() - startMillis) >= timeoutIntervalMillis;
362+
}
353363

354-
res = client.read();
364+
res = client.read();
365+
if (res >= 0) {
366+
return res; // exit on a valid read
367+
}
368+
// NOTE: it is possible to get here and have all of the following
369+
// assertions hold true
370+
//
371+
// -- client.available() > 0
372+
// -- client.connected == true
373+
// -- res == -1
374+
//
375+
// a simple retry strategy overcomes this which is to say the
376+
// assertion is not permanent, but the reason that this works
377+
// is elusive, and possibly indicative of a more subtle underlying
378+
// issue
379+
380+
timedOut = (millis() - startMillis) >= timeoutIntervalMillis;
381+
if (timedOut) {
382+
return res; // exit on a timeout
383+
}
384+
}
355385
}
356386

357387
return res;

Diff for: libraries/WebServer/src/WebServer.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -432,10 +432,8 @@ void WebServer::handleClient() {
432432
case HC_WAIT_READ:
433433
// Wait for data from client to become available
434434
if (_currentClient.available()) {
435+
_currentClient.setTimeout(HTTP_MAX_SEND_WAIT); /* / 1000 removed, WifiClient setTimeout changed to ms */
435436
if (_parseRequest(_currentClient)) {
436-
// because HTTP_MAX_SEND_WAIT is expressed in milliseconds,
437-
// it must be divided by 1000
438-
_currentClient.setTimeout(HTTP_MAX_SEND_WAIT); /* / 1000 removed, WifiClient setTimeout changed to ms */
439437
_contentLength = CONTENT_LENGTH_NOT_SET;
440438
_handleRequest();
441439

Diff for: libraries/WebServer/src/WebServer.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ enum HTTPAuthMethod {
6666
#define HTTP_MAX_DATA_WAIT 5000 //ms to wait for the client to send the request
6767
#define HTTP_MAX_POST_WAIT 5000 //ms to wait for POST data to arrive
6868
#define HTTP_MAX_SEND_WAIT 5000 //ms to wait for data chunk to be ACKed
69-
#define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection
69+
#define HTTP_MAX_CLOSE_WAIT 5000 //ms to wait for the client to close the connection
7070
#define HTTP_MAX_BASIC_AUTH_LEN 256 // maximum length of a basic Auth base64 encoded username:password string
7171

7272
#define CONTENT_LENGTH_UNKNOWN ((size_t) - 1)
@@ -88,7 +88,7 @@ typedef struct {
8888
HTTPRawStatus status;
8989
size_t totalSize; // content size
9090
size_t currentSize; // size of data currently in buf
91-
uint8_t buf[HTTP_UPLOAD_BUFLEN];
91+
uint8_t buf[HTTP_RAW_BUFLEN];
9292
void *data; // additional data
9393
} HTTPRaw;
9494

0 commit comments

Comments
 (0)