Skip to content

Commit

Permalink
allow exceptions for regular webserver within dav space
Browse files Browse the repository at this point in the history
  • Loading branch information
d-a-v committed Sep 9, 2021
1 parent 494e62d commit 0eb4e31
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 15 deletions.
8 changes: 7 additions & 1 deletion ESPWebDAV.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,12 @@ class ESPWebDAVCore
transferStatusFn = cb;
}

bool isIgnored (const String& uri) { return _userIgnoreFunction && _userIgnoreFunction(uri); }
void setIgnored (std::function<bool(const String& uri)> 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);
Expand Down Expand Up @@ -232,6 +236,8 @@ class ESPWebDAVCore
ContentTypeFunction contentTypeFn = nullptr;
TransferStatusCallback transferStatusFn = nullptr;

std::function<bool(const String& uri)> _userIgnoreFunction = nullptr;

// allowing to rewrite DAV root in FS
// (dav://<server>/<davroot>/path <=> FS://<fsroot>/path)
// empty by default (dav://<server>/<davroot>/path <=> FS://<davroot>/path)
Expand Down
13 changes: 9 additions & 4 deletions WebDav4WebServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
42 changes: 32 additions & 10 deletions examples/Hooked/Hooked.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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"));
}

// ------------------------
Expand Down Expand Up @@ -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("<meta http-equiv=\"Refresh\" content=\"0;url=another.html\">")); });
server.on(F("/another.html"), [] () { server.send_P(200, PSTR("text/html"), PSTR("<button style=\"background-color:red;color:orange;\" onclick=\"window.location.href='notfound.html';\">heaven</button>")); });
//
////

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");
Expand Down

0 comments on commit 0eb4e31

Please sign in to comment.