Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce temporary string creation in HTTPClient::sendHeader #6937

Merged
merged 3 commits into from
Dec 29, 2019
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 51 additions & 35 deletions libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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")) &&
!name.equalsIgnoreCase(F("User-Agent")) &&
!name.equalsIgnoreCase(F("Host")) &&
!(name.equalsIgnoreCase(F("Authorization")) && _base64Authorization.length())){

String headerLine = name;
if (!name.equalsIgnoreCase(F("Connection")) &&
!name.equalsIgnoreCase(F("User-Agent")) &&
!name.equalsIgnoreCase(F("Host")) &&
!(name.equalsIgnoreCase(F("Authorization")) && _base64Authorization.length())) {

String headerLine;
headerLine.reserve(name.length() + value.length() + 4);
headerLine += name;
headerLine += ": ";

if (replace) {
Expand All @@ -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)
Expand Down Expand Up @@ -1225,41 +1226,50 @@ 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';
} else {
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: ");

if(_reuse) {
header += F("keep-alive");
} else {
header += F("close");
}
header += "\r\n";
header += F("\r\nUser-Agent: ");
header += _userAgent;

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());

Expand Down Expand Up @@ -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"))) {
Expand All @@ -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;
Expand All @@ -1336,9 +1349,12 @@ int HTTPClient::handleHeaderResponse()
break; // We found a match, stop looking
}
}
continue;
devyte marked this conversation as resolved.
Show resolved Hide resolved
}

if(headerLine == "") {
headerLine.trim(); // remove \r
devyte marked this conversation as resolved.
Show resolved Hide resolved

if (headerLine.isEmpty()) {
DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] code: %d\n", _returnCode);

if(_size > 0) {
Expand Down