Skip to content

Commit 5b05a34

Browse files
authored
Improving WebServer Example (espressif#10111)
* Update WebServer.ino * Enable FAT and LittleFS filesystems as configured. * use new versions of RequestHandler::canHandle and RequestHandler::canUpload * Update Documentation * Documentation changed accoring review comments. * README.md changed accoring to review comments.
1 parent c4cbc3e commit 5b05a34

File tree

2 files changed

+91
-31
lines changed

2 files changed

+91
-31
lines changed

libraries/WebServer/examples/WebServer/README.md

+20-7
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ This example shows different techniques on how to use and extend the WebServer f
44

55
It is a small project in it's own and has some files to use on the web server to show how to use simple REST based services.
66

7-
This example requires some space for a filesystem and runs fine boards with 4 MByte flash using the following options:
7+
This example requires some space for a filesystem and runs fine on supported SoCs with 4 MByte or more flash by selecting the proper partition table:
8+
9+
* For using SPIFFS(LittleFS): Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
10+
* For using FATFS: Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
811

9-
* Board: ESP32 Dev Module
10-
* Partition Scheme: Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
11-
but LittleFS will be used in the partition (not SPIFFS)
1212

1313
It features
1414

@@ -28,9 +28,9 @@ It features
2828

2929
Currently, this example supports the following targets.
3030

31-
| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 |
32-
| ----------------- | ----- | -------- | -------- |
33-
| | yes | yes | yes |
31+
| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 | ESP32-C3 | ESP32-C6 |
32+
| ----------------- | ----- | -------- | -------- | -------- | -------- |
33+
| | yes | yes | yes | yes | yes |
3434

3535
## Use the Example
3636

@@ -200,6 +200,7 @@ This class has to implements several functions and works in a more detailed way:
200200
201201
* The `canUpload()`and `upload()` methods work similar while the `upload()` method is called multiple times to create, append data and close the new file.
202202
203+
203204
## File upload
204205
205206
By opening <http://webserver/$upload.htm> you can easily upload files by dragging them over the drop area.
@@ -238,6 +239,7 @@ You can see on the Serial output that one filesystem write error is reported.
238239
Please be patient and wait for the upload ending even when writing to the filesystem is disabled
239240
it maybe take more than a minute.
240241
242+
241243
## Registering a special handler for "file not found"
242244
243245
Any other incoming request that was not handled by the registered plug-ins above can be detected by registering
@@ -253,6 +255,7 @@ Any other incoming request that was not handled by the registered plug-ins above
253255
This allows sending back an "friendly" result for the browser. Here a simple html page is created from a static string.
254256
You can easily change the html code in the file `builtinfiles.h`.
255257
258+
256259
## customizations
257260
258261
You may like to change the hostname and the timezone in the lines:
@@ -262,10 +265,18 @@ You may like to change the hostname and the timezone in the lines:
262265
> #define TIMEZONE "CET-1CEST,M3.5.0,M10.5.0/3"
263266
> ```
264267
268+
265269
## Troubleshooting
266270
267271
Have a look in the Serial output for some additional runtime information.
268272
273+
274+
## Changes
275+
276+
* 2024-08-02 -- Fixing for board implementation 3.0.4 ff.
277+
* 2024-08-02 -- Support for FAT
278+
279+
269280
## Contribute
270281
271282
To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst)
@@ -274,11 +285,13 @@ If you have any **feedback** or **issue** to report on this example/library, ple
274285
275286
Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else.
276287
288+
277289
## Resources
278290
279291
* Official ESP32 Forum: [Link](https://esp32.com)
280292
* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)
281293
* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf)
282294
* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf)
295+
* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf)
283296
* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf)
284297
* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com)

libraries/WebServer/examples/WebServer/WebServer.ino

+71-24
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,27 @@
1818
//
1919
// Please use the following Arduino IDE configuration
2020
//
21-
// * Board: ESP32 Dev Module
22-
// * Partition Scheme: Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
21+
// * Board: "ESP32 Dev Module" or other board with ESP32
22+
// * Partition Scheme: "Default 4MB with spiffs" or any other scheme with spiffs or FAT
2323
// but LittleFS will be used in the partition (not SPIFFS)
2424
// * other setting as applicable
2525
//
2626
// Changelog:
2727
// 21.07.2021 creation, first version
2828
// 08.01.2023 ESP32 version with ETag
29+
// 02.08.2024 support LitteFS and FAT file systems (on large Flash chips)
2930

3031
#include <Arduino.h>
3132
#include <WebServer.h>
3233
#include <WiFi.h>
3334

3435
#include "secrets.h" // add WLAN Credentials in here.
3536

37+
#include "esp_partition.h" // to check existing data partitions in Flash memory
38+
3639
#include <FS.h> // File System for Web Server Files
37-
#include <LittleFS.h> // This file system is used.
40+
#include <LittleFS.h> // Use LittleFSThis file system is used.
41+
#include <FFat.h> // or.. FAT
3842

3943
// mark parameters not used in example
4044
#define UNUSED __attribute__((unused))
@@ -51,6 +55,9 @@
5155
// need a WebServer for http access on port 80.
5256
WebServer server(80);
5357

58+
// The file system in use...
59+
fs::FS *fsys = nullptr;
60+
5461
// The text of builtin files are in this header file
5562
#include "builtinfiles.h"
5663

@@ -65,7 +72,7 @@ void handleRedirect() {
6572
TRACE("Redirect...\n");
6673
String url = "/index.htm";
6774

68-
if (!LittleFS.exists(url)) {
75+
if (!fsys->exists(url)) {
6976
url = "/$upload.htm";
7077
}
7178

@@ -76,7 +83,7 @@ void handleRedirect() {
7683
// This function is called when the WebServer was requested to list all existing files in the filesystem.
7784
// a JSON array with file information is returned.
7885
void handleListFiles() {
79-
File dir = LittleFS.open("/", "r");
86+
File dir = fsys->open("/", "r");
8087
String result;
8188

8289
result += "[\n";
@@ -107,8 +114,15 @@ void handleSysInfo() {
107114
result += " \"Chip Revision\": " + String(ESP.getChipRevision()) + ",\n";
108115
result += " \"flashSize\": " + String(ESP.getFlashChipSize()) + ",\n";
109116
result += " \"freeHeap\": " + String(ESP.getFreeHeap()) + ",\n";
110-
result += " \"fsTotalBytes\": " + String(LittleFS.totalBytes()) + ",\n";
111-
result += " \"fsUsedBytes\": " + String(LittleFS.usedBytes()) + ",\n";
117+
118+
if (fsys == (fs::FS *)&FFat) {
119+
result += " \"fsTotalBytes\": " + String(FFat.totalBytes()) + ",\n";
120+
result += " \"fsUsedBytes\": " + String(FFat.usedBytes()) + ",\n";
121+
} else {
122+
result += " \"fsTotalBytes\": " + String(LittleFS.totalBytes()) + ",\n";
123+
result += " \"fsUsedBytes\": " + String(LittleFS.usedBytes()) + ",\n";
124+
}
125+
112126
result += "}";
113127

114128
server.sendHeader("Cache-Control", "no-cache");
@@ -132,11 +146,11 @@ public:
132146
// @param requestMethod method of the http request line.
133147
// @param requestUri request resource from the http request line.
134148
// @return true when method can be handled.
135-
bool canHandle(HTTPMethod requestMethod, String UNUSED uri) override {
149+
bool canHandle(WebServer &server, HTTPMethod requestMethod, String uri) override {
136150
return ((requestMethod == HTTP_POST) || (requestMethod == HTTP_DELETE));
137151
} // canHandle()
138152

139-
bool canUpload(String uri) override {
153+
bool canUpload(WebServer &server, String uri) override {
140154
// only allow upload on root fs level.
141155
return (uri == "/");
142156
} // canUpload()
@@ -148,15 +162,13 @@ public:
148162
fName = "/" + fName;
149163
}
150164

151-
TRACE("handle %s\n", fName.c_str());
152-
153165
if (requestMethod == HTTP_POST) {
154166
// all done in upload. no other forms.
155167

156168
} else if (requestMethod == HTTP_DELETE) {
157-
if (LittleFS.exists(fName)) {
169+
if (fsys->exists(fName)) {
158170
TRACE("DELETE %s\n", fName.c_str());
159-
LittleFS.remove(fName);
171+
fsys->remove(fName);
160172
}
161173
} // if
162174

@@ -165,7 +177,7 @@ public:
165177
} // handle()
166178

167179
// uploading process
168-
void upload(WebServer UNUSED &server, String UNUSED _requestUri, HTTPUpload &upload) override {
180+
void upload(WebServer UNUSED &server, String requestUri, HTTPUpload &upload) override {
169181
// ensure that filename starts with '/'
170182
static size_t uploadSize;
171183

@@ -178,10 +190,10 @@ public:
178190
}
179191
TRACE("start uploading file %s...\n", fName.c_str());
180192

181-
if (LittleFS.exists(fName)) {
182-
LittleFS.remove(fName);
193+
if (fsys->exists(fName)) {
194+
fsys->remove(fName);
183195
} // if
184-
_fsUploadFile = LittleFS.open(fName, "w");
196+
_fsUploadFile = fsys->open(fName, "w");
185197
uploadSize = 0;
186198

187199
} else if (upload.status == UPLOAD_FILE_WRITE) {
@@ -198,7 +210,7 @@ public:
198210
if (!fName.startsWith("/")) {
199211
fName = "/" + fName;
200212
}
201-
LittleFS.remove(fName);
213+
fsys->remove(fName);
202214
}
203215
uploadSize += upload.currentSize;
204216
// TRACE("free:: %d of %d\n", LittleFS.usedBytes(), LittleFS.totalBytes());
@@ -207,7 +219,7 @@ public:
207219
} // if
208220

209221
} else if (upload.status == UPLOAD_FILE_END) {
210-
TRACE("finished.\n");
222+
TRACE("upload done.\n");
211223
// Close the file
212224
if (_fsUploadFile) {
213225
_fsUploadFile.close();
@@ -231,14 +243,49 @@ void setup(void) {
231243

232244
TRACE("Starting WebServer example...\n");
233245

246+
// ----- check partitions for finding the fileystem type -----
247+
esp_partition_iterator_t i;
248+
249+
i = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, nullptr);
250+
if (i) {
251+
TRACE("FAT partition found.");
252+
fsys = &FFat;
253+
254+
} else {
255+
i = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, nullptr);
256+
if (i) {
257+
TRACE("SPIFFS partition found.");
258+
fsys = &LittleFS;
259+
260+
} else {
261+
TRACE("no partition found.");
262+
}
263+
}
264+
esp_partition_iterator_release(i);
265+
266+
// mount and format as needed
234267
TRACE("Mounting the filesystem...\n");
235-
if (!LittleFS.begin()) {
268+
if (!fsys) {
269+
TRACE("need to change the board configuration to include a partition for files.\n");
270+
delay(30000);
271+
272+
} else if ((fsys == (fs::FS *)&FFat) && (!FFat.begin())) {
273+
TRACE("could not mount the filesystem...\n");
274+
delay(2000);
275+
TRACE("formatting FAT...\n");
276+
FFat.format();
277+
delay(2000);
278+
TRACE("restarting...\n");
279+
delay(2000);
280+
ESP.restart();
281+
282+
} else if ((fsys == (fs::FS *)&LittleFS) && (!LittleFS.begin())) {
236283
TRACE("could not mount the filesystem...\n");
237284
delay(2000);
238-
TRACE("formatting...\n");
285+
TRACE("formatting LittleFS...\n");
239286
LittleFS.format();
240287
delay(2000);
241-
TRACE("restart.\n");
288+
TRACE("restarting...\n");
242289
delay(2000);
243290
ESP.restart();
244291
}
@@ -286,7 +333,7 @@ void setup(void) {
286333
// UPLOAD and DELETE of files in the file system using a request handler.
287334
server.addHandler(new FileServerHandler());
288335

289-
// // enable CORS header in webserver results
336+
// enable CORS header in webserver results
290337
server.enableCORS(true);
291338

292339
// enable ETAG header in webserver results (used by serveStatic handler)
@@ -306,7 +353,7 @@ void setup(void) {
306353
#endif
307354

308355
// serve all static files
309-
server.serveStatic("/", LittleFS, "/");
356+
server.serveStatic("/", *fsys, "/");
310357

311358
TRACE("Register default (not found) answer...\n");
312359

0 commit comments

Comments
 (0)