27
27
28
28
*/
29
29
30
- #include < ESP8266WiFi.h>
31
30
#include < FS.h>
32
- #include < time.h>
31
+ #if defined(ARDUINO_ARCH_ESP8266)
32
+ #include < ESP8266WiFi.h>
33
33
#include < coredecls.h> // crc32()
34
34
#include < PolledTimeout.h>
35
+ #define FILENAME (f ) f.fileName().c_str()
36
+ #define FILEFULLNAME (f ) f.fullName()
37
+ #define FILESIZE (f ) f.fileSize()
38
+ #define FILETIME (f ) f.fileTime()
39
+ #define GETCREATIONTIME (f ) f.getCreationTime()
40
+ #define FILECREATIONTIME (f ) f.fileCreationTime()
41
+ #define ISFILE (f ) f.isFile()
42
+ #endif // ARDUINO_ARCH_ESP8266
43
+ #if defined(ARDUINO_ARCH_ESP32)
44
+ #include < WiFi.h>
45
+ #include " crc32.h"
46
+ #include " PolledTimeout.h"
47
+ #define FILENAME (f ) f.name()
48
+ #define FILEFULLNAME (f ) f.name()
49
+ #define FILESIZE (f ) f.size()
50
+ #define FILETIME (f ) f.getLastWrite()
51
+ #define GETCREATIONTIME (f ) f.getLastWrite()
52
+ #define FILECREATIONTIME (f ) f.getLastWrite()
53
+ #define ISFILE (f ) !f.isDirectory()
54
+ extern uint64_t TotalBytes ();
55
+ extern uint64_t UsedBytes ();
56
+ #endif // ARDUINO_ARCH_ESP32
57
+
58
+ #include < time.h>
59
+
35
60
36
61
#include < ESPWebDAV.h>
37
62
@@ -211,13 +236,13 @@ void ESPWebDAVCore::dir(const String& path, Print* out)
211
236
for (int i = 0 ; i < depth; i++)
212
237
out->print (" " );
213
238
if (entry.isDirectory ())
214
- out->printf (" [%s]\n " , entry. fileName (). c_str ( ));
239
+ out->printf (" [%s]\n " , FILENAME (entry ));
215
240
else
216
241
out->printf (" %-40s%4dMiB %6dKiB %d\n " ,
217
- entry. fileName (). c_str ( ),
218
- ((int )entry. fileSize ( ) + (1 << 19 )) >> 20 ,
219
- ((int )entry. fileSize ( ) + (1 << 9 )) >> 10 ,
220
- (int )entry. fileSize ( ));
242
+ FILENAME (entry ),
243
+ ((int )FILESIZE (entry ) + (1 << 19 )) >> 20 ,
244
+ ((int )FILESIZE (entry ) + (1 << 9 )) >> 10 ,
245
+ (int )FILESIZE (entry ));
221
246
return true ;
222
247
}, /* false=subdir first*/ false );
223
248
}
@@ -227,7 +252,13 @@ size_t ESPWebDAVCore::makeVirtual(virt_e v, String& internal)
227
252
{
228
253
if (v == VIRT_PROC)
229
254
{
255
+ #if defined(ARDUINO_ARCH_ESP8266)
230
256
internal = ESP.getFullVersion ();
257
+ #endif // ARDUINO_ARCH_ESP8266
258
+ #if defined(ARDUINO_ARCH_ESP32)
259
+ internal = " SDK:" ;
260
+ internal += ESP.getSdkVersion ();
261
+ #endif // ARDUINO_ARCH_ESP32
231
262
internal += ' \n ' ;
232
263
}
233
264
return internal.length ();
@@ -252,7 +283,13 @@ bool ESPWebDAVCore::getPayload(StreamString& payload)
252
283
if (contentLengthHeader > 0 )
253
284
{
254
285
payload.reserve (contentLengthHeader);
286
+ #if defined(ARDUINO_ARCH_ESP8266)
255
287
esp8266::polledTimeout::oneShotFastMs timeout (HTTP_MAX_POST_WAIT);
288
+ #endif // ARDUINO_ARCH_ESP8266
289
+ #if defined(ARDUINO_ARCH_ESP32)
290
+ PolledTimeout timeout (HTTP_MAX_POST_WAIT);
291
+ #endif // ARDUINO_ARCH_ESP32
292
+
256
293
while (payload.length () < (size_t )contentLengthHeader)
257
294
{
258
295
uint8_t buf[16 ];
@@ -284,12 +321,19 @@ bool ESPWebDAVCore::dirAction(const String& path,
284
321
int depth)
285
322
{
286
323
// DBG_PRINTF("diraction: scanning dir '%s'\n", path.c_str());
324
+ #if defined(ARDUINO_ARCH_ESP8266)
287
325
Dir entry = gfs->openDir (path);
288
-
289
- while (entry.next ())
326
+ while (entry.next ())
327
+ #endif // ARDUINO_ARCH_ESP8266
328
+ #if defined(ARDUINO_ARCH_ESP32)
329
+ File root = gfs->open (path);
330
+ File entry = root.openNextFile ();
331
+ while (entry)
332
+ #endif // ARDUINO_ARCH_ESP32
333
+ {
290
334
if (!entry.isDirectory ())
291
335
{
292
- // DBG_PRINTF("diraction: %s/%s (%d B): ", path.c_str(), entry.fileName().c_str( ), (int)entry.fileSize());
336
+ // DBG_PRINTF("diraction: %s/%s (%d B): ", path.c_str(), FILENAME(entry ), (int)entry.fileSize());
293
337
if (cb (depth, path, entry))
294
338
{
295
339
// DBG_PRINTF("(file-OK)\n");
@@ -300,16 +344,27 @@ bool ESPWebDAVCore::dirAction(const String& path,
300
344
return false ;
301
345
}
302
346
}
303
-
347
+ #if defined(ARDUINO_ARCH_ESP32)
348
+ entry = root.openNextFile ();
349
+ #endif // ARDUINO_ARCH_ESP32
350
+ }
304
351
if (recursive)
305
352
{
353
+ #if defined(ARDUINO_ARCH_ESP32)
354
+ root = gfs->open (path);
355
+ entry = root.openNextFile ();
356
+ while (entry)
357
+ #endif // ARDUINO_ARCH_ESP32
358
+ #if defined(ARDUINO_ARCH_ESP8266)
306
359
entry = gfs->openDir (path);
307
360
while (entry.next ())
361
+ #endif // ARDUINO_ARCH_ESP8266
362
+ {
308
363
if (entry.isDirectory ())
309
364
{
310
- // DBG_PRINTF("diraction: -------- %s/%s/\n", path.c_str(), entry.fileName().c_str( ));
365
+ // DBG_PRINTF("diraction: -------- %s/%s/\n", path.c_str(), FILENAME(entry ));
311
366
if ((callAfter || cb (depth, path, entry))
312
- && dirAction (path + ' /' + entry. fileName ( ), recursive, cb, callAfter, depth + 1 )
367
+ && dirAction (path + ' /' + FILENAME (entry ), recursive, cb, callAfter, depth + 1 )
313
368
&& (!callAfter || cb (depth, path, entry)))
314
369
{
315
370
// DBG_PRINTF("(dir-OK)\n");
@@ -320,6 +375,10 @@ bool ESPWebDAVCore::dirAction(const String& path,
320
375
return false ;
321
376
}
322
377
}
378
+ #if defined(ARDUINO_ARCH_ESP32)
379
+ entry = root.openNextFile ();
380
+ #endif // ARDUINO_ARCH_ESP32
381
+ }
323
382
}
324
383
325
384
return true ;
@@ -367,17 +426,20 @@ void ESPWebDAVCore::handleRequest()
367
426
depth = DEPTH_ALL;
368
427
DBG_PRINT (" Depth: " ); DBG_PRINTLN (depth);
369
428
}
370
-
371
- // does uri refer to a file or directory or a null?
372
- File file = gfs->open (uri, " r" );
373
- if (file)
374
- {
375
- resource = file.isDirectory () ? RESOURCE_DIR : RESOURCE_FILE;
376
- DBG_PRINTF (" resource: '%s' is %s\n " , uri.c_str (), resource == RESOURCE_DIR ? " dir" : " file" );
429
+ File file;
430
+ if (gfs->exists (uri) || (uri==" /" )){
431
+ // does uri refer to a file or directory or a null?
432
+ file = gfs->open (uri, " r" );
433
+ if (file)
434
+ {
435
+ resource = file.isDirectory () ? RESOURCE_DIR : RESOURCE_FILE;
436
+ DBG_PRINTF (" resource: '%s' is %s\n " , uri.c_str (), resource == RESOURCE_DIR ? " dir" : " file" );
437
+ }
438
+ else
439
+ DBG_PRINTF (" resource: '%s': no file nor dir\n " , uri.c_str ());
440
+ } else {
441
+ DBG_PRINTF (" resource: '%s': not exists\n " , uri.c_str ());
377
442
}
378
- else
379
- DBG_PRINTF (" resource: '%s': no file nor dir\n " , uri.c_str ());
380
-
381
443
382
444
DBG_PRINT (" \r\n m: " ); DBG_PRINT (method);
383
445
DBG_PRINT (" r: " ); DBG_PRINT (resource);
@@ -635,10 +697,10 @@ void ESPWebDAVCore::handleProp(ResourceType resource, File& file)
635
697
// virtual file
636
698
sendPropResponse (false , uri.c_str (), 1024 , time (nullptr ), 0 );
637
699
}
638
- else if (file. isFile ( ) || depth == DEPTH_NONE)
700
+ else if (ISFILE (file ) || depth == DEPTH_NONE)
639
701
{
640
702
DBG_PRINTF (" ----- PROP FILE '%s':\n " , uri.c_str ());
641
- sendPropResponse (file.isDirectory (), uri.c_str (), file.size (), file.getLastWrite (), file. getCreationTime ( ));
703
+ sendPropResponse (file.isDirectory (), uri.c_str (), file.size (), file.getLastWrite (), GETCREATIONTIME (file ));
642
704
}
643
705
else
644
706
{
@@ -650,30 +712,51 @@ void ESPWebDAVCore::handleProp(ResourceType resource, File& file)
650
712
// /XXX fixme: more generic way to list virtual file list
651
713
sendPropResponse (false , PROC, 1024 , time (nullptr ), 0 );
652
714
}
653
-
715
+ #if defined(ARDUINO_ARCH_ESP32)
716
+ File root = gfs->open (uri);
717
+ File entry = root.openNextFile ();
718
+ while (entry)
719
+ #endif // ARDUINO_ARCH_ESP32
720
+ #if defined(ARDUINO_ARCH_ESP8266)
654
721
Dir entry = gfs->openDir (uri);
655
- while (entry.next ())
722
+ while (entry.next ())
723
+ #endif // ARDUINO_ARCH_ESP8266
656
724
{
657
725
yield ();
658
726
String path;
659
- path.reserve (uri.length () + 1 + entry. fileName (). length ( ));
727
+ path.reserve (uri.length () + 1 + strlen ( FILENAME (entry) ));
660
728
path += uri;
661
729
path += ' /' ;
662
- path += entry. fileName ( );
730
+ path += FILENAME (entry );
663
731
stripSlashes (path);
664
- sendPropResponse (entry.isDirectory (), path.c_str (), entry.fileSize (), entry.fileTime (), entry.fileCreationTime ());
732
+ sendPropResponse (entry.isDirectory (), path.c_str (), FILESIZE (entry), FILETIME (entry), FILECREATIONTIME (entry));
733
+ #if defined(ARDUINO_ARCH_ESP32)
734
+ entry = root.openNextFile ();
735
+ #endif // ARDUINO_ARCH_ESP32
665
736
}
666
737
}
667
738
668
739
if (payload.indexOf (F (" quota-available-bytes" )) >= 0 ||
669
740
payload.indexOf (F (" quota-used-bytes" )) >= 0 )
670
741
{
742
+ #if defined(ARDUINO_ARCH_ESP8266)
671
743
fs::FSInfo64 info;
672
744
if (gfs->info64 (info))
673
745
{
674
746
sendContentProp (F (" quota-available-bytes" ), String (1.0 * (info.totalBytes - info.usedBytes ), 0 ));
675
747
sendContentProp (F (" quota-used-bytes" ), String (1.0 * info.usedBytes , 0 ));
676
748
}
749
+ #endif // ARDUINO_ARCH_ESP8266
750
+ #if defined(ARDUINO_ARCH_ESP32)
751
+ // NEED TO BE not related to SPIFFS
752
+ // use external functions
753
+ // but SPIFFS/FAT size_t because in MB
754
+ // and SD uint64_t because in GB
755
+ // so use uint64_t
756
+ sendContentProp (F (" quota-available-bytes" ), String (1.0 * (TotalBytes () - UsedBytes ()), 0 ));
757
+ sendContentProp (F (" quota-used-bytes" ), String (1.0 * UsedBytes (), 0 ));
758
+ #endif // ARDUINO_ARCH_ESP32
759
+
677
760
}
678
761
679
762
sendContent (F (" </D:multistatus>" ));
@@ -883,8 +966,18 @@ void ESPWebDAVCore::handlePut(ResourceType resource)
883
966
File file;
884
967
stripName (uri);
885
968
DBG_PRINTF (" create file '%s'\n " , uri.c_str ());
969
+ #if defined(ARDUINO_ARCH_ESP8266)
886
970
if (!(file = gfs->open (uri, " w" )))
971
+ #endif // ARDUINO_ARCH_ESP8266
972
+ #if defined(ARDUINO_ARCH_ESP32)
973
+ String s = uri;
974
+ if (uri[0 ]!=' /' )s = " /" + uri;
975
+ DBG_PRINTF (" Create file %s\n " , s.c_str ());
976
+ if (!(file = gfs->open (s, " w" )))
977
+ #endif // ARDUINO_ARCH_ESP32
978
+ {
887
979
return handleWriteError (" Unable to create a new file" , file);
980
+ }
888
981
889
982
// file is created/open for writing at this point
890
983
// did server send any data in put
@@ -1033,7 +1126,7 @@ void ESPWebDAVCore::handleMove(ResourceType resource, File& src)
1033
1126
return handleIssue (code, " Locked" );
1034
1127
1035
1128
File destFile = gfs->open (dest, " r" );
1036
- if (destFile && !destFile. isFile ( ))
1129
+ if (destFile && !ISFILE (destFile ))
1037
1130
{
1038
1131
dest += ' /' ;
1039
1132
dest += src.name ();
@@ -1100,10 +1193,10 @@ bool ESPWebDAVCore::deleteDir(const String& dir)
1100
1193
{
1101
1194
(void )depth;
1102
1195
String toRemove;
1103
- toRemove.reserve (parent.length () + entry. fileName (). length ( ) + 2 );
1196
+ toRemove.reserve (parent.length () + strlen ( FILENAME (entry) ) + 2 );
1104
1197
toRemove += parent;
1105
1198
toRemove += ' /' ;
1106
- toRemove += entry. fileName ( );
1199
+ toRemove += FILENAME (entry );
1107
1200
bool ok = !!(entry.isDirectory () ? gfs->rmdir (toRemove) : gfs->remove (toRemove));
1108
1201
DBG_PRINTF (" DELETE %s %s: %s\n " , entry.isDirectory () ? " [ dir]" : " [file]" , toRemove.c_str (), ok ? " ok" : " bad" );
1109
1202
return ok;
@@ -1170,9 +1263,17 @@ bool ESPWebDAVCore::copyFile(File srcFile, const String& destName)
1170
1263
return false ;
1171
1264
}
1172
1265
}
1266
+ #if defined(ARDUINO_ARCH_ESP8266)
1173
1267
dest = gfs->open (destName, " w" );
1268
+ #endif // ARDUINO_ARCH_ESP8266
1269
+ #if defined(ARDUINO_ARCH_ESP32)
1270
+ String s = destName;
1271
+ if (destName[0 ]!=' /' )s = " /" + destName;
1272
+ dest = gfs->open (s, " w" );
1273
+ DBG_PRINTF (" Create file %s\n " , s.c_str ());
1274
+ #endif // ARDUINO_ARCH_ESP32
1174
1275
if (!dest)
1175
- {
1276
+ {
1176
1277
handleIssue (413 , " Request Entity Too Large" );
1177
1278
return false ;
1178
1279
}
@@ -1188,7 +1289,7 @@ bool ESPWebDAVCore::copyFile(File srcFile, const String& destName)
1188
1289
handleIssue (500 , " Internal Server Error" );
1189
1290
return false ;
1190
1291
}
1191
- int wr = dest.write (cp, nb);
1292
+ int wr = dest.write (( const uint8_t *) cp, nb);
1192
1293
if (wr != nb)
1193
1294
{
1194
1295
DBG_PRINTF (" copy: short write wr=%d != rd=%d\n " , (int )wr, (int )nb);
@@ -1240,7 +1341,7 @@ void ESPWebDAVCore::handleCopy(ResourceType resource, File& src)
1240
1341
}
1241
1342
1242
1343
DBG_PRINTF (" copy: src='%s'=>'%s' dest='%s'=>'%s' parent:'%s'\n " ,
1243
- uri.c_str (), src. fullName ( ),
1344
+ uri.c_str (), FILEFULLNAME (src ),
1244
1345
destinationHeader.c_str (), destPath.c_str (),
1245
1346
destParentPath.c_str ());
1246
1347
File destParent = gfs->open (destParentPath, " r" );
@@ -1254,20 +1355,21 @@ void ESPWebDAVCore::handleCopy(ResourceType resource, File& src)
1254
1355
if (src.isDirectory ())
1255
1356
{
1256
1357
DBG_PRINTF (" Source is directory\n " );
1257
- if (destParent. isFile ( ))
1358
+ if (ISFILE (destParent ))
1258
1359
{
1259
1360
DBG_PRINTF (" '%s' is not a directory\n " , destParentPath.c_str ());
1260
1361
return handleIssue (409 , " Conflict" );
1261
1362
}
1262
1363
1263
- if (!dirAction (src. fullName ( ), depth == DEPTH_ALL, [this , destParentPath](int depth, const String & parent, Dir & source)->bool
1364
+ if (!dirAction (FILEFULLNAME (src ), depth == DEPTH_ALL, [this , destParentPath](int depth, const String & parent, Dir & source)->bool
1264
1365
{
1265
1366
(void )depth;
1266
1367
(void )parent;
1267
- String destNameX = destParentPath + ' /' + source.fileName ();
1368
+ String destNameX = destParentPath + ' /' ;
1369
+ destNameX += FILENAME (source);
1268
1370
stripName (destNameX);
1269
- DBG_PRINTF (" COPY: '%s' -> '%s'\n " , source. fileName (). c_str ( ), destNameX.c_str ());
1270
- return copyFile (gfs->open (source. fileName ( ), " r" ), destNameX);
1371
+ DBG_PRINTF (" COPY: '%s' -> '%s'\n " , FILENAME (source ), destNameX.c_str ());
1372
+ return copyFile (gfs->open (FILENAME (source ), " r" ), destNameX);
1271
1373
}))
1272
1374
{
1273
1375
return ; // handleIssue already called by failed copyFile() handleIssue(409, "Conflict");
0 commit comments