2021-12-23 22:42:19 +01:00
|
|
|
|
#include "StandWebServer.h"
|
|
|
|
|
|
#ifdef STANDARD_WEB_SERVER
|
2021-12-24 22:49:06 +01:00
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
File uploadFile;
|
|
|
|
|
|
String unsupportedFiles = String();
|
2021-12-24 22:49:06 +01:00
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
static const char TEXT_PLAIN[] PROGMEM = "text/plain";
|
|
|
|
|
|
static const char FS_INIT_ERROR[] PROGMEM = "FS INIT ERROR";
|
|
|
|
|
|
static const char FILE_NOT_FOUND[] PROGMEM = "FileNotFound";
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// static bool fsOK;
|
|
|
|
|
|
// const char* fsName = "LittleFS";
|
2023-04-27 01:29:23 +03:00
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void standWebServerInit() {
|
2021-12-23 22:42:19 +01:00
|
|
|
|
// Кэшировать файлы для быстрой работы
|
2023-10-02 13:59:37 +02:00
|
|
|
|
// если указана директория то все файлы будут отмечены как Directory Request Handler
|
|
|
|
|
|
// если указан файл то он будет отмечен как File Request Handler
|
|
|
|
|
|
HTTP.serveStatic("/build", FileFS, "/build", "max-age=31536000"); // кеширование на 1 год
|
|
|
|
|
|
HTTP.serveStatic("/favicon.ico", FileFS, "/favicon.ico", "max-age=31536000"); // кеширование на 1 год
|
2021-12-23 22:42:19 +01:00
|
|
|
|
|
2022-09-28 01:31:35 +02:00
|
|
|
|
// HTTP.on("/devicelist.json", HTTP_GET, []() {
|
|
|
|
|
|
// HTTP.send(200, "application/json", devListHeapJson);
|
|
|
|
|
|
// });
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// HTTP.on("/settings.h.json", HTTP_GET, []() {
|
|
|
|
|
|
// HTTP.send(200, "application/json", settingsFlashJson);
|
|
|
|
|
|
//});
|
2022-09-28 01:31:35 +02:00
|
|
|
|
// HTTP.on("/settings.f.json", HTTP_GET, []() {
|
|
|
|
|
|
// HTTP.send(200, "application/json", readFile(F("settings.json"), 20000));
|
|
|
|
|
|
// });
|
|
|
|
|
|
// HTTP.on("/params.json", HTTP_GET, []() {
|
|
|
|
|
|
// String json = getParamsJson();
|
|
|
|
|
|
// HTTP.send(200, "application/json", json);
|
|
|
|
|
|
// });
|
|
|
|
|
|
// HTTP.on("/errors.json", HTTP_GET, []() {
|
|
|
|
|
|
// HTTP.send(200, "application/json", errorsHeapJson);
|
|
|
|
|
|
// });
|
|
|
|
|
|
// HTTP.on("/config.json", HTTP_GET, []() {
|
|
|
|
|
|
// HTTP.send(200, "application/json", readFile(F("config.json"), 20000));
|
|
|
|
|
|
// });
|
|
|
|
|
|
// HTTP.on("/layout.json", HTTP_GET, []() {
|
|
|
|
|
|
// HTTP.send(200, "application/json", readFile(F("layout.json"), 20000));
|
|
|
|
|
|
// });
|
|
|
|
|
|
// HTTP.on("/restart", HTTP_GET, []() {
|
|
|
|
|
|
// // ESP.restart();
|
|
|
|
|
|
// HTTP.send(200, "text/plain", "ok");
|
|
|
|
|
|
// });
|
2021-12-23 22:42:19 +01:00
|
|
|
|
|
2022-11-15 23:04:26 +03:00
|
|
|
|
HTTP.on("/set", HTTP_GET, []() {
|
|
|
|
|
|
if (HTTP.hasArg(F("routerssid")) && WiFi.getMode() == WIFI_AP) {
|
2023-10-02 12:32:49 +02:00
|
|
|
|
jsonWriteStr(settingsFlashJson, F("routerssid"), HTTP.arg(F("routerssid")));
|
|
|
|
|
|
syncSettingsFlashJson();
|
|
|
|
|
|
HTTP.send(200, "text/plain", "ok");
|
|
|
|
|
|
}
|
2022-11-15 23:04:26 +03:00
|
|
|
|
|
|
|
|
|
|
if (HTTP.hasArg(F("routerpass")) && WiFi.getMode() == WIFI_AP) {
|
2023-10-02 12:32:49 +02:00
|
|
|
|
jsonWriteStr(settingsFlashJson, F("routerpass"), HTTP.arg(F("routerpass")));
|
|
|
|
|
|
syncSettingsFlashJson();
|
|
|
|
|
|
HTTP.send(200, "text/plain", "ok");
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2022-11-15 23:04:26 +03:00
|
|
|
|
|
2021-12-23 22:42:19 +01:00
|
|
|
|
// Добавляем функцию Update для перезаписи прошивки по WiFi при 1М(256K FileFS) и выше
|
|
|
|
|
|
// httpUpdater.setup(&HTTP);
|
2022-09-28 01:31:35 +02:00
|
|
|
|
|
2021-12-23 22:42:19 +01:00
|
|
|
|
// Запускаем HTTP сервер
|
|
|
|
|
|
HTTP.begin();
|
|
|
|
|
|
|
|
|
|
|
|
// HTTP страницы для работы с FFS
|
2022-08-24 00:21:20 +02:00
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
////////////////////////////////
|
|
|
|
|
|
// WEB SERVER INIT
|
2022-08-24 00:21:20 +02:00
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// Filesystem status
|
|
|
|
|
|
HTTP.on("/status", HTTP_GET, handleStatus);
|
2022-05-19 00:14:53 +03:00
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// List directory
|
|
|
|
|
|
HTTP.on("/list", HTTP_GET, handleFileList);
|
2022-05-19 00:14:53 +03:00
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// Load editor
|
|
|
|
|
|
HTTP.on("/edit", HTTP_GET, handleGetEdit);
|
2022-05-19 00:14:53 +03:00
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// Create file
|
2021-12-23 22:42:19 +01:00
|
|
|
|
HTTP.on("/edit", HTTP_PUT, handleFileCreate);
|
2022-08-24 00:21:20 +02:00
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// Delete file
|
2021-12-23 22:42:19 +01:00
|
|
|
|
HTTP.on("/edit", HTTP_DELETE, handleFileDelete);
|
2022-08-24 00:21:20 +02:00
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// Upload file
|
|
|
|
|
|
// - first callback is called after the request has ended with all parsed arguments
|
|
|
|
|
|
// - second callback handles file upload at that location
|
|
|
|
|
|
HTTP.on("/edit", HTTP_POST, replyOK, handleFileUpload);
|
|
|
|
|
|
|
|
|
|
|
|
// Default handler for all URIs not defined above
|
|
|
|
|
|
// Use it to read files from filesystem
|
|
|
|
|
|
HTTP.onNotFound(handleNotFound);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////
|
|
|
|
|
|
// Utils to return HTTP codes, and determine content-type
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void replyOK() {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
HTTP.send(200, FPSTR(TEXT_PLAIN), "");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void replyOKWithMsg(String msg) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
HTTP.send(200, FPSTR(TEXT_PLAIN), msg);
|
2021-12-23 22:42:19 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void replyNotFound(String msg) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
HTTP.send(404, FPSTR(TEXT_PLAIN), msg);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void replyBadRequest(String msg) {
|
|
|
|
|
|
// DBG_OUTPUT_PORT.println(msg);
|
2023-04-27 01:29:23 +03:00
|
|
|
|
HTTP.send(400, FPSTR(TEXT_PLAIN), msg + "\r\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void replyServerError(String msg) {
|
|
|
|
|
|
// DBG_OUTPUT_PORT.println(msg);
|
2023-04-27 01:29:23 +03:00
|
|
|
|
HTTP.send(500, FPSTR(TEXT_PLAIN), msg + "\r\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
Return the FS type, status and size info
|
|
|
|
|
|
*/
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void handleStatus() {
|
|
|
|
|
|
// DBG_OUTPUT_PORT.println("handleStatus");
|
2023-04-27 01:29:23 +03:00
|
|
|
|
String json;
|
|
|
|
|
|
json.reserve(128);
|
|
|
|
|
|
|
|
|
|
|
|
json = "{\"type\":\"";
|
|
|
|
|
|
json += FS_NAME;
|
|
|
|
|
|
json += "\", \"isOk\":";
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
#ifdef ESP8266
|
2023-04-27 01:29:23 +03:00
|
|
|
|
FSInfo fs_info;
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
FileFS.info(fs_info);
|
|
|
|
|
|
json += F("\"true\", \"totalBytes\":\"");
|
|
|
|
|
|
json += fs_info.totalBytes;
|
|
|
|
|
|
json += F("\", \"usedBytes\":\"");
|
|
|
|
|
|
json += fs_info.usedBytes;
|
|
|
|
|
|
json += "\"";
|
|
|
|
|
|
#endif
|
2023-04-27 01:29:23 +03:00
|
|
|
|
#ifdef ESP32
|
2023-10-02 12:32:49 +02:00
|
|
|
|
json += F("\"true\", \"totalBytes\":\"");
|
|
|
|
|
|
json += String(FileFS.totalBytes());
|
|
|
|
|
|
json += F("\", \"usedBytes\":\"");
|
|
|
|
|
|
json += String(FileFS.usedBytes());
|
|
|
|
|
|
json += "\"";
|
2023-04-27 01:29:23 +03:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
json += F(",\"unsupportedFiles\":\"");
|
|
|
|
|
|
json += unsupportedFiles;
|
|
|
|
|
|
json += "\"}";
|
|
|
|
|
|
|
|
|
|
|
|
HTTP.send(200, "application/json", json);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef ESP32
|
|
|
|
|
|
String getContentType(String filename) {
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (HTTP.hasArg("download")) {
|
|
|
|
|
|
return "application/octet-stream";
|
|
|
|
|
|
} else if (filename.endsWith(".htm")) {
|
|
|
|
|
|
return "text/html";
|
|
|
|
|
|
} else if (filename.endsWith(".html")) {
|
|
|
|
|
|
return "text/html";
|
|
|
|
|
|
} else if (filename.endsWith(".css")) {
|
|
|
|
|
|
return "text/css";
|
|
|
|
|
|
} else if (filename.endsWith(".js")) {
|
|
|
|
|
|
return "application/javascript";
|
|
|
|
|
|
} else if (filename.endsWith(".png")) {
|
|
|
|
|
|
return "image/png";
|
|
|
|
|
|
} else if (filename.endsWith(".gif")) {
|
|
|
|
|
|
return "image/gif";
|
|
|
|
|
|
} else if (filename.endsWith(".jpg")) {
|
|
|
|
|
|
return "image/jpeg";
|
|
|
|
|
|
} else if (filename.endsWith(".ico")) {
|
|
|
|
|
|
return "image/x-icon";
|
|
|
|
|
|
} else if (filename.endsWith(".xml")) {
|
|
|
|
|
|
return "text/xml";
|
|
|
|
|
|
} else if (filename.endsWith(".pdf")) {
|
|
|
|
|
|
return "application/x-pdf";
|
|
|
|
|
|
} else if (filename.endsWith(".zip")) {
|
|
|
|
|
|
return "application/x-zip";
|
|
|
|
|
|
} else if (filename.endsWith(".gz")) {
|
|
|
|
|
|
return "application/x-gzip";
|
|
|
|
|
|
}
|
|
|
|
|
|
return "text/plain";
|
2023-04-27 01:29:23 +03:00
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
Read the given file from the filesystem and stream it back to the client
|
|
|
|
|
|
*/
|
2023-10-02 12:32:49 +02:00
|
|
|
|
bool handleFileRead(String path) {
|
|
|
|
|
|
// DBG_OUTPUT_PORT.println(String("handleFileRead: ") + path);
|
|
|
|
|
|
if (path.endsWith("/")) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
path += "index.html";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String contentType;
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (HTTP.hasArg("download")) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
contentType = F("application/octet-stream");
|
2023-10-02 12:32:49 +02:00
|
|
|
|
} else {
|
|
|
|
|
|
#ifdef ESP32
|
2023-04-27 01:29:23 +03:00
|
|
|
|
contentType = getContentType(path);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef ESP8266
|
|
|
|
|
|
contentType = mime::getContentType(path);
|
2023-10-02 12:32:49 +02:00
|
|
|
|
#endif
|
2023-04-27 01:29:23 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (!FileFS.exists(path)) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// File not found, try gzip version
|
|
|
|
|
|
path = path + ".gz";
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (FileFS.exists(path)) {
|
2021-12-23 22:42:19 +01:00
|
|
|
|
File file = FileFS.open(path, "r");
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (HTTP.streamFile(file, contentType) != file.size()) {
|
|
|
|
|
|
// DBG_OUTPUT_PORT.println("Sent less data than expected!");
|
2023-04-27 01:29:23 +03:00
|
|
|
|
}
|
2021-12-23 22:42:19 +01:00
|
|
|
|
file.close();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2023-04-27 01:29:23 +03:00
|
|
|
|
|
2021-12-23 22:42:19 +01:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
/*
|
|
|
|
|
|
As some FS (e.g. LittleFS) delete the parent folder when the last child has been removed,
|
|
|
|
|
|
return the path of the closest parent still existing
|
|
|
|
|
|
*/
|
2023-10-02 12:32:49 +02:00
|
|
|
|
String lastExistingParent(String path) {
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#ifndef LIBRETINY
|
|
|
|
|
|
while (!path.isEmpty() && !FileFS.exists(path))
|
|
|
|
|
|
#else
|
|
|
|
|
|
while (!path.length()==0 && !FileFS.exists(path))
|
|
|
|
|
|
#endif
|
|
|
|
|
|
{
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (path.lastIndexOf('/') > 0) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
path = path.substring(0, path.lastIndexOf('/'));
|
2023-10-02 12:32:49 +02:00
|
|
|
|
} else {
|
|
|
|
|
|
path = String(); // No slash => the top folder does not exist
|
2023-04-27 01:29:23 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// DBG_OUTPUT_PORT.println(String("Last existing parent: ") + path);
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return path;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
Handle a file upload request
|
|
|
|
|
|
*/
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void handleFileUpload() {
|
|
|
|
|
|
if (HTTP.uri() != "/edit") {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
HTTPUpload &upload = HTTP.upload();
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (upload.status == UPLOAD_FILE_START) {
|
2021-12-23 22:42:19 +01:00
|
|
|
|
String filename = upload.filename;
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// Make sure paths always start with "/"
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (!filename.startsWith("/")) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
filename = "/" + filename;
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// DBG_OUTPUT_PORT.println(String("handleFileUpload Name: ") + filename);
|
2023-04-27 01:29:23 +03:00
|
|
|
|
uploadFile = FileFS.open(filename, "w");
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (!uploadFile) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyServerError(F("CREATE FAILED"));
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// DBG_OUTPUT_PORT.println(String("Upload: START, filename: ") + filename);
|
|
|
|
|
|
} else if (upload.status == UPLOAD_FILE_WRITE) {
|
|
|
|
|
|
if (uploadFile) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
size_t bytesWritten = uploadFile.write(upload.buf, upload.currentSize);
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (bytesWritten != upload.currentSize) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyServerError(F("WRITE FAILED"));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// DBG_OUTPUT_PORT.println(String("Upload: WRITE, Bytes: ") + upload.currentSize);
|
|
|
|
|
|
} else if (upload.status == UPLOAD_FILE_END) {
|
|
|
|
|
|
if (uploadFile) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
uploadFile.close();
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// DBG_OUTPUT_PORT.println(String("Upload: END, Size: ") + upload.totalSize);
|
2023-04-27 01:29:23 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#if defined ESP8266
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void deleteRecursive(String path) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
File file = FileFS.open(path, "r");
|
|
|
|
|
|
bool isDir = file.isDirectory();
|
|
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
|
|
|
|
// If it's a plain file, delete it
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (!isDir) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
FileFS.remove(path);
|
|
|
|
|
|
return;
|
2021-12-23 22:42:19 +01:00
|
|
|
|
}
|
2023-04-27 01:29:23 +03:00
|
|
|
|
Dir dir = FileFS.openDir(path);
|
2023-10-02 12:32:49 +02:00
|
|
|
|
while (dir.next()) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
deleteRecursive(path + '/' + dir.fileName());
|
2023-10-02 12:32:49 +02:00
|
|
|
|
}
|
2023-04-27 01:29:23 +03:00
|
|
|
|
|
|
|
|
|
|
// Then delete the folder itself
|
|
|
|
|
|
FileFS.rmdir(path);
|
2021-12-23 22:42:19 +01:00
|
|
|
|
}
|
2023-04-27 01:29:23 +03:00
|
|
|
|
#endif
|
|
|
|
|
|
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#if defined ESP32 || defined LIBRETINY
|
2023-10-02 12:32:49 +02:00
|
|
|
|
struct treename {
|
|
|
|
|
|
uint8_t type;
|
|
|
|
|
|
char *name;
|
2023-04-27 01:29:23 +03:00
|
|
|
|
};
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void deleteRecursive(String path) {
|
2024-09-20 12:45:17 +03:00
|
|
|
|
fs::File dir = FileFS.open(path.c_str());
|
2023-04-27 01:29:23 +03:00
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (!dir.isDirectory()) {
|
|
|
|
|
|
Serial.printf("%s is a file\n", path);
|
|
|
|
|
|
dir.close();
|
|
|
|
|
|
Serial.printf("result of removing file %s: %d\n", path, FileFS.remove(path));
|
|
|
|
|
|
return;
|
2023-04-27 01:29:23 +03:00
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
Serial.printf("%s is a directory\n", path);
|
2023-10-02 12:32:49 +02:00
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
fs::File entry, nextentry;
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
while (entry = dir.openNextFile()) {
|
|
|
|
|
|
if (entry.isDirectory()) {
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#if defined ESP32
|
2023-10-02 12:32:49 +02:00
|
|
|
|
deleteRecursive(entry.path());
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#elif defined LIBRETINY
|
|
|
|
|
|
deleteRecursive(entry.fullName());
|
|
|
|
|
|
#endif
|
2023-10-02 12:32:49 +02:00
|
|
|
|
} else {
|
|
|
|
|
|
String tmpname = path + "/" + strdup(entry.name()); // buffer file name
|
|
|
|
|
|
entry.close();
|
|
|
|
|
|
Serial.printf("result of removing file %s: %d\n", tmpname, FileFS.remove(tmpname));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2021-12-23 22:42:19 +01:00
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
dir.close();
|
|
|
|
|
|
Serial.printf("result of removing directory %s: %d\n", path, FileFS.rmdir(path));
|
2023-04-27 01:29:23 +03:00
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
|
|
|
|
Handle a file deletion request
|
|
|
|
|
|
Operation | req.responseText
|
|
|
|
|
|
---------------+--------------------------------------------------------------
|
|
|
|
|
|
Delete file | parent of deleted file, or remaining ancestor
|
|
|
|
|
|
Delete folder | parent of deleted folder, or remaining ancestor
|
|
|
|
|
|
*/
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void handleFileDelete() {
|
2021-12-23 22:42:19 +01:00
|
|
|
|
String path = HTTP.arg(0);
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#ifndef LIBRETINY
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (path.isEmpty() || path == "/") {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyBadRequest("BAD PATH");
|
|
|
|
|
|
}
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#else
|
|
|
|
|
|
if (path.length()==0 || path == "/") {
|
|
|
|
|
|
return replyBadRequest("BAD PATH");
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// DBG_OUTPUT_PORT.println(String("handleFileDelete: ") + path);
|
|
|
|
|
|
if (!FileFS.exists(path)) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyNotFound(FPSTR(FILE_NOT_FOUND));
|
|
|
|
|
|
}
|
|
|
|
|
|
deleteRecursive(path);
|
|
|
|
|
|
|
|
|
|
|
|
replyOKWithMsg(lastExistingParent(path));
|
2021-12-23 22:42:19 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
/*
|
|
|
|
|
|
Handle the creation/rename of a new file
|
|
|
|
|
|
Operation | req.responseText
|
|
|
|
|
|
---------------+--------------------------------------------------------------
|
|
|
|
|
|
Create file | parent of created file
|
|
|
|
|
|
Create folder | parent of created folder
|
|
|
|
|
|
Rename file | parent of source file
|
|
|
|
|
|
Move file | parent of source file, or remaining ancestor
|
|
|
|
|
|
Rename folder | parent of source folder
|
|
|
|
|
|
Move folder | parent of source folder, or remaining ancestor
|
|
|
|
|
|
*/
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void handleFileCreate() {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
String path = HTTP.arg("path");
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#ifndef LIBRETINY
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (path.isEmpty()) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyBadRequest(F("PATH ARG MISSING"));
|
|
|
|
|
|
}
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#else
|
|
|
|
|
|
if (path.length()==0) {
|
|
|
|
|
|
return replyBadRequest(F("PATH ARG MISSING"));
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
2023-04-27 01:29:23 +03:00
|
|
|
|
#ifdef USE_SPIFFS
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (checkForUnsupportedPath(path).length() > 0) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyServerError(F("INVALID FILENAME"));
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (path == "/") {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyBadRequest("BAD PATH");
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (FileFS.exists(path)) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyBadRequest(F("PATH FILE EXISTS"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String src = HTTP.arg("src");
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#ifndef LIBRETINY
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (src.isEmpty()) {
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#else
|
|
|
|
|
|
if (src.length()==0) {
|
|
|
|
|
|
#endif
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// No source specified: creation
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// DBG_OUTPUT_PORT.println(String("handleFileCreate: ") + path);
|
|
|
|
|
|
if (path.endsWith("/")) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// Create a folder
|
|
|
|
|
|
path.remove(path.length() - 1);
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (!FileFS.mkdir(path)) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyServerError(F("MKDIR FAILED"));
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
} else {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// Create a file
|
|
|
|
|
|
File file = FileFS.open(path, "w");
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (file) {
|
|
|
|
|
|
#ifdef ESP8266
|
2023-04-27 01:29:23 +03:00
|
|
|
|
file.write((const char *)0);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef ESP32
|
|
|
|
|
|
file.write(0);
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef LIBRETINY
|
|
|
|
|
|
file.write((uint8_t)0);
|
2023-10-02 12:32:49 +02:00
|
|
|
|
#endif
|
2023-04-27 01:29:23 +03:00
|
|
|
|
file.close();
|
2023-10-02 12:32:49 +02:00
|
|
|
|
} else {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyServerError(F("CREATE FAILED"));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (path.lastIndexOf('/') > -1) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
path = path.substring(0, path.lastIndexOf('/'));
|
|
|
|
|
|
}
|
|
|
|
|
|
replyOKWithMsg(path);
|
2023-10-02 12:32:49 +02:00
|
|
|
|
} else {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// Source specified: rename
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (src == "/") {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyBadRequest("BAD SRC");
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (!FileFS.exists(src)) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyBadRequest(F("SRC FILE NOT FOUND"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// DBG_OUTPUT_PORT.println(String("handleFileCreate: ") + path + " from " + src);
|
2023-04-27 01:29:23 +03:00
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (path.endsWith("/")) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
path.remove(path.length() - 1);
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (src.endsWith("/")) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
src.remove(src.length() - 1);
|
|
|
|
|
|
}
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (!FileFS.rename(src, path)) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyServerError(F("RENAME FAILED"));
|
|
|
|
|
|
}
|
|
|
|
|
|
replyOKWithMsg(lastExistingParent(src));
|
|
|
|
|
|
}
|
2021-12-23 22:42:19 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-04-27 01:29:23 +03:00
|
|
|
|
/*
|
|
|
|
|
|
Return the list of files in the directory specified by the "dir" query string parameter.
|
|
|
|
|
|
Also demonstrates the use of chunked responses.
|
|
|
|
|
|
*/
|
|
|
|
|
|
#ifdef ESP8266
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void handleFileList() {
|
|
|
|
|
|
if (!HTTP.hasArg("dir")) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyBadRequest(F("DIR ARG MISSING"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String path = HTTP.arg("dir");
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (path != "/" && !FileFS.exists(path)) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return replyBadRequest("BAD PATH");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// DBG_OUTPUT_PORT.println(String("handleFileList: ") + path);
|
2023-04-27 01:29:23 +03:00
|
|
|
|
Dir dir = FileFS.openDir(path);
|
|
|
|
|
|
path.clear();
|
|
|
|
|
|
|
|
|
|
|
|
// use HTTP/1.1 Chunked response to avoid building a huge temporary string
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (!HTTP.chunkedResponseModeStart(200, "text/json")) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
HTTP.send(505, F("text/html"), F("HTTP1.1 required"));
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// use the same string for every line
|
|
|
|
|
|
String output;
|
|
|
|
|
|
output.reserve(64);
|
2023-10-02 12:32:49 +02:00
|
|
|
|
while (dir.next()) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
#ifdef USE_SPIFFS
|
|
|
|
|
|
String error = checkForUnsupportedPath(dir.fileName());
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (error.length() > 0) {
|
|
|
|
|
|
// DBG_OUTPUT_PORT.println(String("Ignoring ") + error + dir.fileName());
|
2023-04-27 01:29:23 +03:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (output.length()) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
// send string from previous iteration
|
|
|
|
|
|
// as an HTTP chunk
|
|
|
|
|
|
HTTP.sendContent(output);
|
|
|
|
|
|
output = ',';
|
2023-10-02 12:32:49 +02:00
|
|
|
|
} else {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
output = '[';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-12-23 22:42:19 +01:00
|
|
|
|
output += "{\"type\":\"";
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (dir.isDirectory()) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
output += "dir";
|
2023-10-02 12:32:49 +02:00
|
|
|
|
} else {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
output += F("file\",\"size\":\"");
|
|
|
|
|
|
output += dir.fileSize();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
output += F("\",\"name\":\"");
|
|
|
|
|
|
// Always return names without leading "/"
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (dir.fileName()[0] == '/') {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
output += &(dir.fileName()[1]);
|
2023-10-02 12:32:49 +02:00
|
|
|
|
} else {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
output += dir.fileName();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-12-23 22:42:19 +01:00
|
|
|
|
output += "\"}";
|
|
|
|
|
|
}
|
2023-04-27 01:29:23 +03:00
|
|
|
|
|
|
|
|
|
|
// send last string
|
2021-12-23 22:42:19 +01:00
|
|
|
|
output += "]";
|
2023-04-27 01:29:23 +03:00
|
|
|
|
HTTP.sendContent(output);
|
|
|
|
|
|
HTTP.chunkedResponseFinalize();
|
2021-12-23 22:42:19 +01:00
|
|
|
|
}
|
2023-04-27 01:29:23 +03:00
|
|
|
|
#endif
|
|
|
|
|
|
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#if defined ESP32
|
2023-04-27 01:29:23 +03:00
|
|
|
|
void handleFileList() {
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (!HTTP.hasArg("dir")) {
|
|
|
|
|
|
HTTP.send(500, "text/plain", "BAD ARGS");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String path = HTTP.arg("dir");
|
2024-09-20 12:45:17 +03:00
|
|
|
|
if (path != "/" && !FileFS.exists(path)) {
|
|
|
|
|
|
return replyBadRequest("BAD PATH");
|
|
|
|
|
|
}
|
|
|
|
|
|
//path = "/build/";
|
|
|
|
|
|
Serial.println("handleFileList: " + path);
|
|
|
|
|
|
#if defined LIBRETINY
|
|
|
|
|
|
File root = FileFS.open(path.c_str());
|
|
|
|
|
|
//Dir root = FileFS.openDir(path);
|
|
|
|
|
|
Serial.println("handleFileList FIRST OPEN Name: " + String(root.name()));
|
|
|
|
|
|
#else
|
2023-10-02 12:32:49 +02:00
|
|
|
|
File root = FileFS.open(path);
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#endif
|
2023-10-02 12:32:49 +02:00
|
|
|
|
path = String();
|
|
|
|
|
|
|
|
|
|
|
|
String output = "[";
|
|
|
|
|
|
if (root.isDirectory()) {
|
2024-09-20 12:45:17 +03:00
|
|
|
|
Serial.println("handleFileList IS DIR: " + String(root.name()));
|
|
|
|
|
|
//root.close();
|
2023-10-02 12:32:49 +02:00
|
|
|
|
File file = root.openNextFile();
|
2024-09-20 12:45:17 +03:00
|
|
|
|
Serial.println("handleFileList openNextFile: " + String(file.name()));
|
|
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
while (file) {
|
2024-09-20 12:45:17 +03:00
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (output != "[") {
|
|
|
|
|
|
output += ',';
|
|
|
|
|
|
}
|
|
|
|
|
|
output += "{\"type\":\"";
|
|
|
|
|
|
// output += (file.isDirectory()) ? "dir" : "file";
|
|
|
|
|
|
if (file.isDirectory()) {
|
|
|
|
|
|
output += "dir";
|
|
|
|
|
|
} else {
|
|
|
|
|
|
output += F("file\",\"size\":\"");
|
|
|
|
|
|
output += file.size();
|
|
|
|
|
|
}
|
2023-04-27 01:29:23 +03:00
|
|
|
|
|
2023-10-02 12:32:49 +02:00
|
|
|
|
output += "\",\"name\":\"";
|
2023-04-27 01:29:23 +03:00
|
|
|
|
output += String(file.name());
|
2023-10-02 12:32:49 +02:00
|
|
|
|
output += "\"}";
|
|
|
|
|
|
file = root.openNextFile();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
output += "]";
|
|
|
|
|
|
HTTP.send(200, "text/json", output);
|
2023-04-27 01:29:23 +03:00
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#if defined LIBRETINY
|
|
|
|
|
|
void handleFileList() {
|
|
|
|
|
|
if (!HTTP.hasArg("dir")) {
|
|
|
|
|
|
HTTP.send(500, "text/plain", "BAD ARGS");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
String path = HTTP.arg("dir");
|
|
|
|
|
|
if (path != "/" && !FileFS.exists(path)) {
|
|
|
|
|
|
return replyBadRequest("BAD PATH");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lfs_dir_t dir;
|
|
|
|
|
|
struct lfs_info info;
|
|
|
|
|
|
int err = lfs_dir_open(&lfs, &dir, path);
|
|
|
|
|
|
if (err) {
|
|
|
|
|
|
HTTP.send(500, "text/plain", "FAIL OPEN DIR");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
String output = "[";
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
int res = lfs_dir_read(&lfs, &dir, &info);
|
|
|
|
|
|
if (res < 0) {
|
|
|
|
|
|
lfs_dir_close(&lfs, &dir);
|
|
|
|
|
|
return err;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!res) {
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Serial.printf("%s %d", info.name, info.type);
|
|
|
|
|
|
|
|
|
|
|
|
if (output != "[") {
|
|
|
|
|
|
output += ',';
|
|
|
|
|
|
}
|
|
|
|
|
|
output += "{\"type\":\"";
|
|
|
|
|
|
// output += (file.isDirectory()) ? "dir" : "file";
|
|
|
|
|
|
if (info.type == LFS_TYPE_DIR) {
|
|
|
|
|
|
output += "dir";
|
|
|
|
|
|
} else {
|
|
|
|
|
|
output += F("file\",\"size\":\"");
|
|
|
|
|
|
output += info.size;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
output += "\",\"name\":\"";
|
|
|
|
|
|
output += String(info.name);
|
|
|
|
|
|
output += "\"}";
|
|
|
|
|
|
//file = root.openNextFile();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
err = lfs_dir_close(&lfs, &dir);
|
|
|
|
|
|
if (err) {
|
|
|
|
|
|
HTTP.send(500, "text/plain", "FAIL CLOSE DIR");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
output += "]";
|
|
|
|
|
|
HTTP.send(200, "text/json", output);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
2023-04-27 01:29:23 +03:00
|
|
|
|
/*
|
|
|
|
|
|
The "Not Found" handler catches all URI not explicitly declared in code
|
|
|
|
|
|
First try to find and return the requested file from the filesystem,
|
|
|
|
|
|
and if it fails, return a 404 page with debug information
|
|
|
|
|
|
*/
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void handleNotFound() {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
#ifdef ESP8266
|
2023-10-02 12:32:49 +02:00
|
|
|
|
String uri = ESP8266WebServer::urlDecode(HTTP.uri()); // required to read paths with blanks
|
2023-04-27 01:29:23 +03:00
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef ESP32
|
2023-10-02 12:32:49 +02:00
|
|
|
|
String uri = WebServer::urlDecode(HTTP.uri()); // required to read paths with blanks
|
2024-09-20 12:45:17 +03:00
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef LIBRETINY
|
|
|
|
|
|
String uri = WebServer::urlDecode(HTTP.uri()); // required to read paths with blanks
|
2023-04-27 01:29:23 +03:00
|
|
|
|
#endif
|
2023-10-02 12:32:49 +02:00
|
|
|
|
if (handleFileRead(uri)) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Dump debug data
|
|
|
|
|
|
String message;
|
|
|
|
|
|
message.reserve(100);
|
|
|
|
|
|
message = F("Error: File not found\n\nURI: ");
|
|
|
|
|
|
message += uri;
|
|
|
|
|
|
message += F("\nMethod: ");
|
|
|
|
|
|
message += (HTTP.method() == HTTP_GET) ? "GET" : "POST";
|
|
|
|
|
|
message += F("\nArguments: ");
|
|
|
|
|
|
message += HTTP.args();
|
|
|
|
|
|
message += '\n';
|
2023-10-02 12:32:49 +02:00
|
|
|
|
for (uint8_t i = 0; i < HTTP.args(); i++) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
message += F(" NAME:");
|
|
|
|
|
|
message += HTTP.argName(i);
|
|
|
|
|
|
message += F("\n VALUE:");
|
|
|
|
|
|
message += HTTP.arg(i);
|
|
|
|
|
|
message += '\n';
|
2022-09-28 01:31:35 +02:00
|
|
|
|
}
|
2023-04-27 01:29:23 +03:00
|
|
|
|
message += "path=";
|
|
|
|
|
|
message += HTTP.arg("path");
|
|
|
|
|
|
message += '\n';
|
2023-10-02 12:32:49 +02:00
|
|
|
|
// DBG_OUTPUT_PORT.print(message);
|
2023-04-27 01:29:23 +03:00
|
|
|
|
|
|
|
|
|
|
return replyNotFound(message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
This specific handler returns the index.htm (or a gzipped version) from the /edit folder.
|
|
|
|
|
|
If the file is not present but the flag INCLUDE_FALLBACK_INDEX_HTM has been set, falls back to the version
|
|
|
|
|
|
embedded in the program code.
|
|
|
|
|
|
Otherwise, fails with a 404 page with debug information
|
|
|
|
|
|
*/
|
2023-10-02 12:32:49 +02:00
|
|
|
|
void handleGetEdit() {
|
|
|
|
|
|
if (handleFileRead(F("/edit.htm"))) {
|
2023-04-27 01:29:23 +03:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef INCLUDE_FALLBACK_INDEX_HTM
|
|
|
|
|
|
server.sendHeader(F("Content-Encoding"), "gzip");
|
|
|
|
|
|
server.send(200, "text/html", index_htm_gz, index_htm_gz_len);
|
|
|
|
|
|
#else
|
|
|
|
|
|
replyNotFound(FPSTR(FILE_NOT_FOUND));
|
|
|
|
|
|
#endif
|
2022-09-28 01:31:35 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-12-23 22:42:19 +01:00
|
|
|
|
#endif
|