@@ -1076,12 +1076,14 @@ String HTTPClient::errorToString(int error)
10761076void HTTPClient::addHeader (const String& name, const String& value, bool first, bool replace)
10771077{
10781078 // not allow set of Header handled by code
1079- if (!name.equalsIgnoreCase (F (" Connection" )) &&
1080- !name.equalsIgnoreCase (F (" User-Agent" )) &&
1081- !name.equalsIgnoreCase (F (" Host" )) &&
1082- !(name.equalsIgnoreCase (F (" Authorization" )) && _base64Authorization.length ())){
1083-
1084- String headerLine = name;
1079+ if (!name.equalsIgnoreCase (F (" Connection" )) &&
1080+ !name.equalsIgnoreCase (F (" User-Agent" )) &&
1081+ !name.equalsIgnoreCase (F (" Host" )) &&
1082+ !(name.equalsIgnoreCase (F (" Authorization" )) && _base64Authorization.length ())) {
1083+
1084+ String headerLine;
1085+ headerLine.reserve (name.length () + value.length () + 4 );
1086+ headerLine += name;
10851087 headerLine += " : " ;
10861088
10871089 if (replace) {
@@ -1094,13 +1096,12 @@ void HTTPClient::addHeader(const String& name, const String& value, bool first,
10941096
10951097 headerLine += value;
10961098 headerLine += " \r\n " ;
1097- if (first) {
1099+ if (first) {
10981100 _headers = headerLine + _headers;
10991101 } else {
11001102 _headers += headerLine;
11011103 }
11021104 }
1103-
11041105}
11051106
11061107void HTTPClient::collectHeaders (const char * headerKeys[], const size_t headerKeysCount)
@@ -1225,41 +1226,49 @@ bool HTTPClient::sendHeader(const char * type)
12251226 return false ;
12261227 }
12271228
1228- String header = String (type) + ' ' + (_uri.length () ? _uri : F (" /" )) + F (" HTTP/1." );
1229+ String header;
1230+ // 168: Arbitrarily chosen to have enough buffer space for avoiding internal reallocations
1231+ header.reserve (_headers.length () + _base64Authorization.length () + _host.length () + 168 );
1232+ header += type;
1233+ header += ' ' ;
1234+ if (_uri.length ()) {
1235+ header += _uri;
1236+ } else {
1237+ header += ' /' ;
1238+ }
1239+ header += F (" HTTP/1." );
12291240
12301241 if (_useHTTP10) {
12311242 header += ' 0' ;
12321243 } else {
12331244 header += ' 1' ;
12341245 }
12351246
1236- header += String (F (" \r\n Host: " )) + _host;
1247+ header += F (" \r\n Host: " );
1248+ header += _host;
12371249 if (_port != 80 && _port != 443 )
12381250 {
12391251 header += ' :' ;
12401252 header += String (_port);
12411253 }
1242- header += String (F (" \r\n User-Agent: " )) + _userAgent +
1243- F (" \r\n Connection: " );
1244-
1245- if (_reuse) {
1246- header += F (" keep-alive" );
1247- } else {
1248- header += F (" close" );
1249- }
1250- header += " \r\n " ;
1254+ header += F (" \r\n User-Agent: " );
1255+ header += _userAgent;
12511256
1252- if (!_useHTTP10) {
1253- header += F (" Accept -Encoding: identity;q=1,chunked;q=0.1,*;q=0\r\n " );
1257+ if (!_useHTTP10) {
1258+ header += F (" \r\n Accept -Encoding: identity;q=1,chunked;q=0.1,*;q=0" );
12541259 }
12551260
1256- if (_base64Authorization.length ()) {
1257- header += F (" Authorization : Basic " );
1261+ if (_base64Authorization.length ()) {
1262+ header += F (" \r\n Authorization : Basic " );
12581263 header += _base64Authorization;
1259- header += " \r\n " ;
12601264 }
12611265
1262- header += _headers + " \r\n " ;
1266+ header += F (" \r\n Connection: " );
1267+ header += _reuse ? F (" keep-alive" ) : F (" close" );
1268+ header += " \r\n " ;
1269+
1270+ header += _headers;
1271+ header += " \r\n " ;
12631272
12641273 DEBUG_HTTPCLIENT (" [HTTP-Client] sending request header\n -----\n %s-----\n " , header.c_str ());
12651274
@@ -1290,20 +1299,23 @@ int HTTPClient::handleHeaderResponse()
12901299 size_t len = _client->available ();
12911300 if (len > 0 ) {
12921301 String headerLine = _client->readStringUntil (' \n ' );
1293- headerLine.trim (); // remove \r
12941302
12951303 lastDataTime = millis ();
12961304
12971305 DEBUG_HTTPCLIENT (" [HTTP-Client][handleHeaderResponse] RX: '%s'\n " , headerLine.c_str ());
12981306
1299- if (headerLine.startsWith (" HTTP/1." )) {
1300- if (_canReuse) {
1307+ if (headerLine.startsWith (F ( " HTTP/1." ) )) {
1308+ if (_canReuse) {
13011309 _canReuse = (headerLine[sizeof " HTTP/1." - 1 ] != ' 0' );
13021310 }
13031311 _returnCode = headerLine.substring (9 , headerLine.indexOf (' ' , 9 )).toInt ();
1304- } else if (headerLine.indexOf (' :' )) {
1305- String headerName = headerLine.substring (0 , headerLine.indexOf (' :' ));
1306- String headerValue = headerLine.substring (headerLine.indexOf (' :' ) + 1 );
1312+ continue ;
1313+ }
1314+
1315+ int headerSeparator = headerLine.indexOf (' :' );
1316+ if (headerSeparator > 0 ) {
1317+ String headerName = headerLine.substring (0 , headerSeparator);
1318+ String headerValue = headerLine.substring (headerSeparator + 1 );
13071319 headerValue.trim ();
13081320
13091321 if (headerName.equalsIgnoreCase (F (" Content-Length" ))) {
@@ -1324,9 +1336,9 @@ int HTTPClient::handleHeaderResponse()
13241336 _location = headerValue;
13251337 }
13261338
1327- for (size_t i = 0 ; i < _headerKeysCount; i++) {
1328- if (_currentHeaders[i].key .equalsIgnoreCase (headerName)) {
1329- if (_currentHeaders[i].value != " " ) {
1339+ for (size_t i = 0 ; i < _headerKeysCount; i++) {
1340+ if (_currentHeaders[i].key .equalsIgnoreCase (headerName)) {
1341+ if (! _currentHeaders[i].value . isEmpty () ) {
13301342 // Existing value, append this one with a comma
13311343 _currentHeaders[i].value += ' ,' ;
13321344 _currentHeaders[i].value += headerValue;
@@ -1336,9 +1348,12 @@ int HTTPClient::handleHeaderResponse()
13361348 break ; // We found a match, stop looking
13371349 }
13381350 }
1351+ continue ;
13391352 }
13401353
1341- if (headerLine == " " ) {
1354+ headerLine.trim (); // remove \r
1355+
1356+ if (headerLine.isEmpty ()) {
13421357 DEBUG_HTTPCLIENT (" [HTTP-Client][handleHeaderResponse] code: %d\n " , _returnCode);
13431358
13441359 if (_size > 0 ) {
0 commit comments