Уже есть. Реализовано:
1. Загрузка файлов по воздуху
2. Обновление прошивки по воздуху
3. Редактирование страниц в браузере с сохранением результата " на лету" без перезагрузки сервера
В скетч добавляем вкладку HTTP с текстом
Код: Выделить всё
/*
Modul HTTP for ESP_32
part of Arduino Mega Server project
*/
#ifdef HTTP_FEATURE
#include "WebServer.h"
#include "Update.h"
#define HTTP_PORT 8080
WebServer HTTP(HTTP_PORT);
File fsUploadFile;
String getContentType(String filename){
if(HTTP.hasArg("download")) return "application/octet-stream";
else if(filename.endsWith(".htm")) return "text/html";
else if(filename.endsWith(".html")) return "text/html";
else if(filename.endsWith(".css")) return "text/css";
else if(filename.endsWith(".csv")) return "text/plain";
else if(filename.endsWith(".cfg")) return "text/plain";
else if(filename.endsWith(".js")) return "application/javascript";
else if(filename.endsWith(".png")) return "image/png";
else if(filename.endsWith(".gif")) return "image/gif";
else if(filename.endsWith(".jpg")) return "image/jpeg";
else if(filename.endsWith(".ico")) return "image/x-icon";
else if(filename.endsWith(".xml")) return "text/xml";
else if(filename.endsWith(".pdf")) return "application/x-pdf";
else if(filename.endsWith(".zip")) return "application/x-zip";
else if(filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}
bool handleFileRead(String path){
Serial.println("handleFileRead: " + path);
if(path.endsWith("/")) path += "index.htm";
String contentType = getContentType(path);
String pathWithGz = path + ".gz";
if(SD.exists(pathWithGz) || SD.exists(path)){
if(SD.exists(pathWithGz))
path += ".gz";
File file = SD.open(path, "r");
HTTP.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
void handleFileUpload() {
if(HTTP.uri() != "/edit") return;
HTTPUpload& upload = HTTP.upload();
if(upload.status == UPLOAD_FILE_START){
String filename = upload.filename;
if(!filename.startsWith("/")) filename = "/"+filename;
fsUploadFile = SD.open(filename, "w");
filename = String();
} else if(upload.status == UPLOAD_FILE_WRITE){
if(fsUploadFile)
fsUploadFile.write(upload.buf, upload.currentSize);
} else if(upload.status == UPLOAD_FILE_END){
if(fsUploadFile)
fsUploadFile.close();
}
} // handleFileUpload()
void handleFileDelete() {
if(HTTP.args() == 0) return HTTP.send(500, "text/plain", "BAD ARGS");
String path = HTTP.arg(0);
if(path == "/")
return HTTP.send(500, "text/plain", "BAD PATH");
if(!SD.exists(path))
return HTTP.send(404, "text/plain", "FileNotFound");
SD.remove(path);
HTTP.send(200, "text/plain", "");
path = String();
} // handleFileDelete()
void handleFileCreate() {
if(HTTP.args() == 0)
return HTTP.send(500, "text/plain", "BAD ARGS");
String path = HTTP.arg(0);
if(path == "/")
return HTTP.send(500, "text/plain", "BAD PATH");
if(SD.exists(path))
return HTTP.send(500, "text/plain", "FILE EXISTS");
File file = SD.open(path, "w");
if(file)
file.close();
else
return HTTP.send(500, "text/plain", "CREATE FAILED");
HTTP.send(200, "text/plain", "");
path = String();
} // handleFileCreate();
void handleFileList() {
if(!HTTP.hasArg("dir")) {HTTP.send(500, "text/plain", "BAD ARGS"); return;}
String path = HTTP.arg("dir");
if(path != "/" && !SD.exists((char *)path.c_str())) {HTTP.send(500, "text/plain", "BAD PATH"); return;}
File dir = SD.open((char *)path.c_str());
path = String();
if(!dir.isDirectory()){
dir.close();
HTTP.send(500, "text/plain", "BAD DIR");
return;
}
dir.rewindDirectory();
HTTP.setContentLength(CONTENT_LENGTH_UNKNOWN);
HTTP.send(200, "text/json", "");
HTTP.sendContent("[");
for (int cnt = 0; true; ++cnt) {
File entry = dir.openNextFile();
if (!entry)
break;
String output;
if (cnt > 0)
output = ',';
output += "{\"type\":\"";
output += (entry.isDirectory()) ? "dir" : "file";
output += "\",\"name\":\"";
output += String(entry.name()).substring(1);
output += "\"";
output += "}";
HTTP.sendContent(output);
entry.close();
Serial.println(output);//============== вывод в сериал
}
HTTP.sendContent("]");
dir.close();
} // handleFileList()
String Fail = "<!DOCTYPE html><html><head><meta http-equiv='Content-type' content='text/html; charset=utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'></head><style>body{background:#FFA07A;}</style><body><h3>Firmware update:</h3><h2>  FAIL</h2><h3>  Restart ESP</h3></body></html>";
String Ok = "<!DOCTYPE html><html><head><meta http-equiv='Content-type' content='text/html; charset=utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><meta http-equiv='refresh' content='15;update.htm'></head><style>body{background:#E0EEE0;}</style><body><h3>Firmware update:</h3><h2>  OK!</h2></body></html>";
void updateInit() {
HTTP.on("/update", HTTP_POST, [](){
HTTP.sendHeader("Connection", "close");
HTTP.send(200, "text/html", (Update.hasError()) ? Fail : Ok);
delay(500);//=================================
ESP.restart();
},[](){
HTTPUpload& upload = HTTP.upload();
if(upload.status == UPLOAD_FILE_START){
uint32_t maxSketchSpace = 0x140000;
if(!Update.begin(maxSketchSpace)){
Update.printError(Serial);
}
} else if(upload.status == UPLOAD_FILE_WRITE){
if(Update.write(upload.buf, upload.currentSize) != upload.currentSize){
Update.printError(Serial);
}
} else if(upload.status == UPLOAD_FILE_END){
if(Update.end(true)){
Serial.printf("Update Success: %u B\nDownload time: %d sec.\nRebooting...\n", upload.totalSize);
} else {
Update.printError(Serial);
}
}
yield();
});
} // updateInit()
void initHttp() {
HTTP.on("/list", HTTP_GET, handleFileList);
HTTP.on("/edit", HTTP_GET, []() { if (!handleFileRead("edit.htm")) HTTP.send(404, "text/plain", "FileNotFound"); });
HTTP.on("/edit", HTTP_PUT, handleFileCreate);
HTTP.on("/edit", HTTP_DELETE, handleFileDelete);
HTTP.on("/edit", HTTP_POST, []() { HTTP.send(200, "text/plain", ""); }, handleFileUpload);
HTTP.onNotFound([]() { if (!handleFileRead(HTTP.uri())) HTTP.send(404, "text/plain", "FileNotFound"); });
updateInit();
HTTP.begin();
timeStamp();
printValue("HTTP port", String(HTTP_PORT));
moduleHTTP = ENABLE;
started(F("Http"), true);
} // initHttp()
void httpWork() {
HTTP.handleClient();
}
#endif // HTTP_FEATURE
Код: Выделить всё
#define HTTP_FEATURE
----------------------------
byte moduleHTTP = NOT_COMPILLED;
----------------------------
#ifdef HTTP_FEATURE
initHttp();
#endif
--------------------------
#ifdef HTTP_FEATURE
httpWork();
#endif
-------------------------