Skip to content

Commit

Permalink
WebServer: Allow client to send many requests on the same connection (e…
Browse files Browse the repository at this point in the history
…sp8266#7414)

* WebServer: Allow client to send many requests on the same connection

* WebServer: Keep the connection alive with a client by default

* WebServer: Use the request's HTTP version and Connection header to set the default keep alive value

* Fix a typo in a comment
  • Loading branch information
ZakCodes authored Jul 16, 2020
1 parent 709ba79 commit 3c1bd65
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
14 changes: 13 additions & 1 deletion libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ ESP8266WebServerTemplate<ServerType>::ESP8266WebServerTemplate(IPAddress addr, i
, _currentVersion(0)
, _currentStatus(HC_NONE)
, _statusChange(0)
, _keepAlive(false)
, _currentHandler(nullptr)
, _firstHandler(nullptr)
, _lastHandler(nullptr)
Expand Down Expand Up @@ -327,6 +328,10 @@ void ESP8266WebServerTemplate<ServerType>::handleClient() {
bool callYield = false;

if (_currentClient.connected() || _currentClient.available()) {
if (_currentClient.available() && _keepAlive) {
_currentStatus = HC_WAIT_READ;
}

switch (_currentStatus) {
case HC_NONE:
// No-op to avoid C++ compiler warning
Expand Down Expand Up @@ -431,7 +436,14 @@ void ESP8266WebServerTemplate<ServerType>::_prepareHeader(String& response, int
if (_corsEnabled) {
sendHeader(String(F("Access-Control-Allow-Origin")), String("*"));
}
sendHeader(String(F("Connection")), String(F("close")));

if (_keepAlive && _server.hasClient()) { // Disable keep alive if another client is waiting.
_keepAlive = false;
}
sendHeader(String(F("Connection")), String(_keepAlive ? F("keep-alive") : F("close")));
if (_keepAlive) {
sendHeader(String(F("Keep-Alive")), String(F("timeout=")) + HTTP_MAX_CLOSE_WAIT);
}

response += _responseHeaders;
response += "\r\n";
Expand Down
9 changes: 9 additions & 0 deletions libraries/ESP8266WebServer/src/ESP8266WebServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ class ESP8266WebServerTemplate
sendContent(emptyString);
}

// Whether other requests should be accepted from the client on the
// same socket after a response is sent.
// This will automatically configure the "Connection" header of the response.
// Defaults to true when the client's HTTP version is 1.1 or above, otherwise it defaults to false.
// If the client sends the "Connection" header, the value given by the header is used.
void keepAlive(bool keepAlive) { _keepAlive = keepAlive; }
bool keepAlive() { return _keepAlive; }

static String credentialHash(const String& username, const String& realm, const String& password);

static String urlDecode(const String& text);
Expand Down Expand Up @@ -224,6 +232,7 @@ class ESP8266WebServerTemplate
uint8_t _currentVersion;
HTTPClientStatus _currentStatus;
unsigned long _statusChange;
bool _keepAlive;

RequestHandlerType* _currentHandler;
RequestHandlerType* _firstHandler;
Expand Down
9 changes: 8 additions & 1 deletion libraries/ESP8266WebServer/src/Parsing-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
}
_currentMethod = method;

_keepAlive = _currentVersion > 0; // Keep the connection alive by default
// if the protocol version is greater than HTTP 1.0

#ifdef DEBUG_ESP_HTTP_SERVER
DEBUG_OUTPUT.print("method: ");
DEBUG_OUTPUT.print(methodStr);
Expand Down Expand Up @@ -144,7 +147,7 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
while(1){
req = client.readStringUntil('\r');
client.readStringUntil('\n');
if (req.isEmpty()) break;//no moar headers
if (req.isEmpty()) break; //no more headers
int headerDiv = req.indexOf(':');
if (headerDiv == -1){
break;
Expand Down Expand Up @@ -177,6 +180,8 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
contentLength = headerValue.toInt();
} else if (headerName.equalsIgnoreCase(F("Host"))){
_hostHeader = headerValue;
} else if (headerName.equalsIgnoreCase(F("Connection"))){
_keepAlive = headerValue.equalsIgnoreCase(F("keep-alive"));
}
}

Expand Down Expand Up @@ -241,6 +246,8 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {

if (headerName.equalsIgnoreCase(F("Host"))){
_hostHeader = headerValue;
} else if (headerName.equalsIgnoreCase(F("Connection"))){
_keepAlive = headerValue.equalsIgnoreCase(F("keep-alive"));
}
}
_parseArguments(searchStr);
Expand Down

0 comments on commit 3c1bd65

Please sign in to comment.