#include #include #define FLASH_TEXT(name) const char *name namespace webdav_constants { FLASH_TEXT(MULTISTATUS_START) = ""; FLASH_TEXT(MULTISTATUS_END) = ""; FLASH_TEXT(RESPONSE_START) = ""; FLASH_TEXT(RESPONSE_END) = ""; FLASH_TEXT(HREF_START) = ""; FLASH_TEXT(HREF_END) = ""; FLASH_TEXT(PROPSTAT_START) = ""; FLASH_TEXT(PROPSTAT_END) = ""; FLASH_TEXT(PROP_START) = ""; FLASH_TEXT(PROP_END) = ""; FLASH_TEXT(RESOURCETYPE_START) = ""; FLASH_TEXT(RESOURCETYPE_END) = ""; FLASH_TEXT(RESOURCE_COLLECTION) = ""; FLASH_TEXT(HTTP_204_NO_CONTENT) = "HTTP/1.1 204 No Content"; FLASH_TEXT(CONTENTLEN_START) = ""; FLASH_TEXT(CONTENTLEN_END) = ""; FLASH_TEXT(CREATEDATE_START) = ""; FLASH_TEXT(CREATEDATE_END) = ""; FLASH_TEXT(MODDATE_START) = ""; FLASH_TEXT(MODDATE_END) = ""; FLASH_TEXT(STATUS_OK) = "HTTP/1.1 200 OK"; } void listFiles(AsyncResponseStream * response, const char *folderPath, Dir * dir) { using namespace webdav_constants; response->println(MULTISTATUS_START); Serial.println("Before rewind"); dir->rewind(); Serial.println("After rewind"); while (dir->next()) { Serial.println("Inside dir loop"); Serial.println(folderPath); Serial.println(dir->fileName()); response->print(RESPONSE_START); response->print(HREF_START); response->print(folderPath); response->print(dir->fileName()); response->print(HREF_END); response->print(PROPSTAT_START); response->print(PROP_START); if (dir->isDirectory()) { response->print(RESOURCETYPE_START); response->print(RESOURCE_COLLECTION); response->print(RESOURCETYPE_END); } else { response->print(CONTENTLEN_START); response->print(dir->fileSize(), DEC); response->print(CONTENTLEN_END); } response->print(PROP_END); response->print(STATUS_OK); response->print(PROPSTAT_END); response->println(webdav_constants::RESPONSE_END); } response->println(MULTISTATUS_END); } class SpiffsWebDavHandler : public AsyncWebHandler { public: SpiffsWebDavHandler(const String & prefix, const String & folder) : prefix_(prefix), folder_(folder) {} virtual bool canHandle(AsyncWebServerRequest *request) override final { Serial.print("Can handle for url : "); Serial.println(request->url()); return request->url().startsWith(prefix_); } virtual void handleRequest(AsyncWebServerRequest *request) override final { if (request->url() == prefix_ + "/" && request->method() == HTTP_PROPFIND) { Serial.println("Propfind start"); AsyncResponseStream * response = request->beginResponseStream("application/xml"); Dir dir = SPIFFS.openDir(folder_); listFiles(response, "/", &dir); request->send(response); } else if(request->url() == prefix_ + "/" && request->method() == HTTP_GET) { AsyncResponseStream * response = request->beginResponseStream("text/plain", 1460*10); Dir dir = SPIFFS.openDir(folder_); Serial.print("Opening folder "); Serial.println(folder_); while (dir.next()) { Serial.print(" File: "); Serial.println(dir.fileName()); response->println(dir.fileName()); } request->send(response); } else if (request->method() == HTTP_GET) { auto path = folder_ + request->url().substring(prefix_.length()); if (SPIFFS.exists(path)) { request->send(SPIFFS, path, "application/x-msgpack"); } else { request->send(404, "text/plain", "Webdav: File not found"); } } else if (request->method() == HTTP_DELETE) { auto path = folder_ + request->url().substring(prefix_.length()); if (SPIFFS.exists(path)) { if(SPIFFS.remove(path)) request->send(204, "text/plain", "Success"); else request->send(404, "text/plain", "Webdav: Invalid delete request"); } else { request->send(404, "text/plain", "Webdav: File to delete not found"); } } else { request->send(404, "text/plain", "Webdav: Invalid request"); } } virtual bool isRequestHandlerTrivial() override final {return false;} private: String prefix_; String folder_; };