23
23
File extensions with more than 3 charecters are not supported by the SD Library
24
24
File Names longer than 8 charecters will be truncated by the SD library, so keep filenames shorter
25
25
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
27
28
29
+ */
28
30
#include < ESP8266WiFi.h>
29
31
#include < WiFiClient.h>
30
32
#include < ESP8266WebServer.h>
31
33
#include < ESP8266mDNS.h>
32
34
#include < SPI.h>
33
35
#include < SD.h>
34
36
35
- // do not go larger than 1460 bytes as that is the maximum that could fit in a packet
36
37
#define WWW_BUF_SIZE 1460
38
+ #define DBG_OUTPUT_PORT Serial
37
39
38
40
const char * ssid = " **********" ;
39
41
const char * password = " **********" ;
@@ -45,31 +47,36 @@ ESP8266WebServer server(80);
45
47
static bool hasSD = false ;
46
48
File uploadFile;
47
49
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 ();
65
74
}
66
75
67
76
bool loadFromSdCard (String path){
68
77
String dataType = " text/plain" ;
69
- // handle default index
70
78
if (path.endsWith (" /" )) path += " index.htm" ;
71
79
72
- // set proper Content-Type for the most common extensions
73
80
if (path.endsWith (" .src" )) path = path.substring (0 , path.lastIndexOf (" ." ));
74
81
else if (path.endsWith (" .htm" )) dataType = " text/html" ;
75
82
else if (path.endsWith (" .css" )) dataType = " text/css" ;
@@ -82,121 +89,225 @@ bool loadFromSdCard(String path){
82
89
else if (path.endsWith (" .pdf" )) dataType = " application/pdf" ;
83
90
else if (path.endsWith (" .zip" )) dataType = " application/zip" ;
84
91
85
- // Try to open the file
86
92
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 ()){
90
94
path += " /index.htm" ;
91
95
dataType = " text/html" ;
92
96
dataFile = SD.open (path.c_str ());
93
97
}
94
98
95
- // and finally if the file exists, stream the content to the client
99
+ if (server.hasArg (" download" )) dataType = " application/octet-stream" ;
100
+
96
101
if (dataFile) {
97
102
WiFiClient client = server.client ();
98
- // send the file headers
99
103
String head = " HTTP/1.1 200 OK\r\n Content-Type: " ;
100
104
head += dataType;
101
105
head += " \r\n Content-Length: " ;
102
106
head += dataFile.size ();
107
+ head += " \r\n Connection: close" ;
108
+ head += " \r\n Access-Control-Allow-Origin: *" ;
103
109
head += " \r\n\r\n " ;
104
110
client.print (head);
111
+ dataType = 0 ;
112
+ path = 0 ;
105
113
106
- // partition the data packets to fit in a TCP packet (1460 bytes MAX)
107
114
uint8_t obuf[WWW_BUF_SIZE];
115
+
108
116
while (dataFile.available () > WWW_BUF_SIZE){
109
117
dataFile.read (obuf, WWW_BUF_SIZE);
110
118
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!" );
112
120
dataFile.close ();
113
121
return true ;
114
122
}
115
123
}
116
- // stream the last data left (size is at most WWW_BUF_SIZE bytes)
117
124
uint16_t leftLen = dataFile.available ();
118
125
dataFile.read (obuf, leftLen);
119
126
if (client.write (obuf, leftLen) != leftLen){
120
- Serial .println (" Sent less data than expected!" );
127
+ DBG_OUTPUT_PORT .println (" Sent less data than expected!" );
121
128
dataFile.close ();
122
129
return true ;
123
130
}
124
-
125
131
dataFile.close ();
132
+ client.stop ();
126
133
return true ;
127
134
}
128
135
return false ;
129
136
}
130
137
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
+ }
136
202
} 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\n Content-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 += " \n Method: " ;
254
+ message += (server.method () == HTTP_GET)?" GET" :" POST" ;
255
+ message += " \n Arguments: " ;
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 " ;
138
260
}
139
261
server.send (404 , " text/plain" , message);
262
+ DBG_OUTPUT_PORT.print (message);
140
263
}
141
-
264
+
142
265
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 " );
147
269
WiFi.begin (ssid, password);
148
- Serial .print (" \n Connecting to " );
149
- Serial .println (ssid);
270
+ DBG_OUTPUT_PORT .print (" Connecting to " );
271
+ DBG_OUTPUT_PORT .println (ssid);
150
272
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
+ }
155
278
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);
159
281
while (1 ) delay (500 );
160
282
}
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
+ /*
165
286
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");
170
291
}
292
+ */
171
293
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);
176
299
server.onFileUpload (handleFileUpload);
177
300
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
189
301
server.begin ();
190
- Serial .println (" HTTP server started" );
302
+ DBG_OUTPUT_PORT .println (" HTTP server started" );
191
303
192
- // init SD Card
193
304
if (SD.begin (SS)){
194
- Serial .println (" SD Card initialized." );
305
+ DBG_OUTPUT_PORT .println (" SD Card initialized." );
195
306
hasSD = true ;
196
307
}
197
308
}
198
309
199
310
void loop (void ){
200
- mdns.update ();
311
+ // mdns.update();
201
312
server.handleClient ();
202
- }
313
+ }
0 commit comments