mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
Reduce temporary string creation in HTTPClient::sendHeader (#6937)
* Reduce temporary string creation/reallocation in HTTPClient This improves both performance due to fewer memory allocations/copies as well as reduces code size by ~ 25% (150 bytes) * Add more correct reservation calculation Co-authored-by: Develo <deveyes@gmail.com>
This commit is contained in:
parent
3197d2ac4e
commit
5d5200af41
@ -1076,12 +1076,14 @@ String HTTPClient::errorToString(int error)
|
|||||||
void HTTPClient::addHeader(const String& name, const String& value, bool first, bool replace)
|
void HTTPClient::addHeader(const String& name, const String& value, bool first, bool replace)
|
||||||
{
|
{
|
||||||
// not allow set of Header handled by code
|
// not allow set of Header handled by code
|
||||||
if(!name.equalsIgnoreCase(F("Connection")) &&
|
if (!name.equalsIgnoreCase(F("Connection")) &&
|
||||||
!name.equalsIgnoreCase(F("User-Agent")) &&
|
!name.equalsIgnoreCase(F("User-Agent")) &&
|
||||||
!name.equalsIgnoreCase(F("Host")) &&
|
!name.equalsIgnoreCase(F("Host")) &&
|
||||||
!(name.equalsIgnoreCase(F("Authorization")) && _base64Authorization.length())){
|
!(name.equalsIgnoreCase(F("Authorization")) && _base64Authorization.length())) {
|
||||||
|
|
||||||
String headerLine = name;
|
String headerLine;
|
||||||
|
headerLine.reserve(name.length() + value.length() + 4);
|
||||||
|
headerLine += name;
|
||||||
headerLine += ": ";
|
headerLine += ": ";
|
||||||
|
|
||||||
if (replace) {
|
if (replace) {
|
||||||
@ -1094,13 +1096,12 @@ void HTTPClient::addHeader(const String& name, const String& value, bool first,
|
|||||||
|
|
||||||
headerLine += value;
|
headerLine += value;
|
||||||
headerLine += "\r\n";
|
headerLine += "\r\n";
|
||||||
if(first) {
|
if (first) {
|
||||||
_headers = headerLine + _headers;
|
_headers = headerLine + _headers;
|
||||||
} else {
|
} else {
|
||||||
_headers += headerLine;
|
_headers += headerLine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPClient::collectHeaders(const char* headerKeys[], const size_t headerKeysCount)
|
void HTTPClient::collectHeaders(const char* headerKeys[], const size_t headerKeysCount)
|
||||||
@ -1225,7 +1226,18 @@ bool HTTPClient::sendHeader(const char * type)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String header = String(type) + ' ' + (_uri.length() ? _uri : F("/")) + F(" HTTP/1.");
|
String header;
|
||||||
|
// 128: Arbitrarily chosen to have enough buffer space for avoiding internal reallocations
|
||||||
|
header.reserve(_headers.length() + _uri.length() +
|
||||||
|
_base64Authorization.length() + _host.length() + _userAgent.length() + 128);
|
||||||
|
header += type;
|
||||||
|
header += ' ';
|
||||||
|
if (_uri.length()) {
|
||||||
|
header += _uri;
|
||||||
|
} else {
|
||||||
|
header += '/';
|
||||||
|
}
|
||||||
|
header += F(" HTTP/1.");
|
||||||
|
|
||||||
if(_useHTTP10) {
|
if(_useHTTP10) {
|
||||||
header += '0';
|
header += '0';
|
||||||
@ -1233,33 +1245,31 @@ bool HTTPClient::sendHeader(const char * type)
|
|||||||
header += '1';
|
header += '1';
|
||||||
}
|
}
|
||||||
|
|
||||||
header += String(F("\r\nHost: ")) + _host;
|
header += F("\r\nHost: ");
|
||||||
|
header += _host;
|
||||||
if (_port != 80 && _port != 443)
|
if (_port != 80 && _port != 443)
|
||||||
{
|
{
|
||||||
header += ':';
|
header += ':';
|
||||||
header += String(_port);
|
header += String(_port);
|
||||||
}
|
}
|
||||||
header += String(F("\r\nUser-Agent: ")) + _userAgent +
|
header += F("\r\nUser-Agent: ");
|
||||||
F("\r\nConnection: ");
|
header += _userAgent;
|
||||||
|
|
||||||
if(_reuse) {
|
if (!_useHTTP10) {
|
||||||
header += F("keep-alive");
|
header += F("\r\nAccept-Encoding: identity;q=1,chunked;q=0.1,*;q=0");
|
||||||
} else {
|
|
||||||
header += F("close");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_base64Authorization.length()) {
|
||||||
|
header += F("\r\nAuthorization: Basic ");
|
||||||
|
header += _base64Authorization;
|
||||||
|
}
|
||||||
|
|
||||||
|
header += F("\r\nConnection: ");
|
||||||
|
header += _reuse ? F("keep-alive") : F("close");
|
||||||
header += "\r\n";
|
header += "\r\n";
|
||||||
|
|
||||||
if(!_useHTTP10) {
|
header += _headers;
|
||||||
header += F("Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0\r\n");
|
header += "\r\n";
|
||||||
}
|
|
||||||
|
|
||||||
if(_base64Authorization.length()) {
|
|
||||||
header += F("Authorization: Basic ");
|
|
||||||
header += _base64Authorization;
|
|
||||||
header += "\r\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
header += _headers + "\r\n";
|
|
||||||
|
|
||||||
DEBUG_HTTPCLIENT("[HTTP-Client] sending request header\n-----\n%s-----\n", header.c_str());
|
DEBUG_HTTPCLIENT("[HTTP-Client] sending request header\n-----\n%s-----\n", header.c_str());
|
||||||
|
|
||||||
@ -1290,20 +1300,23 @@ int HTTPClient::handleHeaderResponse()
|
|||||||
size_t len = _client->available();
|
size_t len = _client->available();
|
||||||
if(len > 0) {
|
if(len > 0) {
|
||||||
String headerLine = _client->readStringUntil('\n');
|
String headerLine = _client->readStringUntil('\n');
|
||||||
headerLine.trim(); // remove \r
|
|
||||||
|
|
||||||
lastDataTime = millis();
|
lastDataTime = millis();
|
||||||
|
|
||||||
DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] RX: '%s'\n", headerLine.c_str());
|
DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] RX: '%s'\n", headerLine.c_str());
|
||||||
|
|
||||||
if(headerLine.startsWith("HTTP/1.")) {
|
if (headerLine.startsWith(F("HTTP/1."))) {
|
||||||
if(_canReuse) {
|
if (_canReuse) {
|
||||||
_canReuse = (headerLine[sizeof "HTTP/1." - 1] != '0');
|
_canReuse = (headerLine[sizeof "HTTP/1." - 1] != '0');
|
||||||
}
|
}
|
||||||
_returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt();
|
_returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt();
|
||||||
} else if(headerLine.indexOf(':')) {
|
continue;
|
||||||
String headerName = headerLine.substring(0, headerLine.indexOf(':'));
|
}
|
||||||
String headerValue = headerLine.substring(headerLine.indexOf(':') + 1);
|
|
||||||
|
int headerSeparator = headerLine.indexOf(':');
|
||||||
|
if (headerSeparator > 0) {
|
||||||
|
String headerName = headerLine.substring(0, headerSeparator);
|
||||||
|
String headerValue = headerLine.substring(headerSeparator + 1);
|
||||||
headerValue.trim();
|
headerValue.trim();
|
||||||
|
|
||||||
if(headerName.equalsIgnoreCase(F("Content-Length"))) {
|
if(headerName.equalsIgnoreCase(F("Content-Length"))) {
|
||||||
@ -1324,9 +1337,9 @@ int HTTPClient::handleHeaderResponse()
|
|||||||
_location = headerValue;
|
_location = headerValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(size_t i = 0; i < _headerKeysCount; i++) {
|
for (size_t i = 0; i < _headerKeysCount; i++) {
|
||||||
if(_currentHeaders[i].key.equalsIgnoreCase(headerName)) {
|
if (_currentHeaders[i].key.equalsIgnoreCase(headerName)) {
|
||||||
if (_currentHeaders[i].value != "") {
|
if (!_currentHeaders[i].value.isEmpty()) {
|
||||||
// Existing value, append this one with a comma
|
// Existing value, append this one with a comma
|
||||||
_currentHeaders[i].value += ',';
|
_currentHeaders[i].value += ',';
|
||||||
_currentHeaders[i].value += headerValue;
|
_currentHeaders[i].value += headerValue;
|
||||||
@ -1336,9 +1349,12 @@ int HTTPClient::handleHeaderResponse()
|
|||||||
break; // We found a match, stop looking
|
break; // We found a match, stop looking
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(headerLine == "") {
|
headerLine.trim(); // remove \r
|
||||||
|
|
||||||
|
if (headerLine.isEmpty()) {
|
||||||
DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] code: %d\n", _returnCode);
|
DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] code: %d\n", _returnCode);
|
||||||
|
|
||||||
if(_size > 0) {
|
if(_size > 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user