From b80ea9021b59583469499573aed564b3ce80ea1c Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Sat, 6 Oct 2018 22:17:57 +0200 Subject: [PATCH 01/17] Add path args --- .../src/ESP8266WebServer-impl.h | 5 ++ .../ESP8266WebServer/src/ESP8266WebServer.h | 1 + .../src/detail/RequestHandler.h | 10 ++++ .../src/detail/RequestHandlersImpl.h | 50 +++++++++++++++++-- 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index 1efcf92e5e..6acfff2cb3 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -542,6 +542,11 @@ void ESP8266WebServerTemplate::_streamFileCore(const size_t fileSize send(200, contentType, emptyString); } +String ESP8266WebServer::pathArg(int i) { + if (_currentHandler != nullptr) + return _currentHandler->pathArg(i); + return ""; +} template const String& ESP8266WebServerTemplate::arg(const String& name) const { diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 4281ce8636..bb550bc315 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -107,6 +107,7 @@ class ESP8266WebServerTemplate // Allows setting server options (i.e. SSL keys) by the instantiator ServerType &getServer() { return _server; } + String pathArg(int i); // get request path argument by number const String& arg(const String& name) const; // get request argument value by name const String& arg(int i) const; // get request argument value by number const String& argName(int i) const; // get request argument name by number diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandler.h b/libraries/ESP8266WebServer/src/detail/RequestHandler.h index db840af2a1..1848479040 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandler.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandler.h @@ -18,6 +18,16 @@ class RequestHandler { private: RequestHandler* _next = nullptr; + +protected: + std::vector pathArgs; + +public: + String pathArg(int i) { + if (i < pathArgs.size()) + return pathArgs[i]; + return ""; + } }; #endif //REQUESTHANDLER_H diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h index e9b8689c04..31d5cef4de 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h @@ -18,16 +18,60 @@ class FunctionRequestHandler : public RequestHandler { , _uri(uri) , _method(method) { + int numParams = 0, start = 0; + do + { + start = _uri.indexOf("{}", start); + if (start > 0) + { + numParams++; + start += 2; + } + } while (start > 0); + pathArgs = std::vector(numParams); } bool canHandle(HTTPMethod requestMethod, String requestUri) override { if (_method != HTTP_ANY && _method != requestMethod) return false; - if (requestUri != _uri) - return false; + if (_uri == requestUri) + return true; + + int listIndex = 0; + int length = _uri.length(); + int j = 0; + for (int i = 0; i < length; i++, j++) + { + char uriChar = _uri[i]; + char requestUriChar = requestUri[j]; + + if (uriChar == requestUriChar) + continue; + + if (uriChar != '{') + return false; + + i += 2; // index of char after '}' + if (i >= length) + { + // there is no char after '}' + pathArgs[listIndex] = requestUri.substring(j); + return true; + } + else + { + char charEnd = _uri[i]; + int uriIndex = requestUri.indexOf(charEnd, j); + if (uriIndex < 0) + return false; + pathArgs[listIndex] = requestUri.substring(j, uriIndex); + j = uriIndex; + } + listIndex++; + } - return true; + return j >= requestUri.length(); } bool canUpload(String requestUri) override { From 37f3d59c5e02e24f62313a0da9ce7706c4862c8c Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Sat, 6 Oct 2018 22:35:54 +0200 Subject: [PATCH 02/17] Add example --- .../examples/PathArgServer/PathArgServer.ino | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino diff --git a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino new file mode 100644 index 0000000000..1a2917dfaa --- /dev/null +++ b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino @@ -0,0 +1,70 @@ +#include +#include +#include +#include + +const char *ssid = "........"; +const char *password = "........"; + +ESP8266WebServer server(80); + +const int led = 2; + +void setup(void) +{ + pinMode(led, OUTPUT); + digitalWrite(led, 0); + Serial.begin(9600); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + Serial.println(""); + + // Wait for connection + while (WiFi.status() != WL_CONNECTED) + { + delay(500); + Serial.print("."); + } + Serial.println(""); + Serial.print("Connected to "); + Serial.println(ssid); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + + if (MDNS.begin("esp8266")) + { + Serial.println("MDNS responder started"); + } + + server.on("/", []() { + server.send(200, "text/plain", "hello from esp8266!"); + }); + + server.on("/led/2/actions/{}", []() { + String action = server.pathArg(0); + if (action == "on") + { + // /led/2/actions/on + digitalWrite(led, 1); + server.send(200, "text/plain", "Led 2 on"); + } + else if (action == "off") + { + // /led/2/actions/off + digitalWrite(led, 0); + server.send(200, "text/plain", "Led 2 off"); + } + else + { + server.send(404, "text/plain", "Action '" + action + "' was not found"); + } + }); + + server.begin(); + Serial.println("HTTP server started"); +} + +void loop(void) +{ + server.handleClient(); +} From 41695e6298618cf000450f61b018ec0f21b88ac5 Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Sat, 6 Oct 2018 23:04:22 +0200 Subject: [PATCH 03/17] Update code format --- .../examples/PathArgServer/PathArgServer.ino | 23 ++++++------------- .../src/detail/RequestHandlersImpl.h | 16 ++++--------- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino index 1a2917dfaa..c7086c0080 100644 --- a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino +++ b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino @@ -10,8 +10,7 @@ ESP8266WebServer server(80); const int led = 2; -void setup(void) -{ +void setup(void) { pinMode(led, OUTPUT); digitalWrite(led, 0); Serial.begin(9600); @@ -20,8 +19,7 @@ void setup(void) Serial.println(""); // Wait for connection - while (WiFi.status() != WL_CONNECTED) - { + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } @@ -31,8 +29,7 @@ void setup(void) Serial.print("IP address: "); Serial.println(WiFi.localIP()); - if (MDNS.begin("esp8266")) - { + if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); } @@ -42,20 +39,15 @@ void setup(void) server.on("/led/2/actions/{}", []() { String action = server.pathArg(0); - if (action == "on") - { + if (action == "on") { // /led/2/actions/on digitalWrite(led, 1); server.send(200, "text/plain", "Led 2 on"); - } - else if (action == "off") - { + } else if (action == "off") { // /led/2/actions/off digitalWrite(led, 0); server.send(200, "text/plain", "Led 2 off"); - } - else - { + } else { server.send(404, "text/plain", "Action '" + action + "' was not found"); } }); @@ -64,7 +56,6 @@ void setup(void) Serial.println("HTTP server started"); } -void loop(void) -{ +void loop(void) { server.handleClient(); } diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h index 31d5cef4de..93707f42c1 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h @@ -19,11 +19,9 @@ class FunctionRequestHandler : public RequestHandler { , _method(method) { int numParams = 0, start = 0; - do - { + do { start = _uri.indexOf("{}", start); - if (start > 0) - { + if (start > 0) { numParams++; start += 2; } @@ -41,8 +39,7 @@ class FunctionRequestHandler : public RequestHandler { int listIndex = 0; int length = _uri.length(); int j = 0; - for (int i = 0; i < length; i++, j++) - { + for (int i = 0; i < length; i++, j++) { char uriChar = _uri[i]; char requestUriChar = requestUri[j]; @@ -53,14 +50,11 @@ class FunctionRequestHandler : public RequestHandler { return false; i += 2; // index of char after '}' - if (i >= length) - { + if (i >= length) { // there is no char after '}' pathArgs[listIndex] = requestUri.substring(j); return true; - } - else - { + } else { char charEnd = _uri[i]; int uriIndex = requestUri.indexOf(charEnd, j); if (uriIndex < 0) From 5dfa3f1bc650137504e42040d93cb6856570e787 Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Sat, 6 Oct 2018 23:07:09 +0200 Subject: [PATCH 04/17] Add missing include --- libraries/ESP8266WebServer/src/detail/RequestHandler.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandler.h b/libraries/ESP8266WebServer/src/detail/RequestHandler.h index 1848479040..c60a40b10a 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandler.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandler.h @@ -2,6 +2,7 @@ #define REQUESTHANDLER_H #include +#include template class RequestHandler { From ddb0f6fa43accf484b1080958ebad0c3d640abbe Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Sat, 6 Oct 2018 23:36:04 +0200 Subject: [PATCH 05/17] Fix codestyle and unsigned int --- .../examples/PathArgServer/PathArgServer.ino | 84 +++++++++---------- .../src/ESP8266WebServer-impl.h | 2 +- .../ESP8266WebServer/src/ESP8266WebServer.h | 2 +- .../src/detail/RequestHandler.h | 2 +- 4 files changed, 45 insertions(+), 45 deletions(-) diff --git a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino index c7086c0080..13108d6a2e 100644 --- a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino +++ b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino @@ -11,51 +11,51 @@ ESP8266WebServer server(80); const int led = 2; void setup(void) { - pinMode(led, OUTPUT); - digitalWrite(led, 0); - Serial.begin(9600); - WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); - Serial.println(""); - - // Wait for connection - while (WiFi.status() != WL_CONNECTED) { - delay(500); - Serial.print("."); - } - Serial.println(""); - Serial.print("Connected to "); - Serial.println(ssid); - Serial.print("IP address: "); - Serial.println(WiFi.localIP()); - - if (MDNS.begin("esp8266")) { - Serial.println("MDNS responder started"); + pinMode(led, OUTPUT); + digitalWrite(led, 0); + Serial.begin(9600); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + Serial.println(""); + + // Wait for connection + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + Serial.print("Connected to "); + Serial.println(ssid); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + + if (MDNS.begin("esp8266")) { + Serial.println("MDNS responder started"); + } + + server.on("/", []() { + server.send(200, "text/plain", "hello from esp8266!"); + }); + + server.on("/led/2/actions/{}", []() { + String action = server.pathArg(0); + if (action == "on") { + // /led/2/actions/on + digitalWrite(led, 1); + server.send(200, "text/plain", "Led 2 on"); + } else if (action == "off") { + // /led/2/actions/off + digitalWrite(led, 0); + server.send(200, "text/plain", "Led 2 off"); + } else { + server.send(404, "text/plain", "Action '" + action + "' was not found"); } + }); - server.on("/", []() { - server.send(200, "text/plain", "hello from esp8266!"); - }); - - server.on("/led/2/actions/{}", []() { - String action = server.pathArg(0); - if (action == "on") { - // /led/2/actions/on - digitalWrite(led, 1); - server.send(200, "text/plain", "Led 2 on"); - } else if (action == "off") { - // /led/2/actions/off - digitalWrite(led, 0); - server.send(200, "text/plain", "Led 2 off"); - } else { - server.send(404, "text/plain", "Action '" + action + "' was not found"); - } - }); - - server.begin(); - Serial.println("HTTP server started"); + server.begin(); + Serial.println("HTTP server started"); } void loop(void) { - server.handleClient(); + server.handleClient(); } diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index 6acfff2cb3..4d93e18ad5 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -542,7 +542,7 @@ void ESP8266WebServerTemplate::_streamFileCore(const size_t fileSize send(200, contentType, emptyString); } -String ESP8266WebServer::pathArg(int i) { +String ESP8266WebServer::pathArg(unsigned int i) { if (_currentHandler != nullptr) return _currentHandler->pathArg(i); return ""; diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index bb550bc315..dffa470a7f 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -107,7 +107,7 @@ class ESP8266WebServerTemplate // Allows setting server options (i.e. SSL keys) by the instantiator ServerType &getServer() { return _server; } - String pathArg(int i); // get request path argument by number + String pathArg(unsigned int i); // get request path argument by number const String& arg(const String& name) const; // get request argument value by name const String& arg(int i) const; // get request argument value by number const String& argName(int i) const; // get request argument name by number diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandler.h b/libraries/ESP8266WebServer/src/detail/RequestHandler.h index c60a40b10a..d0ed402f6e 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandler.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandler.h @@ -24,7 +24,7 @@ class RequestHandler { std::vector pathArgs; public: - String pathArg(int i) { + String pathArg(unsigned int i) { if (i < pathArgs.size()) return pathArgs[i]; return ""; From 4e49e29e305e91196ae046aa2ca96c9654e1f284 Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Sun, 7 Oct 2018 00:01:11 +0200 Subject: [PATCH 06/17] fix unsigned int --- .../src/detail/RequestHandlersImpl.h | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h index 93707f42c1..f67c81cb69 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h @@ -36,33 +36,34 @@ class FunctionRequestHandler : public RequestHandler { if (_uri == requestUri) return true; - int listIndex = 0; - int length = _uri.length(); - int j = 0; - for (int i = 0; i < length; i++, j++) { + size_t uriLength = _uri.length(); + unsigned int pathArgIndex = 0; + unsigned int j = 0; + for (unsigned int i = 0; i < uriLength; i++, j++) { char uriChar = _uri[i]; char requestUriChar = requestUri[j]; if (uriChar == requestUriChar) continue; - if (uriChar != '{') return false; i += 2; // index of char after '}' - if (i >= length) { + if (i >= uriLength) { // there is no char after '}' - pathArgs[listIndex] = requestUri.substring(j); + pathArgs[pathArgIndex] = requestUri.substring(j); return true; - } else { + } + else + { char charEnd = _uri[i]; int uriIndex = requestUri.indexOf(charEnd, j); if (uriIndex < 0) return false; - pathArgs[listIndex] = requestUri.substring(j, uriIndex); - j = uriIndex; + pathArgs[pathArgIndex] = requestUri.substring(j, uriIndex); + j = (unsigned int) uriIndex; } - listIndex++; + pathArgIndex++; } return j >= requestUri.length(); From 15848597fd6866b1d7433e958df932d1e7b6c464 Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Mon, 8 Oct 2018 14:10:37 +0200 Subject: [PATCH 07/17] Remove tabs --- libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h index f67c81cb69..ac47beb198 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h @@ -18,7 +18,7 @@ class FunctionRequestHandler : public RequestHandler { , _uri(uri) , _method(method) { - int numParams = 0, start = 0; + int numParams = 0, start = 0; do { start = _uri.indexOf("{}", start); if (start > 0) { From da189bad18b1391077bc3d1b4b49c97b98184756 Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Mon, 8 Oct 2018 14:11:16 +0200 Subject: [PATCH 08/17] use vector<>.resize --- libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h index ac47beb198..61d42f3836 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h @@ -26,7 +26,7 @@ class FunctionRequestHandler : public RequestHandler { start += 2; } } while (start > 0); - pathArgs = std::vector(numParams); + pathArgs.resize(numParams); } bool canHandle(HTTPMethod requestMethod, String requestUri) override { From cabf6200e9324727429a990f9ea5096952c0c787 Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Mon, 8 Oct 2018 14:12:32 +0200 Subject: [PATCH 09/17] rename j to requestUriIndex --- .../src/detail/RequestHandlersImpl.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h index 61d42f3836..ba47a971c6 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h @@ -38,10 +38,10 @@ class FunctionRequestHandler : public RequestHandler { size_t uriLength = _uri.length(); unsigned int pathArgIndex = 0; - unsigned int j = 0; - for (unsigned int i = 0; i < uriLength; i++, j++) { + unsigned int requestUriIndex = 0; + for (unsigned int i = 0; i < uriLength; i++, requestUriIndex++) { char uriChar = _uri[i]; - char requestUriChar = requestUri[j]; + char requestUriChar = requestUri[requestUriIndex]; if (uriChar == requestUriChar) continue; @@ -51,22 +51,22 @@ class FunctionRequestHandler : public RequestHandler { i += 2; // index of char after '}' if (i >= uriLength) { // there is no char after '}' - pathArgs[pathArgIndex] = requestUri.substring(j); + pathArgs[pathArgIndex] = requestUri.substring(requestUriIndex); return true; } else { char charEnd = _uri[i]; - int uriIndex = requestUri.indexOf(charEnd, j); + int uriIndex = requestUri.indexOf(charEnd, requestUriIndex); if (uriIndex < 0) return false; - pathArgs[pathArgIndex] = requestUri.substring(j, uriIndex); - j = (unsigned int) uriIndex; + pathArgs[pathArgIndex] = requestUri.substring(requestUriIndex, uriIndex); + requestUriIndex = (unsigned int) uriIndex; } pathArgIndex++; } - return j >= requestUri.length(); + return requestUriIndex >= requestUri.length(); } bool canUpload(String requestUri) override { From 7cd3468b80aa0903885eab06baaed44b4390f90e Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Tue, 9 Oct 2018 13:23:14 +0200 Subject: [PATCH 10/17] using assert checking the path argument index --- libraries/ESP8266WebServer/src/detail/RequestHandler.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandler.h b/libraries/ESP8266WebServer/src/detail/RequestHandler.h index d0ed402f6e..e37c5a5cf9 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandler.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandler.h @@ -25,9 +25,8 @@ class RequestHandler { public: String pathArg(unsigned int i) { - if (i < pathArgs.size()) - return pathArgs[i]; - return ""; + assert(i < pathArgs.size()); + return pathArgs[i]; } }; From 637b9cb6fc1dbf68be48c5696612b933b828a66a Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Tue, 9 Oct 2018 15:05:17 +0200 Subject: [PATCH 11/17] Add missing include "assert.h" --- libraries/ESP8266WebServer/src/detail/RequestHandler.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandler.h b/libraries/ESP8266WebServer/src/detail/RequestHandler.h index e37c5a5cf9..5384a5f305 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandler.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandler.h @@ -3,6 +3,7 @@ #include #include +#include template class RequestHandler { From 63163d7af6a9601e7fca6a56f71837e6ef2871ca Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Tue, 9 Oct 2018 15:38:14 +0200 Subject: [PATCH 12/17] The order no longer matters. Path arguments may not contain the value '/' Updated the example --- .../examples/PathArgServer/PathArgServer.ino | 26 +++++++------------ .../src/detail/RequestHandlersImpl.h | 2 +- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino index 13108d6a2e..5f8ae8ea9c 100644 --- a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino +++ b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino @@ -8,11 +8,7 @@ const char *password = "........"; ESP8266WebServer server(80); -const int led = 2; - void setup(void) { - pinMode(led, OUTPUT); - digitalWrite(led, 0); Serial.begin(9600); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); @@ -37,19 +33,15 @@ void setup(void) { server.send(200, "text/plain", "hello from esp8266!"); }); - server.on("/led/2/actions/{}", []() { - String action = server.pathArg(0); - if (action == "on") { - // /led/2/actions/on - digitalWrite(led, 1); - server.send(200, "text/plain", "Led 2 on"); - } else if (action == "off") { - // /led/2/actions/off - digitalWrite(led, 0); - server.send(200, "text/plain", "Led 2 off"); - } else { - server.send(404, "text/plain", "Action '" + action + "' was not found"); - } + server.on("/users/{}", []() { + String user = server.pathArg(0); + server.send(200, "text/plain", "User: '" + user + "'"); + }); + + server.on("/users/{}/devices/{}", []() { + String user = server.pathArg(0); + String device = server.pathArg(1); + server.send(200, "text/plain", "User: '" + user + "' and Device: '" + device + "'"); }); server.begin(); diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h index ba47a971c6..1fcf9a970f 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h @@ -52,7 +52,7 @@ class FunctionRequestHandler : public RequestHandler { if (i >= uriLength) { // there is no char after '}' pathArgs[pathArgIndex] = requestUri.substring(requestUriIndex); - return true; + return pathArgs[pathArgIndex].indexOf("/") == -1; // path argument may not contain a '/' } else { From a626c5fd9b21bd44bd76e703c77d44ccfce88d62 Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Tue, 9 Oct 2018 15:39:31 +0200 Subject: [PATCH 13/17] make pathArg return a const --- libraries/ESP8266WebServer/src/detail/RequestHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandler.h b/libraries/ESP8266WebServer/src/detail/RequestHandler.h index 5384a5f305..9202f623b3 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandler.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandler.h @@ -25,7 +25,7 @@ class RequestHandler { std::vector pathArgs; public: - String pathArg(unsigned int i) { + const String& pathArg(unsigned int i) { assert(i < pathArgs.size()); return pathArgs[i]; } From 977120c4c614c0913264e28448360b5c0aad6809 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Thu, 11 Oct 2018 00:39:41 +0200 Subject: [PATCH 14/17] Update PathArgServer.ino fix trailing space --- .../ESP8266WebServer/examples/PathArgServer/PathArgServer.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino index 5f8ae8ea9c..e100290f61 100644 --- a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino +++ b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino @@ -37,7 +37,7 @@ void setup(void) { String user = server.pathArg(0); server.send(200, "text/plain", "User: '" + user + "'"); }); - + server.on("/users/{}/devices/{}", []() { String user = server.pathArg(0); String device = server.pathArg(1); From de7b504564c5fa61281396cf2da4cef549c26fb4 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 30 Nov 2018 01:03:24 +0100 Subject: [PATCH 15/17] const String& --- libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index 4d93e18ad5..0532455e4d 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -542,10 +542,10 @@ void ESP8266WebServerTemplate::_streamFileCore(const size_t fileSize send(200, contentType, emptyString); } -String ESP8266WebServer::pathArg(unsigned int i) { +const String& ESP8266WebServer::pathArg(unsigned int i) { if (_currentHandler != nullptr) return _currentHandler->pathArg(i); - return ""; + return emptyString; } template From 879e076dd774f9afb791c350a50f284ebef83bfa Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Mon, 24 Dec 2018 11:29:17 +0100 Subject: [PATCH 16/17] Add regex support --- .../examples/PathArgServer/PathArgServer.ino | 2 +- .../src/detail/RequestHandler.h | 1 + .../src/detail/RequestHandlersImpl.h | 61 ++++++++----------- 3 files changed, 26 insertions(+), 38 deletions(-) diff --git a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino index e100290f61..db8bcfe039 100644 --- a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino +++ b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino @@ -38,7 +38,7 @@ void setup(void) { server.send(200, "text/plain", "User: '" + user + "'"); }); - server.on("/users/{}/devices/{}", []() { + server.on("^\\/users\\/([0-9]+)\\/devices\\/([0-9]+)$", []() { String user = server.pathArg(0); String device = server.pathArg(1); server.send(200, "text/plain", "User: '" + user + "' and Device: '" + device + "'"); diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandler.h b/libraries/ESP8266WebServer/src/detail/RequestHandler.h index 9202f623b3..488849ccf3 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandler.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandler.h @@ -23,6 +23,7 @@ class RequestHandler { protected: std::vector pathArgs; + bool _isRegex = false; public: const String& pathArg(unsigned int i) { diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h index 1fcf9a970f..7a8cd8479f 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h @@ -2,6 +2,8 @@ #define REQUESTHANDLERSIMPL_H #include +#include +#include #include "RequestHandler.h" #include "mimetable.h" #include "WString.h" @@ -18,15 +20,16 @@ class FunctionRequestHandler : public RequestHandler { , _uri(uri) , _method(method) { - int numParams = 0, start = 0; - do { - start = _uri.indexOf("{}", start); - if (start > 0) { - numParams++; - start += 2; - } - } while (start > 0); - pathArgs.resize(numParams); + _isRegex = uri.startsWith("^") && uri.endsWith("$"); + if (_isRegex) { + std::regex rgx((_uri + "|").c_str()); + std::smatch matches; + std::string s{""}; + std::regex_search(s, matches, rgx); + pathArgs.resize(matches.size() - 1); + } else { + pathArgs.resize(0); + } } bool canHandle(HTTPMethod requestMethod, String requestUri) override { @@ -36,37 +39,21 @@ class FunctionRequestHandler : public RequestHandler { if (_uri == requestUri) return true; - size_t uriLength = _uri.length(); - unsigned int pathArgIndex = 0; - unsigned int requestUriIndex = 0; - for (unsigned int i = 0; i < uriLength; i++, requestUriIndex++) { - char uriChar = _uri[i]; - char requestUriChar = requestUri[requestUriIndex]; - - if (uriChar == requestUriChar) - continue; - if (uriChar != '{') - return false; - - i += 2; // index of char after '}' - if (i >= uriLength) { - // there is no char after '}' - pathArgs[pathArgIndex] = requestUri.substring(requestUriIndex); - return pathArgs[pathArgIndex].indexOf("/") == -1; // path argument may not contain a '/' - } - else - { - char charEnd = _uri[i]; - int uriIndex = requestUri.indexOf(charEnd, requestUriIndex); - if (uriIndex < 0) - return false; - pathArgs[pathArgIndex] = requestUri.substring(requestUriIndex, uriIndex); - requestUriIndex = (unsigned int) uriIndex; + if (_isRegex) { + unsigned int pathArgIndex = 0; + std::regex rgx(_uri.c_str()); + std::smatch matches; + std::string s(requestUri.c_str()); + if (std::regex_search(s, matches, rgx)) { + for (size_t i = 1; i < matches.size(); ++i) { // skip first + pathArgs[pathArgIndex] = String(matches[i].str().c_str()); + pathArgIndex++; + } + return true; } - pathArgIndex++; } - return requestUriIndex >= requestUri.length(); + return false; } bool canUpload(String requestUri) override { From afe785463fc2f6d5dea07a88c4a8d68643425e33 Mon Sep 17 00:00:00 2001 From: Bob Mooij Date: Fri, 1 Nov 2019 17:20:05 +0100 Subject: [PATCH 17/17] Fix to match templating --- libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h | 3 ++- libraries/ESP8266WebServer/src/ESP8266WebServer.h | 2 +- libraries/ESP8266WebServer/src/detail/RequestHandler.h | 1 - .../ESP8266WebServer/src/detail/RequestHandlersImpl.h | 8 +++++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index 0532455e4d..9de4f393dd 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -542,7 +542,8 @@ void ESP8266WebServerTemplate::_streamFileCore(const size_t fileSize send(200, contentType, emptyString); } -const String& ESP8266WebServer::pathArg(unsigned int i) { +template +const String& ESP8266WebServerTemplate::pathArg(unsigned int i) const { if (_currentHandler != nullptr) return _currentHandler->pathArg(i); return emptyString; diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index dffa470a7f..5797548eae 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -107,7 +107,7 @@ class ESP8266WebServerTemplate // Allows setting server options (i.e. SSL keys) by the instantiator ServerType &getServer() { return _server; } - String pathArg(unsigned int i); // get request path argument by number + const String& pathArg(unsigned int i) const; // get request path argument by number const String& arg(const String& name) const; // get request argument value by name const String& arg(int i) const; // get request argument value by number const String& argName(int i) const; // get request argument name by number diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandler.h b/libraries/ESP8266WebServer/src/detail/RequestHandler.h index 488849ccf3..9202f623b3 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandler.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandler.h @@ -23,7 +23,6 @@ class RequestHandler { protected: std::vector pathArgs; - bool _isRegex = false; public: const String& pathArg(unsigned int i) { diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h index 7a8cd8479f..bc81dcc0c7 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h @@ -19,6 +19,7 @@ class FunctionRequestHandler : public RequestHandler { , _ufn(ufn) , _uri(uri) , _method(method) + , _isRegex(false) { _isRegex = uri.startsWith("^") && uri.endsWith("$"); if (_isRegex) { @@ -26,9 +27,9 @@ class FunctionRequestHandler : public RequestHandler { std::smatch matches; std::string s{""}; std::regex_search(s, matches, rgx); - pathArgs.resize(matches.size() - 1); + RequestHandler::pathArgs.resize(matches.size() - 1); } else { - pathArgs.resize(0); + RequestHandler::pathArgs.resize(0); } } @@ -46,7 +47,7 @@ class FunctionRequestHandler : public RequestHandler { std::string s(requestUri.c_str()); if (std::regex_search(s, matches, rgx)) { for (size_t i = 1; i < matches.size(); ++i) { // skip first - pathArgs[pathArgIndex] = String(matches[i].str().c_str()); + RequestHandler::pathArgs[pathArgIndex] = String(matches[i].str().c_str()); pathArgIndex++; } return true; @@ -84,6 +85,7 @@ class FunctionRequestHandler : public RequestHandler { typename WebServerType::THandlerFunction _ufn; String _uri; HTTPMethod _method; + bool _isRegex; }; template