123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- /*
- Share.ino
- This module handle file sharing on the WebSticks
- Recommended file size <= 5MB
- */
- //Create a file share, must be logged in
- void HandleCreateShare(AsyncWebServerRequest *r) {
- if (!HandleAuth(r)) {
- return;
- }
- //Get filename from parameters
- String filepath = GetPara(r, "filename");
- filepath.trim();
- //filepath is the subpath under the www folder
- // e.g. "/www/myfile.txt" filepath will be "/myfile.txt"
- if (filepath == "") {
- SendErrorResp(r, "invalid filename given");
- return;
- }
- if (IsFileShared(filepath)) {
- SendErrorResp(r, "target file already shared");
- return;
- }
- //Add a share entry for this file
- String shareID = GeneratedRandomHex();
- bool succ = DBWrite("shln", shareID, filepath);
- if (!succ) {
- SendErrorResp(r, "unable to save share entry");
- return;
- }
- succ = DBWrite("shfn", filepath, shareID);
- if (!succ) {
- SendErrorResp(r, "unable to save share entry");
- return;
- }
- Serial.println("Shared: " + filepath + " with ID: " + shareID);
- SendOK(r);
- }
- //Remove a file share
- void HandleRemoveShare(AsyncWebServerRequest *r) {
- if (!HandleAuth(r)) {
- return;
- }
- //Get filename from parameters
- String filepath = GetPara(r, "filename");
- filepath.trim();
- if (filepath == "") {
- SendErrorResp(r, "invalid filename given");
- return;
- }
- if (!IsFileShared(filepath)) {
- SendErrorResp(r, "target file is not shared");
- return;
- }
- //Get the share ID of this entry
- String shareId = DBRead("shfn", filepath);
- if (shareId == "") {
- SendErrorResp(r, "unable to load share entry");
- return;
- }
- //Remove share entry in both tables
- bool succ = DBRemove("shln", shareId);
- if (!succ) {
- SendErrorResp(r, "unable to remove share entry");
- return;
- }
- succ = DBRemove("shfn", filepath);
- if (!succ) {
- SendErrorResp(r, "unable to remove share entry");
- return;
- }
- Serial.println("Removed shared file " + filepath + " (share ID: " + shareId + ")");
- SendOK(r);
- }
- //List all shared files
- void HandleShareList(AsyncWebServerRequest *r) {
- if (!HandleAuth(r)) {
- return;
- }
- //Build the json with brute force
- String jsonString = "[";
- //As the DB do not support list, it directly access the root of the folder where the kvdb stores the entries
- File root = SD.open(DB_root + "shln/");
- bool firstObject = true;
- if (root) {
- while (true) {
- File entry = root.openNextFile();
- if (!entry) {
- // No more files
- break;
- } else {
- //There are more lines. Add a , to the end of the previous json object
- if (!firstObject) {
- jsonString = jsonString + ",";
- } else {
- firstObject = false;
- }
- //Filter out all the directory if any
- if (entry.isDirectory()) {
- continue;
- }
- //Read the filename from file
- String filename = "";
- while (entry.available()) {
- filename = filename + entry.readString();
- }
- //Append to the JSON line
- jsonString = jsonString + "{\"filename\":\"" + basename(filename) + "\", \"filepath\":\"" + filename + "\", \"shareid\":\"" + entry.name() + "\"}";
- }
- }
- }
- jsonString += "]";
- r->send(200, "application/json", jsonString);
- }
- //Serve a shared file, do not require login
- void HandleShareAccess(AsyncWebServerRequest *r) {
- String shareID = GetPara(r, "id");
- if (shareID == "") {
- r->send(404, "text/plain", "Not Found");
- return;
- }
- //Download request
- String sharedFilename = GetFilenameFromShareID(shareID);
- if (sharedFilename == "") {
- r->send(404, "text/plain", "Share not found");
- return;
- }
- //Check if the file still exists on SD card
- String realFilepath = "/www" + sharedFilename;
- File targetFile = SD.open(realFilepath);
- if (!targetFile) {
- r->send(404, "text/plain", "Shared file no longer exists");
- return;;
- }
- if (r->hasParam("download")) {
- //Serve the file
- r->send(SDFS, realFilepath, getMime(sharedFilename), false);
- } else if (r->hasParam("prop")) {
- //Serve the file properties
- File targetFile = SD.open(realFilepath);
- if (!targetFile) {
- SendErrorResp(r, "File open failed");
- return;
- }
- String resp = "{\"filename\":\"" + basename(sharedFilename) + "\",\"filepath\":\"" + sharedFilename + "\",\"isDir\":false,\"filesize\":" + String(targetFile.size()) + ",\"shareid\":\"" + shareID + "\"}";
- targetFile.close();
- SendJsonResp(r, resp);
- } else {
- //serve download UI template
- r->send(SDFS, "/www/admin/share.html", "text/html", false);
- return;
- }
- }
- //Clear the shares that no longer exists
- void HandleShareListCleaning(AsyncWebServerRequest *r) {
- if (!HandleAuth(r)) {
- return;
- }
- File root = SD.open(DB_root + "shln/");
- bool firstObject = true;
- if (root) {
- while (true) {
- File entry = root.openNextFile();
- if (!entry) {
- // No more files
- break;
- } else {
- //Filter out all the directory if any
- if (entry.isDirectory()) {
- continue;
- }
- //Read the filename from file
- String filename = "";
- while (entry.available()) {
- filename = filename + entry.readString();
- }
- //Check if the target file still exists
- File targetFile = SD.open("/www" + filename);
- if (!targetFile) {
- //File no longer exists. Remove this share entry
- DBRemove("shln", entry.name());
- DBRemove("shfn", filename);
- } else {
- //File still exists.
- targetFile.close();
- }
- }
- }
- }
- SendOK(r);
- }
- //Get the file share ID from filename, return empty string if not shared
- String GetFileShareIDByFilename(String filepath) {
- return DBRead("shfn", filepath);
- }
- //Get the filename (without /www prefix) from share id
- // return empty string if not found
- String GetFilenameFromShareID(String shareid) {
- return DBRead("shln", shareid);
- }
- //Check if a file is shared
- bool IsFileShared(String filepath) {
- //Check if the file is shared
- return DBKeyExists("shfn", filepath);
- }
|