Skip to content

Improving WebServer Example #10111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions libraries/WebServer/examples/WebServer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ It is a small project in it's own and has some files to use on the web server to

This example requires some space for a filesystem and runs fine boards with 4 MByte flash using the following options:

* Board: ESP32 Dev Module
* Partition Scheme: Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
but LittleFS will be used in the partition (not SPIFFS)
* For using SPIFFS(LittleFS): Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
* For using FATFS: Default 4MB with ffat (1.2MB APP/1.5MB FATFS)


It features

Expand All @@ -28,9 +28,9 @@ It features

Currently, this example supports the following targets.

| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 |
| ----------------- | ----- | -------- | -------- |
| | yes | yes | yes |
| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 | ESP32-C3 | ESP32-C6 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| | yes | yes | yes | yes | yes |

## Use the Example

Expand Down Expand Up @@ -200,6 +200,7 @@ This class has to implements several functions and works in a more detailed way:

* The `canUpload()`and `upload()` methods work similar while the `upload()` method is called multiple times to create, append data and close the new file.


## File upload

By opening <http://webserver/$upload.htm> you can easily upload files by dragging them over the drop area.
Expand Down Expand Up @@ -238,6 +239,7 @@ You can see on the Serial output that one filesystem write error is reported.
Please be patient and wait for the upload ending even when writing to the filesystem is disabled
it maybe take more than a minute.


## Registering a special handler for "file not found"

Any other incoming request that was not handled by the registered plug-ins above can be detected by registering
Expand All @@ -253,6 +255,7 @@ Any other incoming request that was not handled by the registered plug-ins above
This allows sending back an "friendly" result for the browser. Here a simple html page is created from a static string.
You can easily change the html code in the file `builtinfiles.h`.


## customizations

