@@ -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,50 @@ 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+ // 128: Arbitrarily chosen to have enough buffer space for avoiding internal reallocations
1231+ header.reserve (_headers.length () + _uri.length () +
1232+ _base64Authorization.length () + _host.length () + _userAgent.length () + 128 );
1233+ header += type;
1234+ header += ' ' ;
1235+ if (_uri.length ()) {
1236+ header += _uri;
1237+ } else {
1238+ header += ' /' ;
1239+ }
1240+ header += F (" HTTP/1." );
12291241
12301242 if (_useHTTP10) {
12311243 header += ' 0' ;
12321244 } else {
12331245 header += ' 1' ;
12341246 }
12351247
1236- header += String (F (" \r\n Host: " )) + _host;
1248+ header += F (" \r\n Host: " );
1249+ header += _host;
12371250 if (_port != 80 && _port != 443 )
12381251 {
12391252 header += ' :' ;
12401253 header += String (_port);
12411254 }
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 " ;
1255+ header += F (" \r\n User-Agent: " );
1256+ header += _userAgent;
12511257
1252- if (!_useHTTP10) {
1253- header += F (" Accept -Encoding: identity;q=1,chunked;q=0.1,*;q=0\r\n " );
1258+ if (!_useHTTP10) {
1259+ header += F (" \r\n Accept -Encoding: identity;q=1,chunked;q=0.1,*;q=0" );
12541260 }
12551261
1256- if (_base64Authorization.length ()) {
1257- header += F (" Authorization : Basic " );
1262+ if (_base64Authorization.length ()) {
1263+ header += F (" \r\n Authorization : Basic " );
12581264 header += _base64Authorization;
1259- header += " \r\n " ;
12601265 }
12611266
1262- header += _headers + " \r\n " ;
1267+ header += F (" \r\n Connection: " );
1268+ header += _reuse ? F (" keep-alive" ) : F (" close" );
1269+ header += " \r\n " ;
1270+
1271+ header += _headers;
1272+ header += " \r\n " ;
12631273
12641274 DEBUG_HTTPCLIENT (" [HTTP-Client] sending request header\n -----\n %s-----\n " , header.c_str ());
12651275
@@ -1290,20 +1300,23 @@ int HTTPClient::handleHeaderResponse()
12901300 size_t len = _client->available ();
12911301 if (len > 0 ) {
12921302 String headerLine = _client->readStringUntil (' \n ' );
1293- headerLine.trim (); // remove \r
12941303
12951304 lastDataTime = millis ();
12961305
12971306 DEBUG_HTTPCLIENT (" [HTTP-Client][handleHeaderResponse] RX: '%s'\n " , headerLine.c_str ());
12981307
1299- if (headerLine.startsWith (" HTTP/1." )) {
1300- if (_canReuse) {
1308+ if (headerLine.startsWith (F ( " HTTP/1." ) )) {
1309+ if (_canReuse) {
13011310 _canReuse = (headerLine[sizeof " HTTP/1." - 1 ] != ' 0' );
13021311 }
13031312 _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 );
1313+ continue ;
1314+ }
1315+
1316+ int headerSeparator = headerLine.indexOf (' :' );
1317+ if (headerSeparator > 0 ) {
1318+ String headerName = headerLine.substring (0 , headerSeparator);
1319+ String headerValue = headerLine.substring (headerSeparator + 1 );
13071320 headerValue.trim ();
13081321
13091322 if (headerName.equalsIgnoreCase (F (" Content-Length" ))) {
@@ -1324,9 +1337,9 @@ int HTTPClient::handleHeaderResponse()
13241337 _location = headerValue;
13251338 }
13261339
1327- for (size_t i = 0 ; i < _headerKeysCount; i++) {
1328- if (_currentHeaders[i].key .equalsIgnoreCase (headerName)) {
1329- if (_currentHeaders[i].value != " " ) {
1340+ for (size_t i = 0 ; i < _headerKeysCount; i++) {
1341+ if (_currentHeaders[i].key .equalsIgnoreCase (headerName)) {
1342+ if (! _currentHeaders[i].value . isEmpty () ) {
13301343 // Existing value, append this one with a comma
13311344 _currentHeaders[i].value += ' ,' ;
13321345 _currentHeaders[i].value += headerValue;
@@ -1336,9 +1349,12 @@ int HTTPClient::handleHeaderResponse()
13361349 break ; // We found a match, stop looking
13371350 }
13381351 }
1352+ continue ;
13391353 }
13401354
1341- if (headerLine == " " ) {
1355+ headerLine.trim (); // remove \r
1356+
1357+ if (headerLine.isEmpty ()) {
13421358 DEBUG_HTTPCLIENT (" [HTTP-Client][handleHeaderResponse] code: %d\n " , _returnCode);
13431359
13441360 if (_size > 0 ) {
0 commit comments