Skip to content

Commit 69a869c

Browse files
HTTPClient: add readChunkHeader() and readChunkTrailer() methods
These new methods will be reused in the next commit when an implementation of the Stream class will be added to the HTTPClient class. HTTPClient::writeToStream() is being refactored to use the new methods.
1 parent de30762 commit 69a869c

File tree

2 files changed

+67
-15
lines changed

2 files changed

+67
-15
lines changed

libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp

+63-15
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ void HTTPClient::clear()
139139
_size = -1;
140140
_headers.clear();
141141
_location.clear();
142+
_chunkHeader.clear();
143+
_chunkLen = 0;
142144
_payload.reset();
143145
}
144146

@@ -956,22 +958,15 @@ int HTTPClient::writeToStream(Stream * stream)
956958
if(!connected()) {
957959
return returnError(HTTPC_ERROR_CONNECTION_LOST);
958960
}
959-
String chunkHeader = _client->readStringUntil('\n');
960-
961-
if(chunkHeader.length() <= 0) {
961+
if(!readChunkHeader()) {
962962
return returnError(HTTPC_ERROR_READ_TIMEOUT);
963963
}
964-
965-
chunkHeader.trim(); // remove \r
966-
967-
// read size of chunk
968-
len = (uint32_t) strtol((const char *) chunkHeader.c_str(), NULL, 16);
969-
size += len;
970-
DEBUG_HTTPCLIENT("[HTTP-Client] read chunk len: %d\n", len);
964+
size += _chunkLen;
965+
DEBUG_HTTPCLIENT("[HTTP-Client] read chunk len: %d\n", _chunkLen);
971966

972967
// data left?
973-
if(len > 0) {
974-
int r = writeToStreamDataBlock(stream, len);
968+
if(_chunkLen > 0) {
969+
int r = writeToStreamDataBlock(stream, _chunkLen);
975970
if(r < 0) {
976971
// error in writeToStreamDataBlock
977972
return returnError(r);
@@ -992,9 +987,7 @@ int HTTPClient::writeToStream(Stream * stream)
992987
}
993988

994989
// read trailing \r\n at the end of the chunk
995-
char buf[2];
996-
auto trailing_seq_len = _client->readBytes((uint8_t*)buf, 2);
997-
if (trailing_seq_len != 2 || buf[0] != '\r' || buf[1] != '\n') {
990+
if (!readChunkTrailer()) {
998991
return returnError(HTTPC_ERROR_READ_TIMEOUT);
999992
}
1000993

@@ -1496,6 +1489,61 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size)
14961489
return bytesWritten;
14971490
}
14981491

1492+
/**
1493+
* Read header of next chunk in HTTP response using chunked encoding
1494+
* @param blocking bool whether this method is allowed to block
1495+
* @return boolean value indicating whether a complete header could be read
1496+
*/
1497+
bool HTTPClient::readChunkHeader(bool blocking)
1498+
{
1499+
if (blocking) {
1500+
_chunkHeader += _client->readStringUntil('\n');
1501+
if (_chunkHeader.length() == 0) {
1502+
return false;
1503+
}
1504+
} else {
1505+
while (_client->available() && !_chunkHeader.endsWith("\n")) {
1506+
_chunkHeader += (char) _client->read();
1507+
}
1508+
if (!_chunkHeader.endsWith("\n")) {
1509+
return false;
1510+
}
1511+
}
1512+
1513+
// read size of chunk
1514+
_chunkLen = (uint32_t) strtol((const char *) _chunkHeader.c_str(), NULL,
1515+
16);
1516+
1517+
return true;
1518+
}
1519+
1520+
/**
1521+
* Read trailer of current chunk in HTTP response using chunked encoding
1522+
* @param blocking bool whether this method is allowed to block
1523+
* @return boolean value indicating whether the complete trailer could be read
1524+
*/
1525+
bool HTTPClient::readChunkTrailer(bool blocking)
1526+
{
1527+
uint8_t buf[2];
1528+
1529+
if (blocking || (_client->available() >= 2)) {
1530+
auto trailing_seq_len = _client->readBytes((uint8_t *) buf, 2);
1531+
1532+
if (trailing_seq_len != 2 || buf[0] != '\r' || buf[1] != '\n') {
1533+
return false;
1534+
} else {
1535+
/* Clear _chunkHeader to indicate that the current chunk has been
1536+
* completely read, and reset _chunkLen to indicate that the next
1537+
* chunk header has not been read yet. */
1538+
_chunkHeader.clear();
1539+
_chunkLen = 0;
1540+
return true;
1541+
}
1542+
} else {
1543+
return false;
1544+
}
1545+
}
1546+
14991547
/**
15001548
* called to handle error return, may disconnect the connection if still exists
15011549
* @param error

libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h

+4
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ class HTTPClient
225225
int handleHeaderResponse();
226226
int writeToStreamDataBlock(Stream * stream, int len);
227227

228+
bool readChunkHeader(bool blocking = true);
229+
bool readChunkTrailer(bool blocking = true);
228230

229231
#if HTTPCLIENT_1_1_COMPATIBLE
230232
TransportTraitsPtr _transportTraits;
@@ -257,6 +259,8 @@ class HTTPClient
257259
uint16_t _redirectLimit = 10;
258260
String _location;
259261
transferEncoding_t _transferEncoding = HTTPC_TE_IDENTITY;
262+
String _chunkHeader;
263+
uint32_t _chunkLen = 0;
260264
std::unique_ptr<StreamString> _payload;
261265
};
262266

0 commit comments

Comments
 (0)