Skip to content

Commit 3c1bd65

Browse files
authored
WebServer: Allow client to send many requests on the same connection (#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
1 parent 709ba79 commit 3c1bd65

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

Diff for: libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h

+13-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ ESP8266WebServerTemplate<ServerType>::ESP8266WebServerTemplate(IPAddress addr, i
4949
, _currentVersion(0)
5050
, _currentStatus(HC_NONE)
5151
, _statusChange(0)
52+
, _keepAlive(false)
5253
, _currentHandler(nullptr)
5354
, _firstHandler(nullptr)
5455
, _lastHandler(nullptr)
@@ -327,6 +328,10 @@ void ESP8266WebServerTemplate<ServerType>::handleClient() {
327328
bool callYield = false;
328329

329330
if (_currentClient.connected() || _currentClient.available()) {
331+
if (_currentClient.available() && _keepAlive) {
332+
_currentStatus = HC_WAIT_READ;
333+
}
334+
330335
switch (_currentStatus) {
331336
case HC_NONE:
332337
// No-op to avoid C++ compiler warning
@@ -431,7 +436,14 @@ void ESP8266WebServerTemplate<ServerType>::_prepareHeader(String& response, int
431436
if (_corsEnabled) {
432437
sendHeader(String(F("Access-Control-Allow-Origin")), String("*"));
433438
}
434-
sendHeader(String(F("Connection")), String(F("close")));
439+
440+
if (_keepAlive && _server.hasClient()) { // Disable keep alive if another client is waiting.
441+
_keepAlive = false;
442+
}
443+
sendHeader(String(F("Connection")), String(_keepAlive ? F("keep-alive") : F("close")));
444+
if (_keepAlive) {
445+
sendHeader(String(F("Keep-Alive")), String(F("timeout=")) + HTTP_MAX_CLOSE_WAIT);
446+
}
435447

436448
response += _responseHeaders;
437449
response += "\r\n";

Diff for: libraries/ESP8266WebServer/src/ESP8266WebServer.h

+9
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,14 @@ class ESP8266WebServerTemplate
168168
sendContent(emptyString);
169169
}
170170

171+
// Whether other requests should be accepted from the client on the
172+
// same socket after a response is sent.
173+
// This will automatically configure the "Connection" header of the response.
174+
// Defaults to true when the client's HTTP version is 1.1 or above, otherwise it defaults to false.
175+
// If the client sends the "Connection" header, the value given by the header is used.
176+
void keepAlive(bool keepAlive) { _keepAlive = keepAlive; }
177+
bool keepAlive() { return _keepAlive; }
178+
171179
static String credentialHash(const String& username, const String& realm, const String& password);
172180

173181
static String urlDecode(const String& text);
@@ -224,6 +232,7 @@ class ESP8266WebServerTemplate
224232
uint8_t _currentVersion;
225233
HTTPClientStatus _currentStatus;
226234
unsigned long _statusChange;
235+
bool _keepAlive;
227236

228237
RequestHandlerType* _currentHandler;
229238
RequestHandlerType* _firstHandler;

Diff for: libraries/ESP8266WebServer/src/Parsing-impl.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
114114
}
115115
_currentMethod = method;
116116

117+
_keepAlive = _currentVersion > 0; // Keep the connection alive by default
118+
// if the protocol version is greater than HTTP 1.0
119+
117120
#ifdef DEBUG_ESP_HTTP_SERVER
118121
DEBUG_OUTPUT.print("method: ");
119122
DEBUG_OUTPUT.print(methodStr);
@@ -144,7 +147,7 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
144147
while(1){
145148
req = client.readStringUntil('\r');
146149
client.readStringUntil('\n');
147-
if (req.isEmpty()) break;//no moar headers
150+
if (req.isEmpty()) break; //no more headers
148151
int headerDiv = req.indexOf(':');
149152
if (headerDiv == -1){
150153
break;
@@ -177,6 +180,8 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
177180
contentLength = headerValue.toInt();
178181
} else if (headerName.equalsIgnoreCase(F("Host"))){
179182
_hostHeader = headerValue;
183+
} else if (headerName.equalsIgnoreCase(F("Connection"))){
184+
_keepAlive = headerValue.equalsIgnoreCase(F("keep-alive"));
180185
}
181186
}
182187

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

242247
if (headerName.equalsIgnoreCase(F("Host"))){
243248
_hostHeader = headerValue;
249+
} else if (headerName.equalsIgnoreCase(F("Connection"))){
250+
_keepAlive = headerValue.equalsIgnoreCase(F("keep-alive"));
244251
}
245252
}
246253
_parseArguments(searchStr);

0 commit comments

Comments
 (0)