You may like to change the hostname and the timezone in the lines:
Expand All @@ -262,10 +265,18 @@ You may like to change the hostname and the timezone in the lines:
> #define TIMEZONE "CET-1CEST,M3.5.0,M10.5.0/3"
> ```


## Troubleshooting

Have a look in the Serial output for some additional runtime information.


## Changes

* 2024-08-02 -- Fixing for board implementation 3.0.4 ff.
* 2024-08-02 -- Support for FAT


## Contribute

To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst)
Expand All @@ -274,11 +285,13 @@ If you have any **feedback** or **issue** to report on this example/library, ple

Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else.


## Resources

* Official ESP32 Forum: [Link](https://esp32.com)
* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)
* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf)
* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf)
* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf)
* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf)
* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com)
95 changes: 71 additions & 24 deletions libraries/WebServer/examples/WebServer/WebServer.ino
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,27 @@
//
// Please use the following Arduino IDE configuration
//
// * Board: ESP32 Dev Module
// * Partition Scheme: Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
// * Board: "ESP32 Dev Module" or other board with ESP32
// * Partition Scheme: "Default 4MB with spiffs" or any other scheme with spiffs or FAT
// but LittleFS will be used in the partition (not SPIFFS)
// * other setting as applicable
//
// Changelog:
// 21.07.2021 creation, first version
// 08.01.2023 ESP32 version with ETag
// 02.08.2024 support LitteFS and FAT file systems (on large Flash chips)

#include <Arduino.h>
#include <WebServer.h>
#include <WiFi.h>

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

#include "esp_partition.h" // to check existing data partitions in Flash memory

#include <FS.h> // File System for Web Server Files
#include <LittleFS.h> // This file system is used.
#include <LittleFS.h> // Use LittleFSThis file system is used.
#include <FFat.h> // or.. FAT

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

// The file system in use...
fs::FS *fsys = nullptr;

// The text of builtin files are in this header file
#include "builtinfiles.h"

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

if (!LittleFS.exists(url)) {
if (!fsys->exists(url)) {
url = "/$upload.htm";
}

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

result += "[\n";
Expand Down Expand Up @@ -107,8 +114,15 @@ void handleSysInfo() {
result += " \"Chip Revision\": " + String(ESP.getChipRevision()) + ",\n";
result += " \"flashSize\": " + String(ESP.getFlashChipSize()) + ",\n";
result += " \"freeHeap\": " + String(ESP.getFreeHeap()) + ",\n";
result += " \"fsTotalBytes\": " + String(LittleFS.totalBytes()) + ",\n";
result += " \"fsUsedBytes\": " + String(LittleFS.usedBytes()) + ",\n";

if (fsys == (fs::FS *)&FFat) {
result += " \"fsTotalBytes\": " + String(FFat.totalBytes()) + ",\n";
result += " \"fsUsedBytes\": " + String(FFat.usedBytes()) + ",\n";
} else {
result += " \"fsTotalBytes\": " + String(LittleFS.totalBytes()) + ",\n";
result += " \"fsUsedBytes\": " + String(LittleFS.usedBytes()) + ",\n";
}

result += "}";

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

bool canUpload(String uri) override {
bool canUpload(WebServer &server, String uri) override {
// only allow upload on root fs level.
return (uri == "/");
} // canUpload()
Expand All @@ -148,15 +162,13 @@ public:
fName = "/" + fName;
}

TRACE("handle %s\n", fName.c_str());

if (requestMethod == HTTP_POST) {
// all done in upload. no other forms.

} else if (requestMethod == HTTP_DELETE) {
if (LittleFS.exists(fName)) {
if (fsys->exists(fName)) {
TRACE("DELETE %s\n", fName.c_str());
LittleFS.remove(fName);
fsys->remove(fName);
}
} // if

Expand All @@ -165,7 +177,7 @@ public:
} // handle()

// uploading process
void upload(WebServer UNUSED &server, String UNUSED _requestUri, HTTPUpload &upload) override {
void upload(WebServer UNUSED &server, String requestUri, HTTPUpload &upload) override {
// ensure that filename starts with '/'
static size_t uploadSize;

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

if (LittleFS.exists(fName)) {
LittleFS.remove(fName);
if (fsys->exists(fName)) {
fsys->remove(fName);
} // if
_fsUploadFile = LittleFS.open(fName, "w");
_fsUploadFile = fsys->open(fName, "w");
uploadSize = 0;

} else if (upload.status == UPLOAD_FILE_WRITE) {
Expand All @@ -198,7 +210,7 @@ public:
if (!fName.startsWith("/")) {
fName = "/" + fName;
}
LittleFS.remove(fName);
fsys->remove(fName);
}
uploadSize += upload.currentSize;
// TRACE("free:: %d of %d\n", LittleFS.usedBytes(), LittleFS.totalBytes());
Expand All @@ -207,7 +219,7 @@ public:
} // if

} else if (upload.status == UPLOAD_FILE_END) {
TRACE("finished.\n");
TRACE("upload done.\n");
// Close the file
if (_fsUploadFile) {
_fsUploadFile.close();
Expand All @@ -231,14 +243,49 @@ void setup(void) {

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

// ----- check partitions for finding the fileystem type -----
esp_partition_iterator_t i;

i = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, nullptr);
if (i) {
TRACE("FAT partition found.");
fsys = &FFat;

} else {
i = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, nullptr);
if (i) {
TRACE("SPIFFS partition found.");
fsys = &LittleFS;

} else {
TRACE("no partition found.");
}
}
esp_partition_iterator_release(i);

// mount and format as needed
TRACE("Mounting the filesystem...\n");
if (!LittleFS.begin()) {
if (!fsys) {
TRACE("need to change the board configuration to include a partition for files.\n");
delay(30000);

} else if ((fsys == (fs::FS *)&FFat) && (!FFat.begin())) {
TRACE("could not mount the filesystem...\n");
delay(2000);
TRACE("formatting FAT...\n");
FFat.format();
delay(2000);
TRACE("restarting...\n");
delay(2000);
ESP.restart();

} else if ((fsys == (fs::FS *)&LittleFS) && (!LittleFS.begin())) {
TRACE("could not mount the filesystem...\n");
delay(2000);
TRACE("formatting...\n");
TRACE("formatting LittleFS...\n");
LittleFS.format();
delay(2000);
TRACE("restart.\n");
TRACE("restarting...\n");
delay(2000);
ESP.restart();
}
Expand Down Expand Up @@ -286,7 +333,7 @@ void setup(void) {
// UPLOAD and DELETE of files in the file system using a request handler.
server.addHandler(new FileServerHandler());

// // enable CORS header in webserver results
// enable CORS header in webserver results
server.enableCORS(true);

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

// serve all static files
server.serveStatic("/", LittleFS, "/");
server.serveStatic("/", *fsys, "/");

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

Expand Down
Loading