| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- /*
- SDWebServer - Example WebServer with SD Card backend for esp8266
- Copyright (c) 2015 Hristo Gochkov. All rights reserved.
- This file is part of the ESP8266WebServer 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
- Have a FAT Formatted SD Card connected to the SPI port of the ESP8266
- The web root is the SD Card root folder
- File extensions with more than 3 charecters are not supported by the SD Library
- File Names longer than 8 charecters will be truncated by the SD library, so keep filenames shorter
- index.htm is the default index (works on subfolders as well)
- upload the contents of SdRoot to the root of the SDcard and access the editor by going to http://esp8266sd.local/edit
- */
- #include <ESP8266WiFi.h>
- #include <WiFiClient.h>
- #include <ESP8266WebServer.h>
- #include <ESP8266mDNS.h>
- #include <SPI.h>
- #include <SD.h>
- #define DBG_OUTPUT_PORT Serial
- const char* ssid = "**********";
- const char* password = "**********";
- const char* host = "esp8266sd";
- ESP8266WebServer server(80);
- static bool hasSD = false;
- File uploadFile;
- void returnOK() {
- server.send(200, "text/plain", "");
- }
- void returnFail(String msg) {
- server.send(500, "text/plain", msg + "\r\n");
- }
- bool loadFromSdCard(String path){
- String dataType = "text/plain";
- if(path.endsWith("/")) path += "index.htm";
- if(path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
- else if(path.endsWith(".htm")) dataType = "text/html";
- else if(path.endsWith(".css")) dataType = "text/css";
- else if(path.endsWith(".js")) dataType = "application/javascript";
- else if(path.endsWith(".png")) dataType = "image/png";
- else if(path.endsWith(".gif")) dataType = "image/gif";
- else if(path.endsWith(".jpg")) dataType = "image/jpeg";
- else if(path.endsWith(".ico")) dataType = "image/x-icon";
- else if(path.endsWith(".xml")) dataType = "text/xml";
- else if(path.endsWith(".pdf")) dataType = "application/pdf";
- else if(path.endsWith(".zip")) dataType = "application/zip";
- File dataFile = SD.open(path.c_str());
- if(dataFile.isDirectory()){
- path += "/index.htm";
- dataType = "text/html";
- dataFile = SD.open(path.c_str());
- }
- if (!dataFile)
- return false;
- if (server.hasArg("download")) dataType = "application/octet-stream";
- if (server.streamFile(dataFile, dataType) != dataFile.size()) {
- DBG_OUTPUT_PORT.println("Sent less data than expected!");
- }
- dataFile.close();
- return true;
- }
- void handleFileUpload(){
- if(server.uri() != "/edit") return;
- HTTPUpload& upload = server.upload();
- if(upload.status == UPLOAD_FILE_START){
- if(SD.exists((char *)upload.filename.c_str())) SD.remove((char *)upload.filename.c_str());
- uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE);
- DBG_OUTPUT_PORT.print("Upload: START, filename: "); DBG_OUTPUT_PORT.println(upload.filename);
- } else if(upload.status == UPLOAD_FILE_WRITE){
- if(uploadFile) uploadFile.write(upload.buf, upload.currentSize);
- DBG_OUTPUT_PORT.print("Upload: WRITE, Bytes: "); DBG_OUTPUT_PORT.println(upload.currentSize);
- } else if(upload.status == UPLOAD_FILE_END){
- if(uploadFile) uploadFile.close();
- DBG_OUTPUT_PORT.print("Upload: END, Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
- }
- }
- void deleteRecursive(String path){
- File file = SD.open((char *)path.c_str());
- if(!file.isDirectory()){
- file.close();
- SD.remove((char *)path.c_str());
- return;
- }
- file.rewindDirectory();
- while(true) {
- File entry = file.openNextFile();
- if (!entry) break;
- String entryPath = path + "/" +entry.name();
- if(entry.isDirectory()){
- entry.close();
- deleteRecursive(entryPath);
- } else {
- entry.close();
- SD.remove((char *)entryPath.c_str());
- }
- yield();
- }
- SD.rmdir((char *)path.c_str());
- file.close();
- }
- void handleDelete(){
- if(server.args() == 0) return returnFail("BAD ARGS");
- String path = server.arg(0);
- if(path == "/" || !SD.exists((char *)path.c_str())) {
- returnFail("BAD PATH");
- return;
- }
- deleteRecursive(path);
- returnOK();
- }
- void handleCreate(){
- if(server.args() == 0) return returnFail("BAD ARGS");
- String path = server.arg(0);
- if(path == "/" || SD.exists((char *)path.c_str())) {
- returnFail("BAD PATH");
- return;
- }
- if(path.indexOf('.') > 0){
- File file = SD.open((char *)path.c_str(), FILE_WRITE);
- if(file){
- file.write((const char *)0);
- file.close();
- }
- } else {
- SD.mkdir((char *)path.c_str());
- }
- returnOK();
- }
- void printDirectory() {
- if(!server.hasArg("dir")) return returnFail("BAD ARGS");
- String path = server.arg("dir");
- if(path != "/" && !SD.exists((char *)path.c_str())) return returnFail("BAD PATH");
- File dir = SD.open((char *)path.c_str());
- path = String();
- if(!dir.isDirectory()){
- dir.close();
- return returnFail("NOT DIR");
- }
- dir.rewindDirectory();
- server.setContentLength(CONTENT_LENGTH_UNKNOWN);
- server.send(200, "text/json", "");
- WiFiClient client = server.client();
- server.sendContent("[");
- for (int cnt = 0; true; ++cnt) {
- File entry = dir.openNextFile();
- if (!entry)
- break;
- String output;
- if (cnt > 0)
- output = ',';
- output += "{\"type\":\"";
- output += (entry.isDirectory()) ? "dir" : "file";
- output += "\",\"name\":\"";
- output += entry.name();
- output += "\"";
- output += "}";
- server.sendContent(output);
- entry.close();
- }
- server.sendContent("]");
- dir.close();
- }
- void handleNotFound(){
- if(hasSD && loadFromSdCard(server.uri())) return;
- String message = "SDCARD Not Detected\n\n";
- message += "URI: ";
- message += server.uri();
- message += "\nMethod: ";
- message += (server.method() == HTTP_GET)?"GET":"POST";
- message += "\nArguments: ";
- message += server.args();
- message += "\n";
- for (uint8_t i=0; i<server.args(); i++){
- message += " NAME:"+server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
- }
- server.send(404, "text/plain", message);
- DBG_OUTPUT_PORT.print(message);
- }
- void setup(void){
- DBG_OUTPUT_PORT.begin(115200);
- DBG_OUTPUT_PORT.setDebugOutput(true);
- DBG_OUTPUT_PORT.print("\n");
- WiFi.begin(ssid, password);
- DBG_OUTPUT_PORT.print("Connecting to ");
- DBG_OUTPUT_PORT.println(ssid);
- // Wait for connection
- uint8_t i = 0;
- while (WiFi.status() != WL_CONNECTED && i++ < 20) {//wait 10 seconds
- delay(500);
- }
- if(i == 21){
- DBG_OUTPUT_PORT.print("Could not connect to");
- DBG_OUTPUT_PORT.println(ssid);
- while(1) delay(500);
- }
- DBG_OUTPUT_PORT.print("Connected! IP address: ");
- DBG_OUTPUT_PORT.println(WiFi.localIP());
- if (MDNS.begin(host)) {
- MDNS.addService("http", "tcp", 80);
- DBG_OUTPUT_PORT.println("MDNS responder started");
- DBG_OUTPUT_PORT.print("You can now connect to http://");
- DBG_OUTPUT_PORT.print(host);
- DBG_OUTPUT_PORT.println(".local");
- }
- server.on("/list", HTTP_GET, printDirectory);
- server.on("/edit", HTTP_DELETE, handleDelete);
- server.on("/edit", HTTP_PUT, handleCreate);
- server.on("/edit", HTTP_POST, [](){ returnOK(); }, handleFileUpload);
- server.onNotFound(handleNotFound);
- server.begin();
- DBG_OUTPUT_PORT.println("HTTP server started");
- if (SD.begin(SS)){
- DBG_OUTPUT_PORT.println("SD Card initialized.");
- hasSD = true;
- }
- }
- void loop(void){
- server.handleClient();
- }
|