From e9b184cab7d701592cbc69ae470c8ec81b9fe8c3 Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Thu, 25 Jul 2024 23:32:39 +0300 Subject: [PATCH] ESP8266WebServer: pathArgs() to complement pathArg(N) similar to ::args(), returns number of parsed path arguments shortened #9100 --- libraries/ESP8266WebServer/README.rst | 34 +++++++++++++------ .../examples/PathArgServer/PathArgServer.ino | 17 ++++++++++ .../src/ESP8266WebServer-impl.h | 9 ++++- .../ESP8266WebServer/src/ESP8266WebServer.h | 4 ++- .../src/detail/RequestHandler.h | 12 ++++--- 5 files changed, 58 insertions(+), 18 deletions(-) diff --git a/libraries/ESP8266WebServer/README.rst b/libraries/ESP8266WebServer/README.rst index c37c6d5e64..5071db150b 100644 --- a/libraries/ESP8266WebServer/README.rst +++ b/libraries/ESP8266WebServer/README.rst @@ -16,10 +16,10 @@ Class Constructor Creates the ESP8266WebServer class object. -*Parameters:* +*Parameters:* host IP address: ``IPaddress addr`` (optional) - + host port number: ``int port`` (default is the standard HTTP port 80) Basic Operations @@ -61,7 +61,7 @@ Client request handlers void onNotFound(); void onFileUpload(); -*Example:* +*Example:* .. code:: cpp @@ -75,7 +75,7 @@ Client request filters ^^^^^^^^^^^^^^^^^^^^^^ .. code:: cpp - + RequestHandler& setFilter(); *Example:* @@ -110,10 +110,10 @@ Getting information about request arguments .. code:: cpp - const String & arg(); - const String & argName(); + const String & arg(int); + const String & argName(int); int args(); - bool hasArg(); + bool hasArg(const String&); ``arg`` - get request argument value, use ``arg("plain")`` to get POST body @@ -133,14 +133,14 @@ Getting information about request headers const String & hostHeader(); int headers(); bool hasHeader(); - + ``header`` - get request header value ``headerName`` - get request header name ``hostHeader`` - get request host header if available, else empty string - + ``headers`` - get header count ``hasHeader`` - check if header exist @@ -165,6 +165,18 @@ Authentication server.requestAuthentication(); } +Getting information about request path arguments +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: cpp + + const String & pathArg(int) const; + int pathArgs() const; + +``pathArg`` - get request path argument by index (starting with 0) + +``pathArgs`` - get path arguments count, make sure to check it before accessing ``pathArg`` value + Other Function Calls ~~~~~~~~~~~~~~~~~~~~ @@ -172,13 +184,13 @@ Other Function Calls .. code:: cpp const String & uri(); // get the current uri - HTTPMethod method(); // get the current method + HTTPMethod method(); // get the current method WiFiClient & client(); // get the current client HTTPUpload & upload(); // get the current upload void setContentLength(); // set content length void sendHeader(); // send HTTP header void sendContent(); // send content - void sendContent_P(); + void sendContent_P(); void collectHeaders(); // set the request headers to collect void serveStatic(); size_t streamFile(); diff --git a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino index 4e2ef12ce0..8c63b0fba1 100644 --- a/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino +++ b/libraries/ESP8266WebServer/examples/PathArgServer/PathArgServer.ino @@ -16,6 +16,15 @@ const char *password = STAPSK; ESP8266WebServer server(80); +bool checkPathArgs(int number) { + if (server.pathArgs() == number) { + return true; + } + + server.send(500, "text/plain", "request handler received unexpected number of path arguments"); + return false; +} + void setup(void) { Serial.begin(115200); WiFi.mode(WIFI_STA); @@ -40,11 +49,19 @@ void setup(void) { }); server.on(UriBraces("/users/{}"), []() { + if (!checkPathArgs(1)) { + return; + } + String user = server.pathArg(0); server.send(200, "text/plain", "User: '" + user + "'"); }); server.on(UriRegex("^\\/users\\/([0-9]+)\\/devices\\/([0-9]+)$"), []() { + if (!checkPathArgs(2)) { + return; + } + 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/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index dbcb251135..f4bb662877 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -657,8 +657,15 @@ void ESP8266WebServerTemplate::_streamFileCore(const size_t fileSize } template -const String& ESP8266WebServerTemplate::pathArg(unsigned int i) const { +int ESP8266WebServerTemplate::pathArgs() const { if (_currentHandler != nullptr) + return _currentHandler->pathArgsSize(); + return 0; +} + +template +const String& ESP8266WebServerTemplate::pathArg(int i) const { + if (i >= 0 && _currentHandler != nullptr && (size_t)i < _currentHandler->pathArgsSize()) return _currentHandler->pathArg(i); return emptyString; } diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index f9eca1c8bc..1d7dbebb48 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -141,7 +141,9 @@ class ESP8266WebServerTemplate // Allows setting server options (i.e. SSL keys) by the instantiator ServerType &getServer() { return _server; } - const String& pathArg(unsigned int i) const; // get request path argument by number + const String& pathArg(int i) const; // get request path argument by number + int pathArgs() const; // get path arguments count + 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 c373c58f1b..da28702450 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandler.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandler.h @@ -3,7 +3,6 @@ #include #include -#include namespace esp8266webserver { @@ -16,7 +15,7 @@ class RequestHandler { /* note: old handler API for backward compatibility */ - + virtual bool canHandle(HTTPMethod method, const String& uri) { (void) method; (void) uri; @@ -43,7 +42,7 @@ class RequestHandler { return false; } virtual bool handle(WebServerType& server, HTTPMethod requestMethod, const String& requestUri) { - (void) server; + (void) server; (void) requestMethod; (void) requestUri; return false; @@ -74,8 +73,11 @@ class RequestHandler { std::vector pathArgs; public: - const String& pathArg(unsigned int i) { - assert(i < pathArgs.size()); + size_t pathArgsSize() const { + return pathArgs.size(); + } + + const String& pathArg(unsigned int i) const { return pathArgs[i]; } };