Skip to content

Commit 457272c

Browse files
committed
ditto
1 parent a9f3b6f commit 457272c

File tree

3 files changed

+67
-33
lines changed

3 files changed

+67
-33
lines changed

libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@
3535
#define DEBUG_OUTPUT Serial
3636
#endif
3737

38+
#ifdef DEBUG_ESP_HTTP_SERVER
39+
#define DBGWS(x...) do { DEBUG_OUTPUT.printf(x); } while (0)
40+
#else
41+
#define DBGWS(x...) do { (void)0; } while (0)
42+
#endif
43+
3844
static const char AUTHORIZATION_HEADER[] PROGMEM = "Authorization";
3945
static const char qop_auth[] PROGMEM = "qop=auth";
4046
static const char qop_auth_quoted[] PROGMEM = "qop=\"auth\"";
@@ -324,6 +330,13 @@ void ESP8266WebServerTemplate<ServerType>::handleClient() {
324330
bool keepCurrentClient = false;
325331
bool callYield = false;
326332

333+
DBGWS("http-server loop: conn=%d avail=%d status=%s\n",
334+
_currentClient.connected(), _currentClient.available(),
335+
_currentStatus==HC_NONE?"none":
336+
_currentStatus==HC_WAIT_READ?"wait-read":
337+
_currentStatus==HC_WAIT_CLOSE?"wait-close":
338+
"??");
339+
327340
if (_currentClient.connected() || _currentClient.available()) {
328341
switch (_currentStatus) {
329342
case HC_NONE:
@@ -332,36 +345,57 @@ void ESP8266WebServerTemplate<ServerType>::handleClient() {
332345
case HC_WAIT_READ:
333346
// Wait for data from client to become available
334347
if (_currentClient.available()) {
335-
if (_parseRequest(_currentClient)) {
348+
switch (_parseRequest(_currentClient))
349+
{
350+
case CLIENT_REQUEST_CAN_CONTINUE:
336351
_currentClient.setTimeout(HTTP_MAX_SEND_WAIT);
337352
_contentLength = CONTENT_LENGTH_NOT_SET;
338353
_handleRequest();
339-
} else {
340-
keepCurrentClient = false;
354+
/* fallthrough */
355+
case CLIENT_REQUEST_IS_HANDLED:
356+
if (_currentClient.connected() || _currentClient.available()) {
357+
_currentStatus = HC_WAIT_CLOSE;
358+
_statusChange = millis();
359+
keepCurrentClient = true;
360+
}
361+
else
362+
DBGWS("webserver: peer has closed after served\n");
363+
break;
364+
case CLIENT_MUST_STOP:
365+
DBGWS("Close client\n");
341366
_currentClient.stop();
342-
}
343-
if (_currentClient.connected()) {
344-
_currentStatus = HC_WAIT_CLOSE;
345-
_statusChange = millis();
346-
keepCurrentClient = true;
347-
}
348-
} else { // !_currentClient.available()
367+
break;
368+
case CLIENT_IS_GIVEN:
369+
// client must not be stopped but must not be handled here anymore
370+
// (example: tcp connection given to websocket)
371+
DBGWS("Give client\n");
372+
break;
373+
} // switch _parseRequest()
374+
} else {
375+
// !_currentClient.available(): waiting for more data
349376
if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) {
350377
keepCurrentClient = true;
351378
}
379+
else
380+
DBGWS("webserver: closing after read timeout\n");
352381
callYield = true;
353382
}
354383
break;
355384
case HC_WAIT_CLOSE:
356385
// Wait for client to close the connection
357-
if (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT) {
386+
if (!_server.available() && (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT)) {
358387
keepCurrentClient = true;
359388
callYield = true;
389+
if (_currentClient.available())
390+
// continue serving current client
391+
_currentStatus = HC_WAIT_READ;
360392
}
361-
}
393+
break;
394+
} // switch _currentStatus
362395
}
363396

364397
if (!keepCurrentClient) {
398+
DBGWS("Drop client\n");
365399
_currentClient = ClientType();
366400
_currentStatus = HC_NONE;
367401
_currentUpload.reset();

libraries/ESP8266WebServer/src/ESP8266WebServer.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ class ESP8266WebServerTemplate
8181
using ClientType = typename ServerType::ClientType;
8282
using RequestHandlerType = RequestHandler<ServerType>;
8383
using WebServerType = ESP8266WebServerTemplate<ServerType>;
84-
using hook_f = std::function<bool(const String& method, const String& url, ClientType& client)>;
84+
using ContentType_f = std::function<String(const String&)>;
85+
enum ClientFuture_e { CLIENT_REQUEST_CAN_CONTINUE, CLIENT_REQUEST_IS_HANDLED, CLIENT_MUST_STOP, CLIENT_IS_GIVEN };
86+
using Hook_f = std::function<ClientFuture_e(const String& method, const String& url, WiFiClient* client, ContentType_f contentType)>;
8587

8688
void begin();
8789
void begin(uint16_t port);
@@ -194,16 +196,17 @@ class ESP8266WebServerTemplate
194196

195197
static String responseCodeToString(const int code);
196198

197-
void addHook (hook_f hook)
199+
void addHook (Hook_f hook)
198200
{
199201
if (_hook)
200202
{
201-
auto old = _hook;
202-
_hook = [old, hook](const String& method, const String& url, ClientType& client)
203+
auto previous = _hook;
204+
_hook = [previous, hook](const String& method, const String& url, WiFiClient* client, ContentType_f contentType)
203205
{
204-
if (first(method, url, client))
205-
return true;
206-
return hook(method, url, client);
206+
auto whatNow = previous(method, url, client, contentType);
207+
if (whatNow == CLIENT_REQUEST_CAN_CONTINUE)
208+
return hook(method, url, client, contentType);
209+
return whatNow;
207210
};
208211
}
209212
else
@@ -214,7 +217,7 @@ class ESP8266WebServerTemplate
214217
void _addRequestHandler(RequestHandlerType* handler);
215218
void _handleRequest();
216219
void _finalizeResponse();
217-
bool _parseRequest(ClientType& client);
220+
ClientFuture_e _parseRequest(ClientType& client);
218221
void _parseArguments(const String& data);
219222
int _parseArgumentsPrivate(const String& data, std::function<void(String&,String&,const String&,int,int,int,int)> handler);
220223
bool _parseForm(ClientType& client, const String& boundary, uint32_t len);
@@ -269,8 +272,7 @@ class ESP8266WebServerTemplate
269272
String _sopaque;
270273
String _srealm; // Store the Auth realm between Calls
271274

272-
hook_f _hook;
273-
275+
Hook_f _hook;
274276
};
275277

276278

libraries/ESP8266WebServer/src/Parsing-impl.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static bool readBytesWithTimeout(typename ServerType::ClientType& client, size_t
6161
}
6262

6363
template <typename ServerType>
64-
bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
64+
typename ESP8266WebServerTemplate<ServerType>::ClientFuture_e ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
6565
// Read the first line of HTTP request
6666
String req = client.readStringUntil('\r');
6767
#ifdef DEBUG_ESP_HTTP_SERVER
@@ -82,7 +82,7 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
8282
#ifdef DEBUG_ESP_HTTP_SERVER
8383
DEBUG_OUTPUT.println("Invalid request");
8484
#endif
85-
return false;
85+
return CLIENT_MUST_STOP;
8686
}
8787

8888
String methodStr = req.substring(0, addr_start);
@@ -98,13 +98,11 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
9898
_currentUri = url;
9999
_chunked = false;
100100

101-
if (_hook && _hook(methodStr, url, client))
101+
if (_hook)
102102
{
103-
// _hook() must return true when method is recognized
104-
// (even when request goes wrong)
105-
// in any case, request header and content must be read
106-
// returning false because request is now already handled
107-
return false;
103+
auto whatNow = _hook(methodStr, url, &client, mime::getContentType);
104+
if (whatNow != CLIENT_REQUEST_CAN_CONTINUE)
105+
return whatNow;
108106
}
109107

110108
HTTPMethod method = HTTP_GET;
@@ -197,7 +195,7 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
197195
)
198196
)
199197
{
200-
return false;
198+
return CLIENT_MUST_STOP;
201199
}
202200

203201
if (isEncoded) {
@@ -221,7 +219,7 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
221219
} else { // isForm is true
222220
// here: content is not yet read (plainBuf is still empty)
223221
if (!_parseForm(client, boundaryStr, contentLength)) {
224-
return false;
222+
return CLIENT_MUST_STOP;
225223
}
226224
}
227225
} else {
@@ -268,7 +266,7 @@ bool ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
268266
_currentArgs[i].value.c_str());
269267
#endif
270268

271-
return true;
269+
return CLIENT_REQUEST_CAN_CONTINUE;
272270
}
273271

274272
template <typename ServerType>

0 commit comments

Comments
 (0)