@@ -1076,12 +1076,14 @@ String HTTPClient::errorToString(int error)
1076
1076
void HTTPClient::addHeader (const String& name, const String& value, bool first, bool replace)
1077
1077
{
1078
1078
// 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;
1085
1087
headerLine += " : " ;
1086
1088
1087
1089
if (replace) {
@@ -1094,13 +1096,12 @@ void HTTPClient::addHeader(const String& name, const String& value, bool first,
1094
1096
1095
1097
headerLine += value;
1096
1098
headerLine += " \r\n " ;
1097
- if (first) {
1099
+ if (first) {
1098
1100
_headers = headerLine + _headers;
1099
1101
} else {
1100
1102
_headers += headerLine;
1101
1103
}
1102
1104
}
1103
-
1104
1105
}
1105
1106
1106
1107
void HTTPClient::collectHeaders (const char * headerKeys[], const size_t headerKeysCount)
@@ -1225,41 +1226,49 @@ bool HTTPClient::sendHeader(const char * type)
1225
1226
return false ;
1226
1227
}
1227
1228
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." );
1229
1240
1230
1241
if (_useHTTP10) {
1231
1242
header += ' 0' ;
1232
1243
} else {
1233
1244
header += ' 1' ;
1234
1245
}
1235
1246
1236
- header += String (F (" \r\n Host: " )) + _host;
1247
+ header += F (" \r\n Host: " );
1248
+ header += _host;
1237
1249
if (_port != 80 && _port != 443 )
1238
1250
{
1239
1251
header += ' :' ;
1240
1252
header += String (_port);
1241
1253
}
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;
1251
1256
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" );
1254
1259
}
1255
1260
1256
- if (_base64Authorization.length ()) {
1257
- header += F (" Authorization : Basic " );
1261
+ if (_base64Authorization.length ()) {
1262
+ header += F (" \r\n Authorization : Basic " );
1258
1263
header += _base64Authorization;
1259
- header += " \r\n " ;
1260
1264
}
1261
1265
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 " ;
1263
1272
1264
1273
DEBUG_HTTPCLIENT (" [HTTP-Client] sending request header\n -----\n %s-----\n " , header.c_str ());
1265
1274
@@ -1290,20 +1299,23 @@ int HTTPClient::handleHeaderResponse()
1290
1299
size_t len = _client->available ();
1291
1300
if (len > 0 ) {
1292
1301
String headerLine = _client->readStringUntil (' \n ' );
1293
- headerLine.trim (); // remove \r
1294
1302
1295
1303
lastDataTime = millis ();
1296
1304
1297
1305
DEBUG_HTTPCLIENT (" [HTTP-Client][handleHeaderResponse] RX: '%s'\n " , headerLine.c_str ());
1298
1306
1299
- if (headerLine.startsWith (" HTTP/1." )) {
1300
- if (_canReuse) {
1307
+ if (headerLine.startsWith (F ( " HTTP/1." ) )) {
1308
+ if (_canReuse) {
1301
1309
_canReuse = (headerLine[sizeof " HTTP/1." - 1 ] != ' 0' );
1302
1310
}
1303
1311
_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 );
1307
1319
headerValue.trim ();
1308
1320
1309
1321
if (headerName.equalsIgnoreCase (F (" Content-Length" ))) {
@@ -1324,9 +1336,9 @@ int HTTPClient::handleHeaderResponse()
1324
1336
_location = headerValue;
1325
1337
}
1326
1338
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 () ) {
1330
1342
// Existing value, append this one with a comma
1331
1343
_currentHeaders[i].value += ' ,' ;
1332
1344
_currentHeaders[i].value += headerValue;
@@ -1336,9 +1348,12 @@ int HTTPClient::handleHeaderResponse()
1336
1348
break ; // We found a match, stop looking
1337
1349
}
1338
1350
}
1351
+ continue ;
1339
1352
}
1340
1353
1341
- if (headerLine == " " ) {
1354
+ headerLine.trim (); // remove \r
1355
+
1356
+ if (headerLine.isEmpty ()) {
1342
1357
DEBUG_HTTPCLIENT (" [HTTP-Client][handleHeaderResponse] code: %d\n " , _returnCode);
1343
1358
1344
1359
if (_size > 0 ) {
0 commit comments