Skip to content

Commit a88d739

Browse files
ficetoficeto
ficeto
authored and
ficeto
committed
plaintext POST fixes and rework of the SD example
Added a single file web editor/browser/uploader and all needed methods to work with the files on the SD Card
1 parent 522d2c8 commit a88d739

File tree

5 files changed

+886
-82
lines changed

5 files changed

+886
-82
lines changed

hardware/esp8266com/esp8266/libraries/ESP8266WebServer/examples/SDWebServer/SDWebServer.ino

+191-80
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,19 @@
2323
File extensions with more than 3 charecters are not supported by the SD Library
2424
File Names longer than 8 charecters will be truncated by the SD library, so keep filenames shorter
2525
index.htm is the default index (works on subfolders as well)
26-
*/
26+
27+
upload the contents of SdRoot to the root of the SDcard and access the editor by going to http://esp8266sd.local/edit
2728
29+
*/
2830
#include <ESP8266WiFi.h>
2931
#include <WiFiClient.h>
3032
#include <ESP8266WebServer.h>
3133
#include <ESP8266mDNS.h>
3234
#include <SPI.h>
3335
#include <SD.h>
3436

35-
//do not go larger than 1460 bytes as that is the maximum that could fit in a packet
3637
#define WWW_BUF_SIZE 1460
38+
#define DBG_OUTPUT_PORT Serial
3739

3840
const char* ssid = "**********";
3941
const char* password = "**********";
@@ -45,31 +47,36 @@ ESP8266WebServer server(80);
4547
static bool hasSD = false;
4648
File uploadFile;
4749

48-
void handleFileUpload(){
49-
if(server.uri() != "/upload") return;
50-
HTTPUpload upload = server.upload();
51-
if(upload.status == UPLOAD_FILE_START){
52-
Serial.print("Upload: START, filename:");
53-
Serial.println(upload.filename);
54-
if(SD.exists((char *)upload.filename.c_str())) SD.remove((char *)upload.filename.c_str());
55-
uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE);
56-
} else if(upload.status == UPLOAD_FILE_WRITE){
57-
Serial.print("Upload: WRITE, Bytes:");
58-
Serial.println(upload.buflen);
59-
if(uploadFile) uploadFile.write(upload.buf, upload.buflen);
60-
} else if(upload.status == UPLOAD_FILE_END){
61-
Serial.print("Upload: END, Size:");
62-
Serial.println(upload.size);
63-
if(uploadFile) uploadFile.close();
64-
}
50+
void returnOK(){
51+
WiFiClient client = server.client();
52+
String message = "HTTP/1.1 200 OK\r\n";
53+
message += "Content-Type: text/plain\r\n";
54+
message += "Connection: close\r\n";
55+
message += "Access-Control-Allow-Origin: *\r\n";
56+
message += "\r\n";
57+
client.print(message);
58+
message = 0;
59+
client.stop();
60+
}
61+
62+
void returnFail(String msg){
63+
WiFiClient client = server.client();
64+
String message = "HTTP/1.1 500 Fail\r\n";
65+
message += "Content-Type: text/plain\r\n";
66+
message += "Connection: close\r\n";
67+
message += "Access-Control-Allow-Origin: *\r\n";
68+
message += "\r\n";
69+
message += msg;
70+
message += "\r\n";
71+
client.print(message);
72+
message = 0;
73+
client.stop();
6574
}
6675

