mirror of
				https://github.com/0xFEEDC0DE64/arduino-esp32.git
				synced 2025-10-31 06:01:39 +01:00 
			
		
		
		
	
		
			
	
	
		
			295 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Arduino
		
	
	
	
	
	
		
		
			
		
	
	
			295 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Arduino
		
	
	
	
	
	
|   | /*
 | ||
|  |   FSWebServer - Example WebServer with SPIFFS backend for esp8266 | ||
|  |   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>
 | ||
|  | #include <SPIFFS.h>
 | ||
|  | 
 | ||
|  | #define DBG_OUTPUT_PORT Serial
 | ||
|  | 
 | ||
|  | const char* ssid = "wifi-ssid"; | ||
|  | const char* password = "wifi-password"; | ||
|  | const char* host = "esp32fs"; | ||
|  | 
 | ||
|  | WebServer server(80); | ||
|  | //holds the current upload
 | ||
|  | File fsUploadFile; | ||
|  | 
 | ||
|  | //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 = SPIFFS.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 = SPIFFS.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 = SPIFFS.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"); | ||
|  |   } | ||
|  |   SPIFFS.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 = SPIFFS.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 = SPIFFS.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); | ||
|  |   SPIFFS.begin(); | ||
|  |   { | ||
|  |       File root = SPIFFS.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"); | ||
|  |   } | ||
|  | 
 | ||
|  | 
 | ||
|  |   //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); | ||
|  | 
 | ||
|  |   //called when the url is not defined here
 | ||
|  |   //use it to load content from SPIFFS
 | ||
|  |   server.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"); | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | void loop(void) { | ||
|  |   server.handleClient(); | ||
|  | } |