123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- /*
- FSWebServer - Example WebServer with FS backend for esp8266/esp32
- Copyright (c) 2015 Hristo Gochkov. All rights reserved.
- This file is part of the WebServer library for Arduino environment.
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- upload the contents of the data folder with MkSPIFFS Tool ("ESP32 Sketch Data Upload" in Tools menu in Arduino IDE)
- or you can upload the contents of a folder if you CD in that folder and run the following command:
- for file in `ls -A1`; do curl -F "file=@$PWD/$file" esp32fs.local/edit; done
- access the sample web page at http://esp32fs.local
- edit the page by going to http://esp32fs.local/edit
- */
- #include <WiFi.h>
- #include <WiFiClient.h>
- #include <WebServer.h>
- #include <ESPmDNS.h>
- #define USE_SPIFFS
- // You only need to format the filesystem once
- #define FORMAT_FILESYSTEM false
- #define DBG_OUTPUT_PORT Serial
- #ifdef USE_SPIFFS
- #define FILESYSTEM SPIFFS
- #include <SPIFFS.h>
- #else
- #define FILESYSTEM FFat
- #include <FFat.h>
- #endif
- #include <AutoConnect.h>
- const char* ssid = "wifi-ssid";
- const char* password = "wifi-password";
- const char* host = "esp32fs";
- WebServer server(80);
- //holds the current upload
- File fsUploadFile;
- // Additional lines as the below to apply AutoConnect
- AutoConnect portal(server);
- AutoConnectConfig config;
- //format bytes
- String formatBytes(size_t bytes) {
- if (bytes < 1024) {
- return String(bytes) + "B";
- } else if (bytes < (1024 * 1024)) {
- return String(bytes / 1024.0) + "KB";
- } else if (bytes < (1024 * 1024 * 1024)) {
- return String(bytes / 1024.0 / 1024.0) + "MB";
- } else {
- return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB";
- }
- }
- String getContentType(String filename) {
- if (server.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";
- }
- bool exists(String path){
- bool yes = false;
- File file = FILESYSTEM.open(path, "r");
- if(!file.isDirectory()){
- yes = true;
- }
- file.close();
- return yes;
- }
- bool handleFileRead(String path) {
- DBG_OUTPUT_PORT.println("handleFileRead: " + path);
- if (path.endsWith("/")) {
- path += "index.htm";
- }
- String contentType = getContentType(path);
- String pathWithGz = path + ".gz";
- if (exists(pathWithGz) || exists(path)) {
- if (exists(pathWithGz)) {
- path += ".gz";
- }
- File file = FILESYSTEM.open(path, "r");
- server.streamFile(file, contentType);
- file.close();
- return true;
- }
- return false;
- }
- void handleFileUpload() {
- if (server.uri() != "/edit") {
- return;
- }
- HTTPUpload& upload = server.upload();
- if (upload.status == UPLOAD_FILE_START) {
- String filename = upload.filename;
- if (!filename.startsWith("/")) {
- filename = "/" + filename;
- }
- DBG_OUTPUT_PORT.print("handleFileUpload Name: "); DBG_OUTPUT_PORT.println(filename);
- fsUploadFile = FILESYSTEM.open(filename, "w");
- filename = String();
- } else if (upload.status == UPLOAD_FILE_WRITE) {
- //DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize);
- if (fsUploadFile) {
- fsUploadFile.write(upload.buf, upload.currentSize);
- }
- } else if (upload.status == UPLOAD_FILE_END) {
- if (fsUploadFile) {
- fsUploadFile.close();
- }
- DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
- }
- }
- void handleFileDelete() {
- if (server.args() == 0) {
- return server.send(500, "text/plain", "BAD ARGS");
- }
- String path = server.arg(0);
- DBG_OUTPUT_PORT.println("handleFileDelete: " + path);
- if (path == "/") {
- return server.send(500, "text/plain", "BAD PATH");
- }
- if (!exists(path)) {
- return server.send(404, "text/plain", "FileNotFound");
- }
- FILESYSTEM.remove(path);
- server.send(200, "text/plain", "");
- path = String();
- }
- void handleFileCreate() {
- if (server.args() == 0) {
- return server.send(500, "text/plain", "BAD ARGS");
- }
- String path = server.arg(0);
- DBG_OUTPUT_PORT.println("handleFileCreate: " + path);
- if (path == "/") {
- return server.send(500, "text/plain", "BAD PATH");
- }
- if (exists(path)) {
- return server.send(500, "text/plain", "FILE EXISTS");
- }
- File file = FILESYSTEM.open(path, "w");
- if (file) {
- file.close();
- } else {
- return server.send(500, "text/plain", "CREATE FAILED");
- }
- server.send(200, "text/plain", "");
- path = String();
- }
- void handleFileList() {
- if (!server.hasArg("dir")) {
- server.send(500, "text/plain", "BAD ARGS");
- return;
- }
- String path = server.arg("dir");
- DBG_OUTPUT_PORT.println("handleFileList: " + path);
- File root = FILESYSTEM.open(path);
- path = String();
- String output = "[";
- if(root.isDirectory()){
- File file = root.openNextFile();
- while(file){
- if (output != "[") {
- output += ',';
- }
- output += "{\"type\":\"";
- output += (file.isDirectory()) ? "dir" : "file";
- output += "\",\"name\":\"";
- output += String(file.name()).substring(1);
- output += "\"}";
- file = root.openNextFile();
- }
- }
- output += "]";
- server.send(200, "text/json", output);
- }
- void setup(void) {
- DBG_OUTPUT_PORT.begin(115200);
- DBG_OUTPUT_PORT.print("\n");
- DBG_OUTPUT_PORT.setDebugOutput(true);
- if (FORMAT_FILESYSTEM) FILESYSTEM.format();
- FILESYSTEM.begin();
- {
- File root = FILESYSTEM.open("/");
- File file = root.openNextFile();
- while(file){
- String fileName = file.name();
- size_t fileSize = file.size();
- DBG_OUTPUT_PORT.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
- file = root.openNextFile();
- }
- DBG_OUTPUT_PORT.printf("\n");
- }
- // With applying AutoConnect, making WiFi connection is not necessary.
- //WIFI INIT
- // DBG_OUTPUT_PORT.printf("Connecting to %s\n", ssid);
- // if (String(WiFi.SSID()) != String(ssid)) {
- // WiFi.mode(WIFI_STA);
- // WiFi.begin(ssid, password);
- // }
- // while (WiFi.status() != WL_CONNECTED) {
- // delay(500);
- // DBG_OUTPUT_PORT.print(".");
- // }
- // DBG_OUTPUT_PORT.println("");
- // DBG_OUTPUT_PORT.print("Connected! IP address: ");
- // DBG_OUTPUT_PORT.println(WiFi.localIP());
- // MDNS.begin(host);
- // DBG_OUTPUT_PORT.print("Open http://");
- // DBG_OUTPUT_PORT.print(host);
- // DBG_OUTPUT_PORT.println(".local/edit to see the file browser");
- //SERVER INIT
- //list directory
- server.on("/list", HTTP_GET, handleFileList);
- //load editor
- server.on("/edit", HTTP_GET, []() {
- if (!handleFileRead("/edit.htm")) {
- server.send(404, "text/plain", "FileNotFound");
- }
- });
- //create file
- server.on("/edit", HTTP_PUT, handleFileCreate);
- //delete file
- server.on("/edit", HTTP_DELETE, handleFileDelete);
- //first callback is called after the request has ended with all parsed arguments
- //second callback handles file uploads at that location
- server.on("/edit", HTTP_POST, []() {
- server.send(200, "text/plain", "");
- }, handleFileUpload);
- // Default handler for all URIs not defined above
- // Use it to read files from filesystem
- // To make AutoConnect recognize the 404 handler, replace it with:
- //called when the url is not defined here
- //use it to load content from FILESYSTEM
- // server.onNotFound([]() {
- portal.onNotFound([]() {
- if (!handleFileRead(server.uri())) {
- server.send(404, "text/plain", "FileNotFound");
- }
- });
- //get heap status, analog input value and all GPIO statuses in one json call
- server.on("/all", HTTP_GET, []() {
- String json = "{";
- json += "\"heap\":" + String(ESP.getFreeHeap());
- json += ", \"analog\":" + String(analogRead(A0));
- json += ", \"gpio\":" + String((uint32_t)(0));
- json += "}";
- server.send(200, "text/json", json);
- json = String();
- });
- // server.begin();
- // DBG_OUTPUT_PORT.println("HTTP server started");
- // Start AutoConnect
- config.title = "FSBrowser";
- portal.config(config);
- portal.append("/edit", "Edit");
- portal.append("/list?dir=\"/\"", "List");
- if (portal.begin()) {
- DBG_OUTPUT_PORT.print(F("Connected! IP address: "));
- DBG_OUTPUT_PORT.println(WiFi.localIP());
- }
- DBG_OUTPUT_PORT.println("HTTP server started");
- // With applying AutoConnect, the MDNS service must be started after
- // establishing a WiFi connection.
- // MDNS INIT
- if (MDNS.begin(host)) {
- MDNS.addService("http", "tcp", 80);
- DBG_OUTPUT_PORT.print(F("Open http://"));
- DBG_OUTPUT_PORT.print(host);
- DBG_OUTPUT_PORT.println(F(".local/edit to open the FileSystem Browser"));
- DBG_OUTPUT_PORT.print(F("Open http://"));
- DBG_OUTPUT_PORT.print(host);
- DBG_OUTPUT_PORT.println(F(".local/_ac to AutoConnect statistics"));
- }
- }
- void loop(void) {
- // To make AutoConnect recognize the client handling, replace it with:
- // server.handleClient();
- portal.handleClient();
- }
|