1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00
2022-03-04 02:28:47 +03:00

246 lines
7.2 KiB
C++

// @file WebServer.ino
// @brief Example implementation using the ESP8266 WebServer.
//
// See also README.md for instructions and hints.
//
// Changelog:
// 21.07.2021 creation, first version
#include <Arduino.h>
#include <ESP8266WebServer.h>
#include "secrets.h" // add WLAN Credentials in here.
#include <FS.h> // File System for Web Server Files
#include <LittleFS.h> // This file system is used.
// mark parameters not used in example
#define UNUSED __attribute__((unused))
// TRACE output simplified, can be deactivated here
#define TRACE(...) Serial.printf(__VA_ARGS__)
// name of the server. You reach it using http://webserver
#define HOSTNAME "webserver"
// local time zone definition (Berlin)
#define TIMEZONE "CET-1CEST,M3.5.0,M10.5.0/3"
// need a WebServer for http access on port 80.
ESP8266WebServer server(80);
// The text of builtin files are in this header file
#include "builtinfiles.h"
// ===== Simple functions used to answer simple GET requests =====
// This function is called when the WebServer was requested without giving a filename.
// This will redirect to the file index.htm when it is existing otherwise to the built-in $upload.htm page
void handleRedirect() {
TRACE("Redirect...");
String url = "/index.htm";
if (!LittleFS.exists(url)) { url = "/$update.htm"; }
server.sendHeader("Location", url, true);
server.send(302);
} // 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() {
Dir dir = LittleFS.openDir("/");
String result;
result += "[\n";
while (dir.next()) {
if (result.length() > 4) { result += ","; }
result += " {";
result += " \"name\": \"" + dir.fileName() + "\", ";
result += " \"size\": " + String(dir.fileSize()) + ", ";
result += " \"time\": " + String(dir.fileTime());
result += " }\n";
// jc.addProperty("size", dir.fileSize());
} // while
result += "]";
server.sendHeader("Cache-Control", "no-cache");
server.send(200, "text/javascript; charset=utf-8", result);
} // handleListFiles()
// This function is called when the sysInfo service was requested.
void handleSysInfo() {
String result;
FSInfo fs_info;
LittleFS.info(fs_info);
result += "{\n";
result += " \"flashSize\": " + String(ESP.getFlashChipSize()) + ",\n";
result += " \"freeHeap\": " + String(ESP.getFreeHeap()) + ",\n";
result += " \"fsTotalBytes\": " + String(fs_info.totalBytes) + ",\n";
result += " \"fsUsedBytes\": " + String(fs_info.usedBytes) + ",\n";
result += "}";
server.sendHeader("Cache-Control", "no-cache");
server.send(200, "text/javascript; charset=utf-8", result);
} // handleSysInfo()
// ===== Request Handler class used to answer more complex requests =====
// The FileServerHandler is registered to the web server to support DELETE and UPLOAD of files into the filesystem.
class FileServerHandler : public RequestHandler {
public:
// @brief Construct a new File Server Handler object
// @param fs The file system to be used.
// @param path Path to the root folder in the file system that is used for serving static data down and upload.
// @param cache_header Cache Header to be used in replies.
FileServerHandler() {
TRACE("FileServerHandler is registered\n");
}
// @brief check incoming request. Can handle POST for uploads and DELETE.
// @param requestMethod method of the http request line.
// @param requestUri request ressource from the http request line.
// @return true when method can be handled.
bool canHandle(HTTPMethod requestMethod, const String UNUSED &_uri) override {
return ((requestMethod == HTTP_POST) || (requestMethod == HTTP_DELETE));
} // canHandle()
bool canUpload(const String &uri) override {
// only allow upload on root fs level.
return (uri == "/");
} // canUpload()
bool handle(ESP8266WebServer &server, HTTPMethod requestMethod, const String &requestUri) override {
// ensure that filename starts with '/'
String fName = requestUri;
if (!fName.startsWith("/")) { fName = "/" + fName; }
if (requestMethod == HTTP_POST) {
// all done in upload. no other forms.
} else if (requestMethod == HTTP_DELETE) {
if (LittleFS.exists(fName)) { LittleFS.remove(fName); }
} // if
server.send(200); // all done.
return (true);
} // handle()
// uploading process
void upload(ESP8266WebServer UNUSED &server, const String UNUSED &_requestUri, HTTPUpload &upload) override {
// ensure that filename starts with '/'
String fName = upload.filename;
if (!fName.startsWith("/")) { fName = "/" + fName; }
if (upload.status == UPLOAD_FILE_START) {
// Open the file
if (LittleFS.exists(fName)) { LittleFS.remove(fName); } // if
_fsUploadFile = LittleFS.open(fName, "w");
} else if (upload.status == UPLOAD_FILE_WRITE) {
// Write received bytes
if (_fsUploadFile) { _fsUploadFile.write(upload.buf, upload.currentSize); }
} else if (upload.status == UPLOAD_FILE_END) {
// Close the file
if (_fsUploadFile) { _fsUploadFile.close(); }
} // if
} // upload()
protected:
File _fsUploadFile;
};
// Setup everything to make the webserver work.
void setup(void) {
delay(3000); // wait for serial monitor to start completely.
// Use Serial port for some trace information from the example
Serial.begin(115200);
Serial.setDebugOutput(false);
TRACE("Starting WebServer example...\n");
TRACE("Mounting the filesystem...\n");
if (!LittleFS.begin()) {
TRACE("could not mount the filesystem...\n");
delay(2000);
ESP.restart();
}
// start WiFI
WiFi.mode(WIFI_STA);
if (strlen(ssid) == 0) {
WiFi.begin();
} else {
WiFi.begin(ssid, passPhrase);
}
// allow to address the device by the given name e.g. http://webserver
WiFi.setHostname(HOSTNAME);
TRACE("Connect to WiFi...\n");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
TRACE(".");
}
TRACE("connected.\n");
// Ask for the current time using NTP request builtin into ESP firmware.
TRACE("Setup ntp...\n");
configTime(TIMEZONE, "pool.ntp.org");
TRACE("Register service handlers...\n");
// serve a built-in htm page
server.on("/$upload.htm", []() {
server.send(200, "text/html", FPSTR(uploadContent));
});
// register a redirect handler when only domain name is given.
server.on("/", HTTP_GET, handleRedirect);
// register some REST services
server.on("/$list", HTTP_GET, handleListFiles);
server.on("/$sysinfo", HTTP_GET, handleSysInfo);
// UPLOAD and DELETE of files in the file system using a request handler.
server.addHandler(new FileServerHandler());
// enable CORS header in webserver results
server.enableCORS(true);
// enable ETAG header in webserver results from serveStatic handler
server.enableETag(true);
// serve all static files
server.serveStatic("/", LittleFS, "/");
// handle cases when file is not found
server.onNotFound([]() {
// standard not found in browser.
server.send(404, "text/html", FPSTR(notFoundContent));
});
server.begin();
TRACE("hostname=%s\n", WiFi.getHostname());
} // setup
// run the server...
void loop(void) {
server.handleClient();
} // loop()
// end.