6776
bool loadFromSdCard(String path){
6877
String dataType = "text/plain";
69-
//handle default index
7078
if(path.endsWith("/")) path += "index.htm";
7179

72-
//set proper Content-Type for the most common extensions
7380
if(path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
7481
else if(path.endsWith(".htm")) dataType = "text/html";
7582
else if(path.endsWith(".css")) dataType = "text/css";
@@ -82,121 +89,225 @@ bool loadFromSdCard(String path){
8289
else if(path.endsWith(".pdf")) dataType = "application/pdf";
8390
else if(path.endsWith(".zip")) dataType = "application/zip";
8491

85-
//Try to open the file
8692
File dataFile = SD.open(path.c_str());
87-
88-
//if it's a folder, try to open the default index
89-
if(dataFile && dataFile.isDirectory()){
93+
if(dataFile.isDirectory()){
9094
path += "/index.htm";
9195
dataType = "text/html";
9296
dataFile = SD.open(path.c_str());
9397
}
9498

95-
//and finally if the file exists, stream the content to the client
99+
if(server.hasArg("download")) dataType = "application/octet-stream";
100+
96101
if (dataFile) {
97102
WiFiClient client = server.client();
98-
//send the file headers
99103
String head = "HTTP/1.1 200 OK\r\nContent-Type: ";
100104
head += dataType;
101105
head += "\r\nContent-Length: ";
102106
head += dataFile.size();
107+
head += "\r\nConnection: close";
108+
head += "\r\nAccess-Control-Allow-Origin: *";
103109
head += "\r\n\r\n";
104110
client.print(head);
111+
dataType = 0;
112+
path = 0;
105113

106-
//partition the data packets to fit in a TCP packet (1460 bytes MAX)
107114
uint8_t obuf[WWW_BUF_SIZE];
115+
108116
while (dataFile.available() > WWW_BUF_SIZE){
109117
dataFile.read(obuf, WWW_BUF_SIZE);
110118
if(client.write(obuf, WWW_BUF_SIZE) != WWW_BUF_SIZE){
111-
Serial.println("Sent less data than expected!");
119+
DBG_OUTPUT_PORT.println("Sent less data than expected!");
112120
dataFile.close();
113121
return true;
114122
}
115123
}
116-
//stream the last data left (size is at most WWW_BUF_SIZE bytes)
117124
uint16_t leftLen = dataFile.available();
118125
dataFile.read(obuf, leftLen);
119126
if(client.write(obuf, leftLen) != leftLen){
120-
Serial.println("Sent less data than expected!");
127+
DBG_OUTPUT_PORT.println("Sent less data than expected!");
121128
dataFile.close();
122129
return true;
123130
}
124-
125131
dataFile.close();
132+
client.stop();
126133
return true;
127134
}
128135
return false;
129136
}
130137

131-
void tryLoadFromSdCard(){
132-
String message = "FileNotFound\n\n";
133-
if(hasSD){
134-
//try to load the URL from SD Card
135-
if(loadFromSdCard(server.uri())) return;
138+
void handleFileUpload(){
139+
if(server.uri() != "/edit") return;
140+
HTTPUpload upload = server.upload();
141+
if(upload.status == UPLOAD_FILE_START){
142+
if(SD.exists((char *)upload.filename.c_str())) SD.remove((char *)upload.filename.c_str());
143+
uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE);
144+
DBG_OUTPUT_PORT.print("Upload: START, filename: "); DBG_OUTPUT_PORT.println(upload.filename);
145+
} else if(upload.status == UPLOAD_FILE_WRITE){
146+
if(uploadFile) uploadFile.write(upload.buf, upload.buflen);
147+
DBG_OUTPUT_PORT.print("Upload: WRITE, Bytes: "); DBG_OUTPUT_PORT.println(upload.buflen);
148+
} else if(upload.status == UPLOAD_FILE_END){
149+
if(uploadFile) uploadFile.close();
150+
DBG_OUTPUT_PORT.print("Upload: END, Size: "); DBG_OUTPUT_PORT.println(upload.size);
151+
}
152+
}
153+
154+
void deleteRecursive(String path){
155+
File file = SD.open((char *)path.c_str());
156+
if(!file.isDirectory()){
157+
file.close();
158+
SD.remove((char *)path.c_str());
159+
return;
160+
}
161+
file.rewindDirectory();
162+
File entry;
163+
String entryPath;
164+
while(true) {
165+
entry = file.openNextFile();
166+
if (!entry) break;
167+
entryPath = path + "/" +entry.name();
168+
if(entry.isDirectory()){
169+
entry.close();
170+
deleteRecursive(entryPath);
171+
} else {
172+
entry.close();
173+
SD.remove((char *)entryPath.c_str());
174+
}
175+
entryPath = 0;
176+
yield();
177+
}
178+
SD.rmdir((char *)path.c_str());
179+
path = 0;
180+
file.close();
181+
}
182+
183+
void handleDelete(){
184+
if(server.args() == 0) return returnFail("BAD ARGS");
185+
String path = server.arg(0);
186+
if(path == "/" || !SD.exists((char *)path.c_str())) return returnFail("BAD PATH");
187+
deleteRecursive(path);
188+
returnOK();
189+
path = 0;
190+
}
191+
192+
void handleCreate(){
193+
if(server.args() == 0) return returnFail("BAD ARGS");
194+
String path = server.arg(0);
195+
if(path == "/" || SD.exists((char *)path.c_str())) return returnFail("BAD PATH");
196+
if(path.indexOf('.') > 0){
197+
File file = SD.open((char *)path.c_str(), FILE_WRITE);
198+
if(file){
199+
file.write((const char *)0);
200+
file.close();
201+
}
136202
} else {
137-
message = "SDCARD Not Detected\n\n";
203+
SD.mkdir((char *)path.c_str());
204+
}
205+
returnOK();
206+
path = 0;
207+
}
208+
209+
void printDirectory() {
210+
if(!server.hasArg("dir")) return returnFail("BAD ARGS");
211+
String path = server.arg("dir");
212+
if(path != "/" && !SD.exists((char *)path.c_str())) return returnFail("BAD PATH");
213+
File dir = SD.open((char *)path.c_str());
214+
path = 0;
215+
if(!dir.isDirectory()){
216+
dir.close();
217+
return returnFail("NOT DIR");
218+
}
219+
dir.rewindDirectory();
220+
221+
File entry;
222+
WiFiClient client = server.client();
223+
client.print("HTTP/1.1 200 OK\r\nContent-Type: text/json\r\n\r\n");
224+
String output = "[";
225+
while(true) {
226+
entry = dir.openNextFile();
227+
if (!entry) break;
228+
if(output != "[") output += ',';
229+
output += "{\"type\":\"";
230+
output += (entry.isDirectory())?"dir":"file";
231+
output += "\",\"name\":\"";
232+
output += entry.name();
233+
output += "\"";
234+
output += "}";
235+
entry.close();
236+
if(output.length() > 1460){
237+
client.write(output.substring(0, 1460).c_str(), 1460);
238+
output = output.substring(1460);
239+
}
240+
}
241+
dir.close();
242+
output += "]";
243+
client.write(output.c_str(), output.length());
244+
client.stop();
245+
output = 0;
246+
}
247+
248+
void handleNotFound(){
249+
if(hasSD && loadFromSdCard(server.uri())) return;
250+
String message = "SDCARD Not Detected\n\n";
251+
message += "URI: ";
252+
message += server.uri();
253+
message += "\nMethod: ";
254+
message += (server.method() == HTTP_GET)?"GET":"POST";
255+
message += "\nArguments: ";
256+
message += server.args();
257+
message += "\n";
258+
for (uint8_t i=0; i<server.args(); i++){
259+
message += " NAME:"+server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
138260
}
139261
server.send(404, "text/plain", message);
262+
DBG_OUTPUT_PORT.print(message);
140263
}
141-
264+
142265
void setup(void){
143-
uint8_t i = 0;
144-
Serial.begin(115200);
145-
146-
//setup WiFi
266+
DBG_OUTPUT_PORT.begin(115200);
267+
DBG_OUTPUT_PORT.setDebugOutput(true);
268+
DBG_OUTPUT_PORT.print("\n");
147269
WiFi.begin(ssid, password);
148-
Serial.print("\nConnecting to ");
149-
Serial.println(ssid);
270+
DBG_OUTPUT_PORT.print("Connecting to ");
271+
DBG_OUTPUT_PORT.println(ssid);
150272

151-
//wait for WiFi to connect
152-
while (WiFi.status() != WL_CONNECTED && i++ < 20) delay(500);
153-
154-
//check if we have connected?
273+
// Wait for connection
274+
uint8_t i = 0;
275+
while (WiFi.status() != WL_CONNECTED && i++ < 20) {//wait 10 seconds
276+
delay(500);
277+
}
155278
if(i == 21){
156-
Serial.print("Could not connect to");
157-
Serial.println(ssid);
158-
//stop execution and wait forever
279+
DBG_OUTPUT_PORT.print("Could not connect to");
280+
DBG_OUTPUT_PORT.println(ssid);
159281
while(1) delay(500);
160282
}
161-
Serial.print("Connected! IP address: ");
162-
Serial.println(WiFi.localIP());
163-
164-
//start mDNS Server
283+
DBG_OUTPUT_PORT.print("Connected! IP address: ");
284+
DBG_OUTPUT_PORT.println(WiFi.localIP());
285+
/*
165286
if (mdns.begin(hostname, WiFi.localIP())) {
166-
Serial.println("MDNS responder started");
167-
Serial.print("You can now connect to http://");
168-
Serial.print(hostname);
169-
Serial.println(".local");
287+
DBG_OUTPUT_PORT.println("MDNS responder started");
288+
DBG_OUTPUT_PORT.print("You can now connect to http://");
289+
DBG_OUTPUT_PORT.print(hostname);
290+
DBG_OUTPUT_PORT.println(".local");
170291
}
292+
*/
171293

172-
//Attach handler
173-
server.onNotFound(tryLoadFromSdCard);
174-
175-
//Attach Upload handler
294+
server.on("/list", HTTP_GET, printDirectory);
295+
server.on("/edit", HTTP_DELETE, handleDelete);
296+
server.on("/edit", HTTP_PUT, handleCreate);
297+
server.on("/edit", HTTP_POST, [](){ returnOK(); });
298+
server.onNotFound(handleNotFound);
176299
server.onFileUpload(handleFileUpload);
177300

178-
//Attach handler for the Upload location
179-
server.on("/upload", HTTP_POST, [](){
180-
WiFiClient client = server.client();
181-
String message = "HTTP/1.1 200 OK\r\n";
182-
message += "Content-Type: text/plain\r\n";
183-
message += "Access-Control-Allow-Origin: *\r\n";
184-
message += "\r\n";
185-
client.print(message);
186-
});
187-
188-
//start server
189301
server.begin();
190-
Serial.println("HTTP server started");
302+
DBG_OUTPUT_PORT.println("HTTP server started");
191303

192-
//init SD Card
193304
if (SD.begin(SS)){
194-
Serial.println("SD Card initialized.");
305+
DBG_OUTPUT_PORT.println("SD Card initialized.");
195306
hasSD = true;
196307
}
197308
}
198309

199310
void loop(void){
200-
mdns.update();
311+
//mdns.update();
201312
server.handleClient();
202-
}
313+
}

0 commit comments

Comments
 (0)