From a9f3b6f30d688143f2b7bd251b14d2aabac3ad15 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 12 Jul 2020 13:19:22 +0200 Subject: [PATCH 01/11] webhook api --- .../src/ESP8266WebServer-impl.h | 14 +++++++------ .../ESP8266WebServer/src/ESP8266WebServer.h | 20 ++++++++++++++++++- libraries/ESP8266WebServer/src/Parsing-impl.h | 11 +++++++++- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index 0823a5ed47..ea8673a72b 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -336,12 +336,14 @@ void ESP8266WebServerTemplate::handleClient() { _currentClient.setTimeout(HTTP_MAX_SEND_WAIT); _contentLength = CONTENT_LENGTH_NOT_SET; _handleRequest(); - - if (_currentClient.connected()) { - _currentStatus = HC_WAIT_CLOSE; - _statusChange = millis(); - keepCurrentClient = true; - } + } else { + keepCurrentClient = false; + _currentClient.stop(); + } + if (_currentClient.connected()) { + _currentStatus = HC_WAIT_CLOSE; + _statusChange = millis(); + keepCurrentClient = true; } } else { // !_currentClient.available() if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) { diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 2ace5dc107..07347797dd 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -26,6 +26,7 @@ #include #include +#include #include #include #include "detail/mimetable.h" @@ -80,6 +81,7 @@ class ESP8266WebServerTemplate using ClientType = typename ServerType::ClientType; using RequestHandlerType = RequestHandler; using WebServerType = ESP8266WebServerTemplate; + using hook_f = std::function; void begin(); void begin(uint16_t port); @@ -192,6 +194,22 @@ class ESP8266WebServerTemplate static String responseCodeToString(const int code); + void addHook (hook_f hook) + { + if (_hook) + { + auto old = _hook; + _hook = [old, hook](const String& method, const String& url, ClientType& client) + { + if (first(method, url, client)) + return true; + return hook(method, url, client); + }; + } + else + _hook = hook; + } + protected: void _addRequestHandler(RequestHandlerType* handler); void _handleRequest(); @@ -251,7 +269,7 @@ class ESP8266WebServerTemplate String _sopaque; String _srealm; // Store the Auth realm between Calls - + hook_f _hook; }; diff --git a/libraries/ESP8266WebServer/src/Parsing-impl.h b/libraries/ESP8266WebServer/src/Parsing-impl.h index 54bcd6c28e..30e7e93ce9 100644 --- a/libraries/ESP8266WebServer/src/Parsing-impl.h +++ b/libraries/ESP8266WebServer/src/Parsing-impl.h @@ -71,7 +71,7 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { client.readStringUntil('\n'); //reset header value for (int i = 0; i < _headerKeysCount; ++i) { - _currentHeaders[i].value =String(); + _currentHeaders[i].value.clear(); } // First line of HTTP request looks like "GET /path HTTP/1.1" @@ -98,6 +98,15 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { _currentUri = url; _chunked = false; + if (_hook && _hook(methodStr, url, client)) + { + // _hook() must return true when method is recognized + // (even when request goes wrong) + // in any case, request header and content must be read + // returning false because request is now already handled + return false; + } + HTTPMethod method = HTTP_GET; if (methodStr == F("HEAD")) { method = HTTP_HEAD; From 457272ccdfff0d94f43f60cdae7e7c5241f51d2a Mon Sep 17 00:00:00 2001 From: david gauchard Date: Thu, 16 Jul 2020 01:14:14 +0200 Subject: [PATCH 02/11] ditto --- .../src/ESP8266WebServer-impl.h | 58 +++++++++++++++---- .../ESP8266WebServer/src/ESP8266WebServer.h | 22 +++---- libraries/ESP8266WebServer/src/Parsing-impl.h | 20 +++---- 3 files changed, 67 insertions(+), 33 deletions(-) diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index ea8673a72b..9a5db5eb1f 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -35,6 +35,12 @@ #define DEBUG_OUTPUT Serial #endif +#ifdef DEBUG_ESP_HTTP_SERVER +#define DBGWS(x...) do { DEBUG_OUTPUT.printf(x); } while (0) +#else +#define DBGWS(x...) do { (void)0; } while (0) +#endif + static const char AUTHORIZATION_HEADER[] PROGMEM = "Authorization"; static const char qop_auth[] PROGMEM = "qop=auth"; static const char qop_auth_quoted[] PROGMEM = "qop=\"auth\""; @@ -324,6 +330,13 @@ void ESP8266WebServerTemplate::handleClient() { bool keepCurrentClient = false; bool callYield = false; + DBGWS("http-server loop: conn=%d avail=%d status=%s\n", + _currentClient.connected(), _currentClient.available(), + _currentStatus==HC_NONE?"none": + _currentStatus==HC_WAIT_READ?"wait-read": + _currentStatus==HC_WAIT_CLOSE?"wait-close": + "??"); + if (_currentClient.connected() || _currentClient.available()) { switch (_currentStatus) { case HC_NONE: @@ -332,36 +345,57 @@ void ESP8266WebServerTemplate::handleClient() { case HC_WAIT_READ: // Wait for data from client to become available if (_currentClient.available()) { - if (_parseRequest(_currentClient)) { + switch (_parseRequest(_currentClient)) + { + case CLIENT_REQUEST_CAN_CONTINUE: _currentClient.setTimeout(HTTP_MAX_SEND_WAIT); _contentLength = CONTENT_LENGTH_NOT_SET; _handleRequest(); - } else { - keepCurrentClient = false; + /* fallthrough */ + case CLIENT_REQUEST_IS_HANDLED: + if (_currentClient.connected() || _currentClient.available()) { + _currentStatus = HC_WAIT_CLOSE; + _statusChange = millis(); + keepCurrentClient = true; + } + else + DBGWS("webserver: peer has closed after served\n"); + break; + case CLIENT_MUST_STOP: + DBGWS("Close client\n"); _currentClient.stop(); - } - if (_currentClient.connected()) { - _currentStatus = HC_WAIT_CLOSE; - _statusChange = millis(); - keepCurrentClient = true; - } - } else { // !_currentClient.available() + break; + case CLIENT_IS_GIVEN: + // client must not be stopped but must not be handled here anymore + // (example: tcp connection given to websocket) + DBGWS("Give client\n"); + break; + } // switch _parseRequest() + } else { + // !_currentClient.available(): waiting for more data if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) { keepCurrentClient = true; } + else + DBGWS("webserver: closing after read timeout\n"); callYield = true; } break; case HC_WAIT_CLOSE: // Wait for client to close the connection - if (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT) { + if (!_server.available() && (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT)) { keepCurrentClient = true; callYield = true; + if (_currentClient.available()) + // continue serving current client + _currentStatus = HC_WAIT_READ; } - } + break; + } // switch _currentStatus } if (!keepCurrentClient) { + DBGWS("Drop client\n"); _currentClient = ClientType(); _currentStatus = HC_NONE; _currentUpload.reset(); diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 07347797dd..a34be5793e 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -81,7 +81,9 @@ class ESP8266WebServerTemplate using ClientType = typename ServerType::ClientType; using RequestHandlerType = RequestHandler; using WebServerType = ESP8266WebServerTemplate; - using hook_f = std::function; + using ContentType_f = std::function; + enum ClientFuture_e { CLIENT_REQUEST_CAN_CONTINUE, CLIENT_REQUEST_IS_HANDLED, CLIENT_MUST_STOP, CLIENT_IS_GIVEN }; + using Hook_f = std::function; void begin(); void begin(uint16_t port); @@ -194,16 +196,17 @@ class ESP8266WebServerTemplate static String responseCodeToString(const int code); - void addHook (hook_f hook) + void addHook (Hook_f hook) { if (_hook) { - auto old = _hook; - _hook = [old, hook](const String& method, const String& url, ClientType& client) + auto previous = _hook; + _hook = [previous, hook](const String& method, const String& url, WiFiClient* client, ContentType_f contentType) { - if (first(method, url, client)) - return true; - return hook(method, url, client); + auto whatNow = previous(method, url, client, contentType); + if (whatNow == CLIENT_REQUEST_CAN_CONTINUE) + return hook(method, url, client, contentType); + return whatNow; }; } else @@ -214,7 +217,7 @@ class ESP8266WebServerTemplate void _addRequestHandler(RequestHandlerType* handler); void _handleRequest(); void _finalizeResponse(); - bool _parseRequest(ClientType& client); + ClientFuture_e _parseRequest(ClientType& client); void _parseArguments(const String& data); int _parseArgumentsPrivate(const String& data, std::function handler); bool _parseForm(ClientType& client, const String& boundary, uint32_t len); @@ -269,8 +272,7 @@ class ESP8266WebServerTemplate String _sopaque; String _srealm; // Store the Auth realm between Calls - hook_f _hook; - + Hook_f _hook; }; diff --git a/libraries/ESP8266WebServer/src/Parsing-impl.h b/libraries/ESP8266WebServer/src/Parsing-impl.h index 30e7e93ce9..0ca064027d 100644 --- a/libraries/ESP8266WebServer/src/Parsing-impl.h +++ b/libraries/ESP8266WebServer/src/Parsing-impl.h @@ -61,7 +61,7 @@ static bool readBytesWithTimeout(typename ServerType::ClientType& client, size_t } template -bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { +typename ESP8266WebServerTemplate::ClientFuture_e ESP8266WebServerTemplate::_parseRequest(ClientType& client) { // Read the first line of HTTP request String req = client.readStringUntil('\r'); #ifdef DEBUG_ESP_HTTP_SERVER @@ -82,7 +82,7 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { #ifdef DEBUG_ESP_HTTP_SERVER DEBUG_OUTPUT.println("Invalid request"); #endif - return false; + return CLIENT_MUST_STOP; } String methodStr = req.substring(0, addr_start); @@ -98,13 +98,11 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { _currentUri = url; _chunked = false; - if (_hook && _hook(methodStr, url, client)) + if (_hook) { - // _hook() must return true when method is recognized - // (even when request goes wrong) - // in any case, request header and content must be read - // returning false because request is now already handled - return false; + auto whatNow = _hook(methodStr, url, &client, mime::getContentType); + if (whatNow != CLIENT_REQUEST_CAN_CONTINUE) + return whatNow; } HTTPMethod method = HTTP_GET; @@ -197,7 +195,7 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { ) ) { - return false; + return CLIENT_MUST_STOP; } if (isEncoded) { @@ -221,7 +219,7 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { } else { // isForm is true // here: content is not yet read (plainBuf is still empty) if (!_parseForm(client, boundaryStr, contentLength)) { - return false; + return CLIENT_MUST_STOP; } } } else { @@ -268,7 +266,7 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { _currentArgs[i].value.c_str()); #endif - return true; + return CLIENT_REQUEST_CAN_CONTINUE; } template From e27a8f4fcaa6c9678260a80991a566460ec0b385 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 17 Jul 2020 13:19:12 +0200 Subject: [PATCH 03/11] simplify webserver debug printouts, move text to flash --- .../src/ESP8266WebServer-impl.h | 42 +----- .../ESP8266WebServer/src/ESP8266WebServer.h | 12 ++ libraries/ESP8266WebServer/src/Parsing-impl.h | 121 ++++-------------- 3 files changed, 43 insertions(+), 132 deletions(-) diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index fd234be53a..7121a9820c 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -28,26 +28,12 @@ #include "FS.h" #include "detail/RequestHandlersImpl.h" -//#define DEBUG_ESP_HTTP_SERVER -#ifdef DEBUG_ESP_PORT -#define DEBUG_OUTPUT DEBUG_ESP_PORT -#else -#define DEBUG_OUTPUT Serial -#endif - -#ifdef DEBUG_ESP_HTTP_SERVER -#define DBGWS(x...) do { DEBUG_OUTPUT.printf(x); } while (0) -#else -#define DBGWS(x...) do { (void)0; } while (0) -#endif - static const char AUTHORIZATION_HEADER[] PROGMEM = "Authorization"; static const char qop_auth[] PROGMEM = "qop=auth"; static const char qop_auth_quoted[] PROGMEM = "qop=\"auth\""; static const char WWW_Authenticate[] PROGMEM = "WWW-Authenticate"; static const char Content_Length[] PROGMEM = "Content-Length"; - template ESP8266WebServerTemplate::ESP8266WebServerTemplate(IPAddress addr, int port) : _server(addr, port) @@ -176,9 +162,7 @@ bool ESP8266WebServerTemplate::authenticateDigest(const String& user String authReq = header(FPSTR(AUTHORIZATION_HEADER)); if(authReq.startsWith(F("Digest"))) { authReq = authReq.substring(7); - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println(authReq); - #endif + DBGWS("%s\n", authReq.c_str()); String _username = _extractParam(authReq,F("username=\"")); if(!_username.length() || _username != String(username)) { authReq = ""; @@ -205,9 +189,7 @@ bool ESP8266WebServerTemplate::authenticateDigest(const String& user _nc = _extractParam(authReq, F("nc="), ','); _cnonce = _extractParam(authReq, F("cnonce=\"")); } - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Hash of user:realm:pass=" + H1); - #endif + DBGWS("Hash of user:realm:pass=%s\n", H1.c_str()); MD5Builder md5; md5.begin(); if(_currentMethod == HTTP_GET){ @@ -223,9 +205,7 @@ bool ESP8266WebServerTemplate::authenticateDigest(const String& user } md5.calculate(); String _H2 = md5.toString(); - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Hash of GET:uri=" + _H2); - #endif + DBGWS("Hash of GET:uri=%s\n", _H2.c_str()); md5.begin(); if(authReq.indexOf(FPSTR(qop_auth)) != -1 || authReq.indexOf(FPSTR(qop_auth_quoted)) != -1) { md5.add(H1 + ':' + _nonce + ':' + _nc + ':' + _cnonce + F(":auth:") + _H2); @@ -234,9 +214,7 @@ bool ESP8266WebServerTemplate::authenticateDigest(const String& user } md5.calculate(); String _responsecheck = md5.toString(); - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("The Proper response=" +_responsecheck); - #endif + DBGWS("The Proper response=%s\n", _responsecheck.c_str()); if(_response == _responsecheck){ authReq = ""; return true; @@ -320,9 +298,7 @@ void ESP8266WebServerTemplate::handleClient() { return; } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("New client"); -#endif + DBGWS("New client\n"); _currentClient = client; _currentStatus = HC_WAIT_READ; @@ -711,17 +687,13 @@ template void ESP8266WebServerTemplate::_handleRequest() { bool handled = false; if (!_currentHandler){ -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("request handler not found"); -#endif + DBGWS("request handler not found\n"); } else { handled = _currentHandler->handle(*this, _currentMethod, _currentUri); -#ifdef DEBUG_ESP_HTTP_SERVER if (!handled) { - DEBUG_OUTPUT.println("request handler failed to handle request"); + DBGWS("request handler failed to handle request\n"); } -#endif } if (!handled && _notFoundHandler) { _notFoundHandler(); diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 1a90ef1447..2a0990b096 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -32,6 +32,18 @@ #include "detail/mimetable.h" #include "Uri.h" +//#define DEBUG_ESP_HTTP_SERVER + +#ifdef DEBUG_ESP_HTTP_SERVER +#ifdef DEBUG_ESP_PORT +#define DBGWS(f,...) do { DEBUG_ESP_PORT.printf(PSTR(f), ##__VA_ARGS__); } while (0) +#else +#define DBGWS(f,...) do { Serial.printf(F(f), ##__VA_ARGS__); } while (0) +#endif +#else +#define DBGWS(x...) do { (void)0; } while (0) +#endif + enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS }; enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END, UPLOAD_FILE_ABORTED }; diff --git a/libraries/ESP8266WebServer/src/Parsing-impl.h b/libraries/ESP8266WebServer/src/Parsing-impl.h index 7bf474753e..5169be27a2 100644 --- a/libraries/ESP8266WebServer/src/Parsing-impl.h +++ b/libraries/ESP8266WebServer/src/Parsing-impl.h @@ -25,13 +25,6 @@ #include "ESP8266WebServer.h" #include "detail/mimetable.h" -//#define DEBUG_ESP_HTTP_SERVER -#ifdef DEBUG_ESP_PORT -#define DEBUG_OUTPUT DEBUG_ESP_PORT -#else -#define DEBUG_OUTPUT Serial -#endif - #ifndef WEBSERVER_MAX_POST_ARGS #define WEBSERVER_MAX_POST_ARGS 32 #endif @@ -64,10 +57,7 @@ template typename ESP8266WebServerTemplate::ClientFuture_e ESP8266WebServerTemplate::_parseRequest(ClientType& client) { // Read the first line of HTTP request String req = client.readStringUntil('\r'); -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("request: "); - DEBUG_OUTPUT.println(req); -#endif + DBGWS("request: %s\n", req.c_str()); client.readStringUntil('\n'); //reset header value for (int i = 0; i < _headerKeysCount; ++i) { @@ -79,9 +69,7 @@ typename ESP8266WebServerTemplate::ClientFuture_e ESP8266WebServerTe int addr_start = req.indexOf(' '); int addr_end = req.indexOf(' ', addr_start + 1); if (addr_start == -1 || addr_end == -1) { -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Invalid request"); -#endif + DBGWS("Invalid request\n"); return CLIENT_MUST_STOP; } @@ -121,14 +109,8 @@ typename ESP8266WebServerTemplate::ClientFuture_e ESP8266WebServerTe } _currentMethod = method; -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("method: "); - DEBUG_OUTPUT.print(methodStr); - DEBUG_OUTPUT.print(" url: "); - DEBUG_OUTPUT.print(url); - DEBUG_OUTPUT.print(" search: "); - DEBUG_OUTPUT.println(searchStr); -#endif + DBGWS("method: %s url: %s search: %s\n", + methodStr.c_str(), url.c_str(), searchStr.c_str()); //attach handler RequestHandlerType* handler; @@ -161,12 +143,7 @@ typename ESP8266WebServerTemplate::ClientFuture_e ESP8266WebServerTe headerValue.trim(); _collectHeader(headerName.c_str(),headerValue.c_str()); - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("headerName: "); - DEBUG_OUTPUT.println(headerName); - DEBUG_OUTPUT.print("headerValue: "); - DEBUG_OUTPUT.println(headerValue); - #endif + DBGWS("headerName: %s\nheaderValue: %s\n", headerName.c_str(), headerValue.c_str()); if (headerName.equalsIgnoreCase(FPSTR(Content_Type))){ using namespace mime; @@ -239,12 +216,7 @@ typename ESP8266WebServerTemplate::ClientFuture_e ESP8266WebServerTe headerValue = req.substring(headerDiv + 2); _collectHeader(headerName.c_str(),headerValue.c_str()); -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print(F("headerName: ")); - DEBUG_OUTPUT.println(headerName); - DEBUG_OUTPUT.print(F("headerValue: ")); - DEBUG_OUTPUT.println(headerValue); -#endif + DBGWS("headerName: %s\nheaderValue: %s\n", headerName.c_str(), headerValue.c_str()); if (headerName.equalsIgnoreCase(F("Host"))){ _hostHeader = headerValue; @@ -255,14 +227,10 @@ typename ESP8266WebServerTemplate::ClientFuture_e ESP8266WebServerTe client.flush(); #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print(F("Request: ")); - DEBUG_OUTPUT.println(url); - DEBUG_OUTPUT.print(F("Arguments: ")); - DEBUG_OUTPUT.println(searchStr); - - DEBUG_OUTPUT.println(F("final list of key/value pairs:")); + DBGWS("Request: %s\nArguments: %s\nfinal list of key/value pairs:\n", + url.c_str(), searchStr.c_str()); for (int i = 0; i < _currentArgCount; i++) - DEBUG_OUTPUT.printf(" key:'%s' value:'%s'\r\n", + DBGWS(" key:'%s' value:'%s'\r\n", _currentArgs[i].key.c_str(), _currentArgs[i].value.c_str()); #endif @@ -316,10 +284,7 @@ void ESP8266WebServerTemplate::_parseArguments(const String& data) { template int ESP8266WebServerTemplate::_parseArgumentsPrivate(const String& data, std::function handler) { -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("args: "); - DEBUG_OUTPUT.println(data); -#endif + DBGWS("args: %s\n", data.c_str()); size_t pos = 0; int arg_total = 0; @@ -357,11 +322,7 @@ int ESP8266WebServerTemplate::_parseArgumentsPrivate(const String& d break; } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("args count: "); - DEBUG_OUTPUT.println(arg_total); -#endif - + DBGWS("args count: %d\n", (int)arg_total); return arg_total; } @@ -390,12 +351,7 @@ uint8_t ESP8266WebServerTemplate::_uploadReadByte(ClientType& client template bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const String& boundary, uint32_t len){ (void) len; -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Parse Form: Boundary: "); - DEBUG_OUTPUT.print(boundary); - DEBUG_OUTPUT.print(" Length: "); - DEBUG_OUTPUT.println(len); -#endif + DBGWS("Parse Form: Boundary: '%s' Length: %d\n", boundary.c_str(), (int)len); String line; int retry = 0; do { @@ -429,18 +385,12 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const argFilename = argName.substring(nameStart+2, argName.length() - 1); argName = argName.substring(0, argName.indexOf('"')); argIsFile = true; -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg FileName: "); - DEBUG_OUTPUT.println(argFilename); -#endif + DBGWS("PostArg FileName: %s\n", argFilename.c_str()); //use GET to set the filename if uploading using blob if (argFilename == F("blob") && hasArg(FPSTR(filename))) argFilename = arg(FPSTR(filename)); } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg Name: "); - DEBUG_OUTPUT.println(argName); -#endif + DBGWS("PostArg Name: %s\n", argName.c_str()); using namespace mime; argType = FPSTR(mimeTable[txt].mimeType); line = client.readStringUntil('\r'); @@ -451,10 +401,7 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const client.readStringUntil('\r'); client.readStringUntil('\n'); } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg Type: "); - DEBUG_OUTPUT.println(argType); -#endif + DBGWS("PostArg Type: %s\n", argType.c_str()); if (!argIsFile){ while(1){ line = client.readStringUntil('\r'); @@ -463,20 +410,14 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const if (argValue.length() > 0) argValue += '\n'; argValue += line; } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg Value: "); - DEBUG_OUTPUT.println(argValue); - DEBUG_OUTPUT.println(); -#endif + DBGWS("PostArg Value: %s\n\n", argValue.c_str()); RequestArgument& arg = _postArgs[_postArgsLen++]; arg.key = argName; arg.value = argValue; if (line == ("--"+boundary+"--")){ -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Done Parsing POST"); -#endif + DBGWS("Done Parsing POST\n"); break; } } else { @@ -488,12 +429,7 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const _currentUpload->totalSize = 0; _currentUpload->currentSize = 0; _currentUpload->contentLength = len; -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Start File: "); - DEBUG_OUTPUT.print(_currentUpload->filename); - DEBUG_OUTPUT.print(" Type: "); - DEBUG_OUTPUT.println(_currentUpload->type); -#endif + DBGWS("Start File: %s Type: %s\n", _currentUpload->filename.c_str(), _currentUpload->type.c_str()); if(_currentHandler && _currentHandler->canUpload(_currentUri)) _currentHandler->upload(*this, _currentUri, *_currentUpload); _currentUpload->status = UPLOAD_FILE_WRITE; @@ -537,20 +473,14 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const _currentUpload->status = UPLOAD_FILE_END; if(_currentHandler && _currentHandler->canUpload(_currentUri)) _currentHandler->upload(*this, _currentUri, *_currentUpload); -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("End File: "); - DEBUG_OUTPUT.print(_currentUpload->filename); - DEBUG_OUTPUT.print(" Type: "); - DEBUG_OUTPUT.print(_currentUpload->type); - DEBUG_OUTPUT.print(" Size: "); - DEBUG_OUTPUT.println(_currentUpload->totalSize); -#endif + DBGWS("End File: %s Type: %s Size: %d\n", + _currentUpload->filename.c_str(), + _currentUpload->type.c_str(), + (int)_currentUpload->totalSize); line = client.readStringUntil(0x0D); client.readStringUntil(0x0A); if (line == "--"){ -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Done Parsing POST"); -#endif + DBGWS("Done Parsing POST\n"); break; } continue; @@ -598,10 +528,7 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const } return true; } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Error: line: "); - DEBUG_OUTPUT.println(line); -#endif + DBGWS("Error: line: %s\n", line.c_str()); return false; } From 5365d6e91d4437ac466bb7f7661bf2cbe141a514 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 17 Jul 2020 13:23:24 +0200 Subject: [PATCH 04/11] style --- .../ESP8266WebServer/src/ESP8266WebServer.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 2a0990b096..7e2d3fce45 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -208,21 +208,18 @@ class ESP8266WebServerTemplate static String responseCodeToString(const int code); - void addHook (Hook_f hook) - { - if (_hook) - { - auto previous = _hook; - _hook = [previous, hook](const String& method, const String& url, WiFiClient* client, ContentType_f contentType) - { - auto whatNow = previous(method, url, client, contentType); + void addHook (Hook_f hook) { + if (_hook) { + auto previousHook = _hook; + _hook = [previousHook, hook](const String& method, const String& url, WiFiClient* client, ContentType_f contentType) { + auto whatNow = previousHook(method, url, client, contentType); if (whatNow == CLIENT_REQUEST_CAN_CONTINUE) return hook(method, url, client, contentType); return whatNow; }; - } - else + } else { _hook = hook; + } } protected: From b55febab61b340a8a77fdd4933d4bd0fbb5fe63d Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 17 Jul 2020 15:40:44 +0200 Subject: [PATCH 05/11] nothing against Hungarians --- libraries/ESP8266WebServer/src/ESP8266WebServer.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 7e2d3fce45..bce35cc82a 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -32,13 +32,13 @@ #include "detail/mimetable.h" #include "Uri.h" -//#define DEBUG_ESP_HTTP_SERVER +#define DEBUG_ESP_HTTP_SERVER #ifdef DEBUG_ESP_HTTP_SERVER #ifdef DEBUG_ESP_PORT #define DBGWS(f,...) do { DEBUG_ESP_PORT.printf(PSTR(f), ##__VA_ARGS__); } while (0) #else -#define DBGWS(f,...) do { Serial.printf(F(f), ##__VA_ARGS__); } while (0) +#define DBGWS(f,...) do { Serial.printf(PSTR(f), ##__VA_ARGS__); } while (0) #endif #else #define DBGWS(x...) do { (void)0; } while (0) @@ -93,9 +93,9 @@ class ESP8266WebServerTemplate using ClientType = typename ServerType::ClientType; using RequestHandlerType = RequestHandler; using WebServerType = ESP8266WebServerTemplate; - using ContentType_f = std::function; enum ClientFuture_e { CLIENT_REQUEST_CAN_CONTINUE, CLIENT_REQUEST_IS_HANDLED, CLIENT_MUST_STOP, CLIENT_IS_GIVEN }; - using Hook_f = std::function; + typedef String (*ContentTypeFunction) (const String&); + using HookFunction = std::function; void begin(); void begin(uint16_t port); @@ -208,10 +208,11 @@ class ESP8266WebServerTemplate static String responseCodeToString(const int code); - void addHook (Hook_f hook) { + void addHook (HookFunction hook) { + DBGWS("addHook: @=%p\n", hook); if (_hook) { auto previousHook = _hook; - _hook = [previousHook, hook](const String& method, const String& url, WiFiClient* client, ContentType_f contentType) { + _hook = [previousHook, hook](const String& method, const String& url, WiFiClient* client, ContentTypeFunction contentType) { auto whatNow = previousHook(method, url, client, contentType); if (whatNow == CLIENT_REQUEST_CAN_CONTINUE) return hook(method, url, client, contentType); @@ -282,7 +283,7 @@ class ESP8266WebServerTemplate String _sopaque; String _srealm; // Store the Auth realm between Calls - Hook_f _hook; + HookFunction _hook; }; From bfc12fbc9d432da37e35bb2ad2bf944385cd7c68 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 17 Jul 2020 16:26:42 +0200 Subject: [PATCH 06/11] Hook examples in HelloServer example --- .../examples/HelloServer/HelloServer.ino | 69 ++++++++++++++++++- .../ESP8266WebServer/src/ESP8266WebServer.h | 2 +- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino b/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino index 1335c347af..0230e9b21a 100644 --- a/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino +++ b/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino @@ -17,7 +17,7 @@ const int led = 13; void handleRoot() { digitalWrite(led, 1); - server.send(200, "text/plain", "hello from esp8266!"); + server.send(200, "text/plain", "hello from esp8266!\r\n"); digitalWrite(led, 0); } @@ -86,11 +86,76 @@ void setup(void) { server.onNotFound(handleNotFound); + ///////////////////////////////////////////////////////// + // Hook examples + + server.addHook([](const String & method, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction contentType) { + (void)method; + (void)url; + (void)client; + (void)contentType; + Serial.printf("A useless web hook has passed\n"); + return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; + }); + + server.addHook([](const String & method, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction contentType) { + (void)method; + (void)client; + (void)contentType; + if (url.startsWith("/fail")) { + Serial.printf("An always failing web hook has been triggered\n"); + return ESP8266WebServer::CLIENT_MUST_STOP; + } + return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; + }); + + server.addHook([](const String & method, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction contentType) { + (void)method; + (void)client; + (void)contentType; + if (url.startsWith("/dump")) { + Serial.printf("The dumper web hook is on the run\n"); + + // Here the request is not interpreted, so we cannot for sure + // swallow the exact amount matching the full request+content, + // hence the tcp connection cannot be handled anymore by the + // webserver. +#ifdef STREAMTO_API + // we are lucky + client->streamToWithTimeout(Serial, 500); +#else + auto last = millis(); + while ((millis() - last) < 500) { + char buf[32]; + size_t len = client->read((uint8_t*)buf, sizeof(buf)); + if (len > 0) { + Serial.printf("(<%d> chars)", (int)len); + Serial.write(buf, len); + last = millis(); + } + } +#endif + // Two choices: return MUST STOP and webserver will close it + // (we already have the example with '/fail' hook) + // or IS GIVEN and webserver will forget it + // trying with IS GIVEN and storing it on a dumb WiFiClient. + // check the client connection: it should not immediately be closed + // (make another '/dump' one to close the first) + Serial.printf("\nTelling server to forget this connection\n"); + static WiFiClient forgetme = *client; // stop previous one if present and transfer client refcounter + return ESP8266WebServer::CLIENT_IS_GIVEN; + } + return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; + }); + + // Hook examples + ///////////////////////////////////////////////////////// + server.begin(); Serial.println("HTTP server started"); } void loop(void) { server.handleClient(); - MDNS.update(); + //MDNS.update(); } diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index bce35cc82a..43454f22a5 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -32,7 +32,7 @@ #include "detail/mimetable.h" #include "Uri.h" -#define DEBUG_ESP_HTTP_SERVER +//#define DEBUG_ESP_HTTP_SERVER #ifdef DEBUG_ESP_HTTP_SERVER #ifdef DEBUG_ESP_PORT From d24441f8b5bbd38d10e0e14d8fd9e3e6184a2013 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 17 Jul 2020 16:29:27 +0200 Subject: [PATCH 07/11] remove debug comment --- libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino b/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino index 0230e9b21a..2d343bd96f 100644 --- a/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino +++ b/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino @@ -157,5 +157,5 @@ void setup(void) { void loop(void) { server.handleClient(); - //MDNS.update(); + MDNS.update(); } From 724a74fd255d5d611cc92d5b05a70b527737e1a6 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 17 Jul 2020 16:32:34 +0200 Subject: [PATCH 08/11] sorry hungarians (again) --- libraries/ESP8266WebServer/src/ESP8266WebServer.h | 6 +++--- libraries/ESP8266WebServer/src/Parsing-impl.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 43454f22a5..831fd7cede 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -93,9 +93,9 @@ class ESP8266WebServerTemplate using ClientType = typename ServerType::ClientType; using RequestHandlerType = RequestHandler; using WebServerType = ESP8266WebServerTemplate; - enum ClientFuture_e { CLIENT_REQUEST_CAN_CONTINUE, CLIENT_REQUEST_IS_HANDLED, CLIENT_MUST_STOP, CLIENT_IS_GIVEN }; + enum ClientFuture { CLIENT_REQUEST_CAN_CONTINUE, CLIENT_REQUEST_IS_HANDLED, CLIENT_MUST_STOP, CLIENT_IS_GIVEN }; typedef String (*ContentTypeFunction) (const String&); - using HookFunction = std::function; + using HookFunction = std::function; void begin(); void begin(uint16_t port); @@ -227,7 +227,7 @@ class ESP8266WebServerTemplate void _addRequestHandler(RequestHandlerType* handler); void _handleRequest(); void _finalizeResponse(); - ClientFuture_e _parseRequest(ClientType& client); + ClientFuture _parseRequest(ClientType& client); void _parseArguments(const String& data); int _parseArgumentsPrivate(const String& data, std::function handler); bool _parseForm(ClientType& client, const String& boundary, uint32_t len); diff --git a/libraries/ESP8266WebServer/src/Parsing-impl.h b/libraries/ESP8266WebServer/src/Parsing-impl.h index 5169be27a2..3138f04c10 100644 --- a/libraries/ESP8266WebServer/src/Parsing-impl.h +++ b/libraries/ESP8266WebServer/src/Parsing-impl.h @@ -54,7 +54,7 @@ static bool readBytesWithTimeout(typename ServerType::ClientType& client, size_t } template -typename ESP8266WebServerTemplate::ClientFuture_e ESP8266WebServerTemplate::_parseRequest(ClientType& client) { +typename ESP8266WebServerTemplate::ClientFuture ESP8266WebServerTemplate::_parseRequest(ClientType& client) { // Read the first line of HTTP request String req = client.readStringUntil('\r'); DBGWS("request: %s\n", req.c_str()); From fbf4ca36a14128f23fcd8280552d9be9329ab3d7 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 17 Jul 2020 19:14:19 +0200 Subject: [PATCH 09/11] print executable code address in example --- cores/esp8266/core_esp8266_features.h | 8 ++++++++ .../ESP8266WebServer/examples/HelloServer/HelloServer.ino | 3 +++ 2 files changed, 11 insertions(+) diff --git a/cores/esp8266/core_esp8266_features.h b/cores/esp8266/core_esp8266_features.h index d3b70f3dcc..bb9d0f2d87 100644 --- a/cores/esp8266/core_esp8266_features.h +++ b/cores/esp8266/core_esp8266_features.h @@ -92,6 +92,14 @@ inline uint32_t esp_get_cycle_count() { __asm__ __volatile__("rsr %0,ccount":"=a"(ccount)); return ccount; } + +inline uint32_t esp_get_program_counter() __attribute__((always_inline)); +inline uint32_t esp_get_program_counter() { + uint32_t pc; + __asm__ __volatile__("movi %0, ." : "=r" (pc) : : ); + return pc; +} + #endif // not CORE_MOCK diff --git a/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino b/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino index 2d343bd96f..5008905394 100644 --- a/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino +++ b/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino @@ -95,6 +95,7 @@ void setup(void) { (void)client; (void)contentType; Serial.printf("A useless web hook has passed\n"); + Serial.printf("(this hook is in 0x%08x area (401x=IRAM 402x=FLASH))\n", esp_get_program_counter()); return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; }); @@ -102,6 +103,7 @@ void setup(void) { (void)method; (void)client; (void)contentType; + Serial.printf("(this hook is in 0x%08x area (401x=IRAM 402x=FLASH))\n", esp_get_program_counter()); if (url.startsWith("/fail")) { Serial.printf("An always failing web hook has been triggered\n"); return ESP8266WebServer::CLIENT_MUST_STOP; @@ -113,6 +115,7 @@ void setup(void) { (void)method; (void)client; (void)contentType; + Serial.printf("(this hook is in 0x%08x area (401x=IRAM 402x=FLASH))\n", esp_get_program_counter()); if (url.startsWith("/dump")) { Serial.printf("The dumper web hook is on the run\n"); From 93f2fbdb182eb3c179beac8f2137a7b9875b2c54 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 17 Jul 2020 19:36:04 +0200 Subject: [PATCH 10/11] fix emulation on host --- cores/esp8266/core_esp8266_features.h | 8 ++++++-- libraries/ESP8266WebServer/src/ESP8266WebServer.h | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cores/esp8266/core_esp8266_features.h b/cores/esp8266/core_esp8266_features.h index bb9d0f2d87..5a2893a6ed 100644 --- a/cores/esp8266/core_esp8266_features.h +++ b/cores/esp8266/core_esp8266_features.h @@ -96,11 +96,15 @@ inline uint32_t esp_get_cycle_count() { inline uint32_t esp_get_program_counter() __attribute__((always_inline)); inline uint32_t esp_get_program_counter() { uint32_t pc; - __asm__ __volatile__("movi %0, ." : "=r" (pc) : : ); + __asm__ __volatile__("movi %0, ." : "=r" (pc) : : ); // ©earlephilhower return pc; } -#endif // not CORE_MOCK +#else // CORE_MOCK + +inline uint32_t esp_get_program_counter() { return 0; } + +#endif // CORE_MOCK // Tools for preloading code into the flash cache diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 831fd7cede..466fe133a5 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -209,7 +209,6 @@ class ESP8266WebServerTemplate static String responseCodeToString(const int code); void addHook (HookFunction hook) { - DBGWS("addHook: @=%p\n", hook); if (_hook) { auto previousHook = _hook; _hook = [previousHook, hook](const String& method, const String& url, WiFiClient* client, ContentTypeFunction contentType) { From 0e4b110831e888419eac50e2add8601ee6656971 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 17 Jul 2020 21:27:58 +0200 Subject: [PATCH 11/11] simplify example per @mcspr suggestion --- .../examples/HelloServer/HelloServer.ino | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino b/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino index 5008905394..6715f9ee41 100644 --- a/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino +++ b/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino @@ -90,20 +90,16 @@ void setup(void) { // Hook examples server.addHook([](const String & method, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction contentType) { - (void)method; - (void)url; - (void)client; - (void)contentType; + (void)method; // GET, PUT, ... + (void)url; // example: /root/myfile.html + (void)client; // the webserver tcp client connection + (void)contentType; // contentType(".html") => "text/html" Serial.printf("A useless web hook has passed\n"); Serial.printf("(this hook is in 0x%08x area (401x=IRAM 402x=FLASH))\n", esp_get_program_counter()); return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; }); - server.addHook([](const String & method, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction contentType) { - (void)method; - (void)client; - (void)contentType; - Serial.printf("(this hook is in 0x%08x area (401x=IRAM 402x=FLASH))\n", esp_get_program_counter()); + server.addHook([](const String&, const String & url, WiFiClient*, ESP8266WebServer::ContentTypeFunction) { if (url.startsWith("/fail")) { Serial.printf("An always failing web hook has been triggered\n"); return ESP8266WebServer::CLIENT_MUST_STOP; @@ -111,11 +107,7 @@ void setup(void) { return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; }); - server.addHook([](const String & method, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction contentType) { - (void)method; - (void)client; - (void)contentType; - Serial.printf("(this hook is in 0x%08x area (401x=IRAM 402x=FLASH))\n", esp_get_program_counter()); + server.addHook([](const String&, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction) { if (url.startsWith("/dump")) { Serial.printf("The dumper web hook is on the run\n"); @@ -125,7 +117,7 @@ void setup(void) { // webserver. #ifdef STREAMTO_API // we are lucky - client->streamToWithTimeout(Serial, 500); + client->toWithTimeout(Serial, 500); #else auto last = millis(); while ((millis() - last) < 500) {