@@ -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,50 @@ 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
+ // 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." );
1229
1241
1230
1242
if (_useHTTP10) {
1231
1243
header += ' 0' ;
1232
1244
} else {
1233
1245
header += ' 1' ;
1234
1246
}
1235
1247
1236
- header += String (F (" \r\n Host: " )) + _host;
1248
+ header += F (" \r\n Host: " );
1249
+ header += _host;
1237
1250
if (_port != 80 && _port != 443 )
1238
1251
{
1239
1252
header += ' :' ;
1240
1253
header += String (_port);
1241
1254
}
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;
1251
1257
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" );
1254
1260
}
1255
1261
1256
- if (_base64Authorization.length ()) {
1257
- header += F (" Authorization : Basic " );
1262
+ if (_base64Authorization.length ()) {
1263
+ header += F (" \r\n Authorization : Basic " );
1258
1264
header += _base64Authorization;
1259
- header += " \r\n " ;
1260
1265
}
1261
1266
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 " ;
1263
1273
1264
1274
DEBUG_HTTPCLIENT (" [HTTP-Client] sending request header\n -----\n %s-----\n " , header.c_str ());
1265
1275
@@ -1290,20 +1300,23 @@ int HTTPClient::handleHeaderResponse()
1290
1300
size_t len = _client->available ();
1291
1301
if (len > 0 ) {
1292
1302
String headerLine = _client->readStringUntil (' \n ' );
1293
- headerLine.trim (); // remove \r
1294
1303
1295
1304
lastDataTime = millis ();
1296
1305
1297
1306
DEBUG_HTTPCLIENT (" [HTTP-Client][handleHeaderResponse] RX: '%s'\n " , headerLine.c_str ());
1298
1307
1299
- if (headerLine.startsWith (" HTTP/1." )) {
1300
- if (_canReuse) {
1308
+ if (headerLine.startsWith (F ( " HTTP/1." ) )) {
1309
+ if (_canReuse) {
1301
1310
_canReuse = (headerLine[sizeof " HTTP/1." - 1 ] != ' 0' );
1302
1311
}
1303
1312
_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 );
1307
1320
headerValue.trim ();
1308
1321
1309
1322
if (headerName.equalsIgnoreCase (F (" Content-Length" ))) {
@@ -1324,9 +1337,9 @@ int HTTPClient::handleHeaderResponse()
1324
1337
_location = headerValue;
1325
1338
}
1326
1339
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 () ) {
1330
1343
// Existing value, append this one with a comma
1331
1344
_currentHeaders[i].value += ' ,' ;
1332
1345
_currentHeaders[i].value += headerValue;
@@ -1336,9 +1349,12 @@ int HTTPClient::handleHeaderResponse()
1336
1349
break ; // We found a match, stop looking
1337
1350
}
1338
1351
}
1352
+ continue ;
1339
1353
}
1340
1354
1341
- if (headerLine == " " ) {
1355
+ headerLine.trim (); // remove \r
1356
+
1357
+ if (headerLine.isEmpty ()) {
1342
1358
DEBUG_HTTPCLIENT (" [HTTP-Client][handleHeaderResponse] code: %d\n " , _returnCode);
1343
1359
1344
1360
if (_size > 0 ) {
0 commit comments