1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

Honor timeout in HTTPClient (#6056)

* check for timeout in ESP8266HTTPClient::writeToStreamDataBlock
This commit is contained in:
david gauchard 2019-05-06 21:26:17 +02:00 committed by GitHub
parent ac53c2998e
commit e67cc90b7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 89 deletions

View File

@ -63,31 +63,35 @@ void loop() {
// create buffer for read // create buffer for read
uint8_t buff[128] = { 0 }; uint8_t buff[128] = { 0 };
#if 0
// with API
Serial.println(http.getString());
#else
// or "by hand"
// get tcp stream // get tcp stream
WiFiClient * stream = &client; WiFiClient * stream = &client;
// read all data from server // read all data from server
while (http.connected() && (len > 0 || len == -1)) { while (http.connected() && (len > 0 || len == -1)) {
// get available data size // read up to 128 byte
size_t size = stream->available(); int c = stream->readBytes(buff, std::min((size_t)len, sizeof(buff)));
Serial.printf("readBytes: %d\n", c);
if (size) { if (!c) {
// read up to 128 byte Serial.println("read timeout");
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); }
// write it to Serial // write it to Serial
Serial.write(buff, c); Serial.write(buff, c);
if (len > 0) { if (len > 0) {
len -= c; len -= c;
}
} }
delay(1);
} }
#endif
Serial.println(); Serial.println();
Serial.print("[HTTP] connection closed or file end.\n"); Serial.print("[HTTP] connection closed or file end.\n");
} }
} else { } else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
@ -96,5 +100,5 @@ void loop() {
http.end(); http.end();
} }
delay(10000); delay(60000);
} }

View File

@ -847,7 +847,7 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size)
} }
} else { } 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); return returnError(HTTPC_ERROR_TOO_LESS_RAM);
} }
@ -1033,7 +1033,7 @@ String HTTPClient::errorToString(int error)
case HTTPC_ERROR_NO_HTTP_SERVER: case HTTPC_ERROR_NO_HTTP_SERVER:
return F("no HTTP server"); return F("no HTTP server");
case HTTPC_ERROR_TOO_LESS_RAM: case HTTPC_ERROR_TOO_LESS_RAM:
return F("too less ram"); return F("not enough ram");
case HTTPC_ERROR_ENCODING: case HTTPC_ERROR_ENCODING:
return F("Transfer-Encoding not supported"); return F("Transfer-Encoding not supported");
case HTTPC_ERROR_STREAM_WRITE: case HTTPC_ERROR_STREAM_WRITE:
@ -1346,7 +1346,7 @@ int HTTPClient::handleHeaderResponse()
int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) int HTTPClient::writeToStreamDataBlock(Stream * stream, int size)
{ {
int buff_size = HTTP_TCP_BUFFER_SIZE; int buff_size = HTTP_TCP_BUFFER_SIZE;
int len = size; int len = size; // left size to read
int bytesWritten = 0; int bytesWritten = 0;
// if possible create smaller buffer then HTTP_TCP_BUFFER_SIZE // if possible create smaller buffer then HTTP_TCP_BUFFER_SIZE
@ -1357,93 +1357,85 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size)
// create buffer for read // create buffer for read
uint8_t * buff = (uint8_t *) malloc(buff_size); uint8_t * buff = (uint8_t *) malloc(buff_size);
if(buff) { if(!buff) {
// read all data from server DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] not enough ram! need %d\n", HTTP_TCP_BUFFER_SIZE);
while(connected() && (len > 0 || len == -1)) { return HTTPC_ERROR_TOO_LESS_RAM;
}
// get available data size // read all data from server
size_t sizeAvailable = _client->available(); while(connected() && (len > 0 || len == -1))
{
int readBytes = len;
if(sizeAvailable) { // not read more the buffer can handle
if(readBytes > buff_size) {
readBytes = buff_size;
}
int readBytes = sizeAvailable; // 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;
}
// read only the asked bytes // write it to Stream
if(len > 0 && readBytes > len) { int bytesWrite = stream->write(buff, bytesRead);
readBytes = len; bytesWritten += bytesWrite;
}
// not read more the buffer can handle // are all Bytes a writen to stream ?
if(readBytes > buff_size) { if(bytesWrite != bytesRead) {
readBytes = buff_size; DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] short write asked for %d but got %d retry...\n", bytesRead, bytesWrite);
}
// read data // check for write error
int bytesRead = _client->readBytes(buff, readBytes); if(stream->getWriteError()) {
DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] stream write error %d\n", stream->getWriteError());
// write it to Stream //reset write error for retry
int bytesWrite = stream->write(buff, bytesRead); stream->clearWriteError();
bytesWritten += bytesWrite; }
// are all Bytes a writen to stream ? // some time for the stream
if(bytesWrite != bytesRead) { delay(1);
DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] short write asked for %d but got %d retry...\n", bytesRead, bytesWrite);
// check for write error int leftBytes = (bytesRead - bytesWrite);
if(stream->getWriteError()) {
DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] stream write error %d\n", stream->getWriteError());
//reset write error for retry // retry to send the missed bytes
stream->clearWriteError(); bytesWrite = stream->write((buff + bytesWrite), leftBytes);
} bytesWritten += bytesWrite;
// some time for the stream if(bytesWrite != leftBytes) {
delay(1); // failed again
DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] short write asked for %d but got %d failed.\n", leftBytes, bytesWrite);
int leftBytes = (readBytes - bytesWrite); free(buff);
return HTTPC_ERROR_STREAM_WRITE;
// 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;
}
// count bytes to read left
if(len > 0) {
len -= readBytes;
}
delay(0);
} else {
delay(1);
} }
} }
free(buff); // check for write error
if(stream->getWriteError()) {
DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] connection closed or file end (written: %d).\n", bytesWritten); DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] stream write error %d\n", stream->getWriteError());
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; return HTTPC_ERROR_STREAM_WRITE;
} }
} else { // count bytes to read left
DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] too less ram! need %d\n", HTTP_TCP_BUFFER_SIZE); if(len > 0) {
return HTTPC_ERROR_TOO_LESS_RAM; len -= bytesRead;
}
delay(0);
}
free(buff);
DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] connection closed or file end (written: %d).\n", bytesWritten);
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; return bytesWritten;