diff --git a/libraries/ESP8266WebServer/examples/SDWebServer/SDWebServer.ino b/libraries/ESP8266WebServer/examples/SDWebServer/SDWebServer.ino index bdc945d33..f7a1146e9 100644 --- a/libraries/ESP8266WebServer/examples/SDWebServer/SDWebServer.ino +++ b/libraries/ESP8266WebServer/examples/SDWebServer/SDWebServer.ino @@ -23,8 +23,10 @@ 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 #include #include @@ -32,8 +34,8 @@ #include #include -//do not go larger than 1460 bytes as that is the maximum that could fit in a packet #define WWW_BUF_SIZE 1460 +#define DBG_OUTPUT_PORT Serial const char* ssid = "**********"; const char* password = "**********"; @@ -45,31 +47,36 @@ ESP8266WebServer server(80); static bool hasSD = false; File uploadFile; -void handleFileUpload(){ - if(server.uri() != "/upload") return; - HTTPUpload upload = server.upload(); - if(upload.status == UPLOAD_FILE_START){ - Serial.print("Upload: START, filename:"); - Serial.println(upload.filename); - if(SD.exists((char *)upload.filename.c_str())) SD.remove((char *)upload.filename.c_str()); - uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE); - } else if(upload.status == UPLOAD_FILE_WRITE){ - Serial.print("Upload: WRITE, Bytes:"); - Serial.println(upload.buflen); - if(uploadFile) uploadFile.write(upload.buf, upload.buflen); - } else if(upload.status == UPLOAD_FILE_END){ - Serial.print("Upload: END, Size:"); - Serial.println(upload.size); - if(uploadFile) uploadFile.close(); - } +void returnOK(){ + WiFiClient client = server.client(); + String message = "HTTP/1.1 200 OK\r\n"; + message += "Content-Type: text/plain\r\n"; + message += "Connection: close\r\n"; + message += "Access-Control-Allow-Origin: *\r\n"; + message += "\r\n"; + client.print(message); + message = 0; + client.stop(); +} + +void returnFail(String msg){ + WiFiClient client = server.client(); + String message = "HTTP/1.1 500 Fail\r\n"; + message += "Content-Type: text/plain\r\n"; + message += "Connection: close\r\n"; + message += "Access-Control-Allow-Origin: *\r\n"; + message += "\r\n"; + message += msg; + message += "\r\n"; + client.print(message); + message = 0; + client.stop(); } bool loadFromSdCard(String path){ String dataType = "text/plain"; - //handle default index if(path.endsWith("/")) path += "index.htm"; - //set proper Content-Type for the most common extensions 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"; @@ -82,121 +89,225 @@ bool loadFromSdCard(String path){ else if(path.endsWith(".pdf")) dataType = "application/pdf"; else if(path.endsWith(".zip")) dataType = "application/zip"; - //Try to open the file File dataFile = SD.open(path.c_str()); - - //if it's a folder, try to open the default index - if(dataFile && dataFile.isDirectory()){ + if(dataFile.isDirectory()){ path += "/index.htm"; dataType = "text/html"; dataFile = SD.open(path.c_str()); } - //and finally if the file exists, stream the content to the client + if(server.hasArg("download")) dataType = "application/octet-stream"; + if (dataFile) { WiFiClient client = server.client(); - //send the file headers String head = "HTTP/1.1 200 OK\r\nContent-Type: "; head += dataType; head += "\r\nContent-Length: "; head += dataFile.size(); + head += "\r\nConnection: close"; + head += "\r\nAccess-Control-Allow-Origin: *"; head += "\r\n\r\n"; client.print(head); + dataType = 0; + path = 0; - //partition the data packets to fit in a TCP packet (1460 bytes MAX) uint8_t obuf[WWW_BUF_SIZE]; + while (dataFile.available() > WWW_BUF_SIZE){ dataFile.read(obuf, WWW_BUF_SIZE); if(client.write(obuf, WWW_BUF_SIZE) != WWW_BUF_SIZE){ - Serial.println("Sent less data than expected!"); + DBG_OUTPUT_PORT.println("Sent less data than expected!"); dataFile.close(); return true; } } - //stream the last data left (size is at most WWW_BUF_SIZE bytes) uint16_t leftLen = dataFile.available(); dataFile.read(obuf, leftLen); if(client.write(obuf, leftLen) != leftLen){ - Serial.println("Sent less data than expected!"); + DBG_OUTPUT_PORT.println("Sent less data than expected!"); dataFile.close(); return true; } - dataFile.close(); + client.stop(); return true; } return false; } -void tryLoadFromSdCard(){ - String message = "FileNotFound\n\n"; - if(hasSD){ - //try to load the URL from SD Card - if(loadFromSdCard(server.uri())) return; +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.buflen); + DBG_OUTPUT_PORT.print("Upload: WRITE, Bytes: "); DBG_OUTPUT_PORT.println(upload.buflen); + } else if(upload.status == UPLOAD_FILE_END){ + if(uploadFile) uploadFile.close(); + DBG_OUTPUT_PORT.print("Upload: END, Size: "); DBG_OUTPUT_PORT.println(upload.size); + } +} + +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(); + File entry; + String entryPath; + while(true) { + entry = file.openNextFile(); + if (!entry) break; + entryPath = path + "/" +entry.name(); + if(entry.isDirectory()){ + entry.close(); + deleteRecursive(entryPath); + } else { + entry.close(); + SD.remove((char *)entryPath.c_str()); + } + entryPath = 0; + yield(); + } + SD.rmdir((char *)path.c_str()); + path = 0; + 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())) return returnFail("BAD PATH"); + deleteRecursive(path); + returnOK(); + path = 0; +} + +void handleCreate(){ + if(server.args() == 0) return returnFail("BAD ARGS"); + String path = server.arg(0); + if(path == "/" || SD.exists((char *)path.c_str())) return returnFail("BAD PATH"); + if(path.indexOf('.') > 0){ + File file = SD.open((char *)path.c_str(), FILE_WRITE); + if(file){ + file.write((const char *)0); + file.close(); + } } else { - message = "SDCARD Not Detected\n\n"; + SD.mkdir((char *)path.c_str()); + } + returnOK(); + path = 0; +} + +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 = 0; + if(!dir.isDirectory()){ + dir.close(); + return returnFail("NOT DIR"); + } + dir.rewindDirectory(); + + File entry; + WiFiClient client = server.client(); + client.print("HTTP/1.1 200 OK\r\nContent-Type: text/json\r\n\r\n"); + String output = "["; + while(true) { + entry = dir.openNextFile(); + if (!entry) break; + if(output != "[") output += ','; + output += "{\"type\":\""; + output += (entry.isDirectory())?"dir":"file"; + output += "\",\"name\":\""; + output += entry.name(); + output += "\""; + output += "}"; + entry.close(); + if(output.length() > 1460){ + client.write(output.substring(0, 1460).c_str(), 1460); + output = output.substring(1460); + } + } + dir.close(); + output += "]"; + client.write(output.c_str(), output.length()); + client.stop(); + output = 0; +} + +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 + + + SD Editor + + + + + +
+
+
+ + + + diff --git a/libraries/ESP8266WebServer/examples/SDWebServer/SdRoot/index.htm b/libraries/ESP8266WebServer/examples/SDWebServer/SdRoot/index.htm new file mode 100644 index 000000000..55fe5a66c --- /dev/null +++ b/libraries/ESP8266WebServer/examples/SDWebServer/SdRoot/index.htm @@ -0,0 +1,22 @@ + + + + + ESP Index + + + + +

ESP8266 Pin Functions

+ + + diff --git a/libraries/ESP8266WebServer/examples/SDWebServer/SdRoot/pins.png b/libraries/ESP8266WebServer/examples/SDWebServer/SdRoot/pins.png new file mode 100644 index 000000000..ac7fc0f9c Binary files /dev/null and b/libraries/ESP8266WebServer/examples/SDWebServer/SdRoot/pins.png differ diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp b/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp index 0b6d672e2..cc4fffcce 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp @@ -152,7 +152,7 @@ void ESP8266WebServer::handleClient() String formData; //bellow is needed only when POST type request - if(method == HTTP_POST || method == HTTP_PUT || method == HTTP_PATCH){ + if(method == HTTP_POST || method == HTTP_PUT || method == HTTP_PATCH || method == HTTP_DELETE){ String boundaryStr; String headerName; String headerValue; @@ -391,7 +391,8 @@ void ESP8266WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t line = client.readStringUntil('\r'); client.readStringUntil('\n'); if(line.startsWith("--"+boundary)) break; - argValue += line+"\n"; + if(argValue.length() > 0) argValue += "\n"; + argValue += line; } #ifdef DEBUG DEBUG_OUTPUT.print("PostArg Value: ");