mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +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)
|
||||
{
|
||||
// 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("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 += ": ";
|
||||
|
||||
if (replace) {
|
||||
@ -1094,13 +1096,12 @@ void HTTPClient::addHeader(const String& name, const String& value, bool first,
|
||||
|
||||
headerLine += value;
|
||||
headerLine += "\r\n";
|
||||
if(first) {
|
||||
if (first) {
|
||||
_headers = headerLine + _headers;
|
||||
} else {
|
||||
_headers += headerLine;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void HTTPClient::collectHeaders(const char* headerKeys[], const size_t headerKeysCount)
|
||||
@ -1225,7 +1226,18 @@ bool HTTPClient::sendHeader(const char * type)
|
||||
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) {
|
||||
header += '0';
|
||||
@ -1233,33 +1245,31 @@ bool HTTPClient::sendHeader(const char * type)
|
||||
header += '1';
|
||||
}
|
||||
|
||||
header += String(F("\r\nHost: ")) + _host;
|
||||
header += F("\r\nHost: ");
|
||||
header += _host;
|
||||
if (_port != 80 && _port != 443)
|
||||
{
|
||||
header += ':';
|
||||
header += String(_port);
|
||||
}
|
||||
header += String(F("\r\nUser-Agent: ")) + _userAgent +
|
||||
F("\r\nConnection: ");
|
||||
header += F("\r\nUser-Agent: ");
|
||||
header += _userAgent;
|
||||
|
||||
if(_reuse) {
|
||||
header += F("keep-alive");
|
||||
} else {
|
||||
header += F("close");
|
||||
}
|
||||
header += "\r\n";
|
||||
|
||||
if(!_useHTTP10) {
|
||||
header += F("Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0\r\n");
|
||||
if (!_useHTTP10) {
|
||||
header += F("\r\nAccept-Encoding: identity;q=1,chunked;q=0.1,*;q=0");
|
||||
}
|
||||
|
||||
if(_base64Authorization.length()) {
|
||||
header += F("Authorization: Basic ");
|
||||
if (_base64Authorization.length()) {
|
||||
header += F("\r\nAuthorization: Basic ");
|
||||
header += _base64Authorization;
|
||||
header += "\r\n";
|
||||
}
|
||||
|
||||
header += _headers + "\r\n";
|
||||
header += F("\r\nConnection: ");
|
||||
header += _reuse ? F("keep-alive") : F("close");
|
||||
header += "\r\n";
|
||||
|
||||
header += _headers;
|
||||
header += "\r\n";
|
||||
|
||||
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();
|
||||
if(len > 0) {
|
||||
String headerLine = _client->readStringUntil('\n');
|
||||
headerLine.trim(); // remove \r
|
||||
|
||||
lastDataTime = millis();
|
||||
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] RX: '%s'\n", headerLine.c_str());
|
||||
|
||||
if(headerLine.startsWith("HTTP/1.")) {
|
||||
if(_canReuse) {
|
||||
if (headerLine.startsWith(F("HTTP/1."))) {
|
||||
if (_canReuse) {
|
||||
_canReuse = (headerLine[sizeof "HTTP/1." - 1] != '0');
|
||||
}
|
||||
_returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt();
|
||||
} else if(headerLine.indexOf(':')) {
|
||||
String headerName = headerLine.substring(0, headerLine.indexOf(':'));
|
||||
String headerValue = headerLine.substring(headerLine.indexOf(':') + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
int headerSeparator = headerLine.indexOf(':');
|
||||
if (headerSeparator > 0) {
|
||||
String headerName = headerLine.substring(0, headerSeparator);
|
||||
String headerValue = headerLine.substring(headerSeparator + 1);
|
||||
headerValue.trim();
|
||||
|
||||
if(headerName.equalsIgnoreCase(F("Content-Length"))) {
|
||||
@ -1324,9 +1337,9 @@ int HTTPClient::handleHeaderResponse()
|
||||
_location = headerValue;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < _headerKeysCount; i++) {
|
||||
if(_currentHeaders[i].key.equalsIgnoreCase(headerName)) {
|
||||
if (_currentHeaders[i].value != "") {
|
||||
for (size_t i = 0; i < _headerKeysCount; i++) {
|
||||
if (_currentHeaders[i].key.equalsIgnoreCase(headerName)) {
|
||||
if (!_currentHeaders[i].value.isEmpty()) {
|
||||
// Existing value, append this one with a comma
|
||||
_currentHeaders[i].value += ',';
|
||||
_currentHeaders[i].value += headerValue;
|
||||
@ -1336,9 +1349,12 @@ int HTTPClient::handleHeaderResponse()
|
||||
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);
|
||||
|
||||
if(_size > 0) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user