From 0eb4e3165e9506d4cccecdf635b8a663be86e755 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 10 Sep 2021 00:00:08 +0200 Subject: [PATCH] allow exceptions for regular webserver within dav space --- ESPWebDAV.h | 8 +++++++- WebDav4WebServer.cpp | 13 ++++++++---- examples/Hooked/Hooked.ino | 42 +++++++++++++++++++++++++++++--------- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/ESPWebDAV.h b/ESPWebDAV.h index 3a73544..e0923a9 100644 --- a/ESPWebDAV.h +++ b/ESPWebDAV.h @@ -130,8 +130,12 @@ class ESPWebDAVCore transferStatusFn = cb; } + bool isIgnored (const String& uri) { return _userIgnoreFunction && _userIgnoreFunction(uri); } + void setIgnored (std::function userFunction) { _userIgnoreFunction = userFunction; } + + const String& getDAVRoot () { return _davRoot; } void setDAVRoot (const String& davRoot) { _davRoot = davRoot; } - void setFsRoot (const String& fsRoot) { _fsRoot = fsRoot; } + void setFsRoot (const String& fsRoot) { _fsRoot = fsRoot; } static void stripSlashes(String& name); static String date2date(time_t date); @@ -232,6 +236,8 @@ class ESPWebDAVCore ContentTypeFunction contentTypeFn = nullptr; TransferStatusCallback transferStatusFn = nullptr; + std::function _userIgnoreFunction = nullptr; + // allowing to rewrite DAV root in FS // (dav:////path <=> FS:///path) // empty by default (dav:////path <=> FS:///path) diff --git a/WebDav4WebServer.cpp b/WebDav4WebServer.cpp index 920ebf5..0b47415 100644 --- a/WebDav4WebServer.cpp +++ b/WebDav4WebServer.cpp @@ -7,16 +7,21 @@ WebServer::HookFunction hookWebDAVForWebserver(const String& davRootDir, ESPWebD { dav.setDAVRoot(davRootDir); dav.setFsRoot(fsRootDir); - return [&dav, davRootDir, fsRootDir](const String & method, const String & url, WiFiClient * client, WebServer::ContentTypeFunction contentType) + return [&dav](const String & method, const String & url, WiFiClient * client, WebServer::ContentTypeFunction contentType) { - if (url.indexOf(davRootDir) != 0) + if (dav.isIgnored(url)) { - DBG_PRINT("CLIENT_REQUEST_CAN_CONTINUE, %s is not seen in %s", davRootDir.c_str(), url.c_str()); + DBG_PRINT("CLIENT_REQUEST_CAN_CONTINUE, '%s' is explicitally ignored", url.c_str()); + return WebServer::CLIENT_REQUEST_CAN_CONTINUE; + } + if (url.indexOf(dav.getDAVRoot()) != 0) + { + DBG_PRINT("CLIENT_REQUEST_CAN_CONTINUE, '%s' is not seen in '%s'", dav.getDAVRoot().c_str(), url.c_str()); return WebServer::CLIENT_REQUEST_CAN_CONTINUE; } if (dav.parseRequest(method, url, client, contentType)) { - DBG_PRINT("CLIENT_REQUEST_IS_HANDLED"); + DBG_PRINT("CLIENT_REQUEST_IS_HANDLED ('%s')", url.c_str()); return WebServer::CLIENT_REQUEST_IS_HANDLED; } DBG_PRINT("CLIENT_MUST_STOP"); diff --git a/examples/Hooked/Hooked.ino b/examples/Hooked/Hooked.ino index b2a8514..66d7d1a 100644 --- a/examples/Hooked/Hooked.ino +++ b/examples/Hooked/Hooked.ino @@ -66,7 +66,7 @@ #define STAPSK "psk" #endif -#define DAV "/dav" +#define DAVROOT "/" // this is the WebDAV root-URL directory, / is allowed //FS& gfs = SPIFFS; FS& gfs = LittleFS; @@ -80,18 +80,24 @@ static const char TEXT_PLAIN[] PROGMEM = "text/plain"; void notFound () { - String nf = DAV; + String nf = DAVROOT; nf += ESP8266WebServer::urlDecode(server.uri()); - Serial.printf("User request for HTTP file '%s' from '" DAV "'\n", nf.c_str() + sizeof(DAV)); - // open file 'DAV nf' (/dav/userfilename) + Serial.printf("User request for HTTP file '%s' from '" DAVROOT "'\n", nf.c_str() + sizeof(DAVROOT)); + // open file 'DAVROOT nf' (/dav/userfilename) File f = gfs.open(nf.c_str(), "r"); if (!f) { Serial.printf("not found: '%s'\n", nf.c_str()); - server.send(404, FPSTR(TEXT_PLAIN), nf); + server.send(404, FPSTR(TEXT_PLAIN), "webserver's notfound/404"); + } + else + { + // This is a reachable piece of code if the file is + // explicitally ignored in dav.setIgnored({}), + // or if DAVROOT is not '/'. + Serial.printf("found, streaming with HTTP (not webdav)\n"); + server.streamFile(f, F("application/octet-stream")); } - Serial.printf("found, streaming with HTTP (not webdav)\n"); - server.streamFile(f, F("application/octet-stream")); } // ------------------------ @@ -121,14 +127,30 @@ void setup() MDNS.begin(HOSTNAME); gfs.begin(); - gfs.mkdir(DAV); + gfs.mkdir(DAVROOT); dav.begin(&gfs); dav.setTransferStatusCallback([](const char* name, int percent, bool receive) { Serial.printf("%s: '%s': %d%%\n", receive ? "recv" : "send", name, percent); }); - server.addHook(hookWebDAVForWebserver(DAV, dav, "/")); // '/dav/' on URL is stored on '/' on FS - server.onNotFound(notFound); + + // setup webserver's Hook for WebDAV, + // optionally: DAVROOT/some/path on URL is translated to 'somewhere/else/some/path' on FS + server.addHook(hookWebDAVForWebserver(DAVROOT, dav, /*optional, replace DAVROOT by this on FS:*/ "/")); + + //// + // Allow some paths within the WebDAV namespace to be served by the regular webwerver + // + // 1. provide a callback to verify what to ignore to WebDAV (=> thus served by webserver) + dav.setIgnored([] (const String& uri) { return uri == F("/index.html") || uri == F("/another.html") || uri == F("/notfound.html"); }); + // + // 2. setup regular web pages callbacks (only meaningful when paths are ignored by WebDAV, like above) + server.on(F("/index.html"), [] () { server.send_P(200, PSTR("text/html"), PSTR("")); }); + server.on(F("/another.html"), [] () { server.send_P(200, PSTR("text/html"), PSTR("")); }); + // + //// + + server.onNotFound(notFound); // useless when DAVROOT is "/" because WebDAV handles locations first (unless ignored) server.begin(); Serial.println("HTTP server started"); Serial.println("WebDAV server started");