From 127b3c4ab15c1ba995fdc4630e98234c4f9a46e7 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Mon, 6 May 2019 10:43:55 +0200 Subject: [PATCH 1/5] check for timeout in ESP8266HTTPClient::writeToStreamDataBlock --- libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index 2c9542cb03..0aff17e01d 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -1380,6 +1380,11 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) // read data int bytesRead = _client->readBytes(buff, readBytes); + if (!bytesRead) + { + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] input stream timeout\n"); + return HTTPC_ERROR_READ_TIMEOUT; + } // write it to Stream int bytesWrite = stream->write(buff, bytesRead); From c6d7aa0dbd06eb22d8e20c417a39698a046fd83e Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Mon, 6 May 2019 11:27:50 +0200 Subject: [PATCH 2/5] fix example --- .../StreamHttpClient/StreamHttpClient.ino | 31 ++++++++++--------- .../src/ESP8266HTTPClient.cpp | 21 +++---------- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino b/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino index 626dbe7e3a..9b2fa66a0e 100644 --- a/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino +++ b/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino @@ -63,31 +63,34 @@ void loop() { // create buffer for read uint8_t buff[128] = { 0 }; +#if 0 + // with API + Serial.println(http.getString()); +#else + // or "by hand" + // get tcp stream WiFiClient * stream = &client; // read all data from server while (http.connected() && (len > 0 || len == -1)) { - // get available data size - size_t size = stream->available(); - - if (size) { - // read up to 128 byte - int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); + // read up to 128 byte + int c = stream->readBytes(buff, std::min((size_t)len, sizeof(buff))); + Serial.printf("readBytes: %d\n", c); + if (!c) + Serial.println("read timeout"); - // write it to Serial - Serial.write(buff, c); + // write it to Serial + Serial.write(buff, c); - if (len > 0) { - len -= c; - } + if (len > 0) { + len -= c; } - delay(1); } +#endif Serial.println(); Serial.print("[HTTP] connection closed or file end.\n"); - } } else { Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); @@ -96,5 +99,5 @@ void loop() { http.end(); } - delay(10000); + delay(60000); } diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index 0aff17e01d..c8b9ab5680 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -1346,7 +1346,7 @@ int HTTPClient::handleHeaderResponse() int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) { int buff_size = HTTP_TCP_BUFFER_SIZE; - int len = size; + int len = size; // left size to read int bytesWritten = 0; // if possible create smaller buffer then HTTP_TCP_BUFFER_SIZE @@ -1361,17 +1361,8 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) // read all data from server while(connected() && (len > 0 || len == -1)) { - // get available data size - size_t sizeAvailable = _client->available(); - - if(sizeAvailable) { - - int readBytes = sizeAvailable; - - // read only the asked bytes - if(len > 0 && readBytes > len) { - readBytes = len; - } + { + int readBytes = len; // not read more the buffer can handle if(readBytes > buff_size) { @@ -1405,7 +1396,7 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) // some time for the stream delay(1); - int leftBytes = (readBytes - bytesWrite); + int leftBytes = (bytesRead - bytesWrite); // retry to send the missed bytes bytesWrite = stream->write((buff + bytesWrite), leftBytes); @@ -1428,12 +1419,10 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) // count bytes to read left if(len > 0) { - len -= readBytes; + len -= bytesRead; } delay(0); - } else { - delay(1); } } From a2d5d7cc1f6f3cd27417df7f835cf4cc64222007 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Mon, 6 May 2019 13:27:30 +0200 Subject: [PATCH 3/5] example style --- .../examples/StreamHttpClient/StreamHttpClient.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino b/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino index 9b2fa66a0e..7ed0cd5294 100644 --- a/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino +++ b/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino @@ -77,8 +77,9 @@ void loop() { // read up to 128 byte int c = stream->readBytes(buff, std::min((size_t)len, sizeof(buff))); Serial.printf("readBytes: %d\n", c); - if (!c) + if (!c) { Serial.println("read timeout"); + } // write it to Serial Serial.write(buff, c); From 0ee47584d11abd838eb58561f1f9de77b7fa3304 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Mon, 6 May 2019 16:27:38 +0200 Subject: [PATCH 4/5] add missing free(), rework if() structure --- .../src/ESP8266HTTPClient.cpp | 126 +++++++++--------- 1 file changed, 62 insertions(+), 64 deletions(-) diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index c8b9ab5680..3179225dc5 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -847,7 +847,7 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) } } else { - DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] too less ram! need %d\n", HTTP_TCP_BUFFER_SIZE); + DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] not enough ram! need %d\n", HTTP_TCP_BUFFER_SIZE); return returnError(HTTPC_ERROR_TOO_LESS_RAM); } @@ -1357,87 +1357,85 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) // create buffer for read uint8_t * buff = (uint8_t *) malloc(buff_size); - if(buff) { - // read all data from server - while(connected() && (len > 0 || len == -1)) { + if(!buff) { + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] too less ram! need %d\n", HTTP_TCP_BUFFER_SIZE); + return HTTPC_ERROR_TOO_LESS_RAM; + } - { - int readBytes = len; + // read all data from server + while(connected() && (len > 0 || len == -1)) + { + int readBytes = len; - // not read more the buffer can handle - if(readBytes > buff_size) { - readBytes = buff_size; - } + // not read more the buffer can handle + if(readBytes > buff_size) { + readBytes = buff_size; + } - // read data - int bytesRead = _client->readBytes(buff, readBytes); - if (!bytesRead) - { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] input stream timeout\n"); - return HTTPC_ERROR_READ_TIMEOUT; - } + // read data + int bytesRead = _client->readBytes(buff, readBytes); + if (!bytesRead) + { + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] input stream timeout\n"); + free(buff); + return HTTPC_ERROR_READ_TIMEOUT; + } - // write it to Stream - int bytesWrite = stream->write(buff, bytesRead); - bytesWritten += bytesWrite; + // write it to Stream + int bytesWrite = stream->write(buff, bytesRead); + bytesWritten += bytesWrite; - // are all Bytes a writen to stream ? - if(bytesWrite != bytesRead) { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] short write asked for %d but got %d retry...\n", bytesRead, bytesWrite); + // are all Bytes a writen to stream ? + if(bytesWrite != bytesRead) { + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] short write asked for %d but got %d retry...\n", bytesRead, bytesWrite); - // check for write error - if(stream->getWriteError()) { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] stream write error %d\n", stream->getWriteError()); + // check for write error + if(stream->getWriteError()) { + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] stream write error %d\n", stream->getWriteError()); - //reset write error for retry - stream->clearWriteError(); - } + //reset write error for retry + stream->clearWriteError(); + } - // some time for the stream - delay(1); + // some time for the stream + delay(1); - int leftBytes = (bytesRead - bytesWrite); + int leftBytes = (bytesRead - bytesWrite); - // retry to send the missed bytes - bytesWrite = stream->write((buff + bytesWrite), leftBytes); - bytesWritten += bytesWrite; + // retry to send the missed bytes + bytesWrite = stream->write((buff + bytesWrite), leftBytes); + bytesWritten += bytesWrite; - if(bytesWrite != leftBytes) { - // failed again - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] short write asked for %d but got %d failed.\n", leftBytes, bytesWrite); - free(buff); - return HTTPC_ERROR_STREAM_WRITE; - } - } - - // check for write error - if(stream->getWriteError()) { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] stream write error %d\n", stream->getWriteError()); - free(buff); - return HTTPC_ERROR_STREAM_WRITE; - } + if(bytesWrite != leftBytes) { + // failed again + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] short write asked for %d but got %d failed.\n", leftBytes, bytesWrite); + free(buff); + return HTTPC_ERROR_STREAM_WRITE; + } + } - // count bytes to read left - if(len > 0) { - len -= bytesRead; - } + // check for write error + if(stream->getWriteError()) { + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] stream write error %d\n", stream->getWriteError()); + free(buff); + return HTTPC_ERROR_STREAM_WRITE; + } - delay(0); - } + // count bytes to read left + if(len > 0) { + len -= bytesRead; } - free(buff); + delay(0); + } - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] connection closed or file end (written: %d).\n", bytesWritten); + free(buff); - if((size > 0) && (size != bytesWritten)) { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] bytesWritten %d and size %d mismatch!.\n", bytesWritten, size); - return HTTPC_ERROR_STREAM_WRITE; - } + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] connection closed or file end (written: %d).\n", bytesWritten); - } else { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] too less ram! need %d\n", HTTP_TCP_BUFFER_SIZE); - return HTTPC_ERROR_TOO_LESS_RAM; + if((size > 0) && (size != bytesWritten)) { + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] bytesWritten %d and size %d mismatch!.\n", bytesWritten, size); + return HTTPC_ERROR_STREAM_WRITE; } return bytesWritten; From ed39699b7005dd2f81b2260c86a30e44ae505ebe Mon Sep 17 00:00:00 2001 From: david gauchard Date: Mon, 6 May 2019 16:36:30 +0200 Subject: [PATCH 5/5] fix user message --- libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index 3179225dc5..8d7880e4ef 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -1033,7 +1033,7 @@ String HTTPClient::errorToString(int error) case HTTPC_ERROR_NO_HTTP_SERVER: return F("no HTTP server"); case HTTPC_ERROR_TOO_LESS_RAM: - return F("too less ram"); + return F("not enough ram"); case HTTPC_ERROR_ENCODING: return F("Transfer-Encoding not supported"); case HTTPC_ERROR_STREAM_WRITE: @@ -1358,7 +1358,7 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) uint8_t * buff = (uint8_t *) malloc(buff_size); if(!buff) { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] too less ram! need %d\n", HTTP_TCP_BUFFER_SIZE); + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] not enough ram! need %d\n", HTTP_TCP_BUFFER_SIZE); return HTTPC_ERROR_TOO_LESS_RAM; }