Merge branch 'http-server' of https://github.com/iranl/nuki_hub into http-server

This commit is contained in:
iranl
2024-08-28 22:02:16 +02:00
4 changed files with 156 additions and 108 deletions

View File

@@ -4,7 +4,7 @@
#define NUKI_HUB_VERSION "9.01" #define NUKI_HUB_VERSION "9.01"
#define NUKI_HUB_BUILD "unknownbuildnr" #define NUKI_HUB_BUILD "unknownbuildnr"
#define NUKI_HUB_DATE "2024-08-26" #define NUKI_HUB_DATE "2024-08-27"
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest" #define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json" #define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"

View File

@@ -149,6 +149,7 @@ void WebCfgServer::initialize()
_network->reconfigureDevice(); _network->reconfigureDevice();
return res; return res;
} }
return(ESP_OK);
}); });
#endif #endif
_psychicServer->on("/unpairlock", HTTP_POST, [&](PsychicRequest *request){ _psychicServer->on("/unpairlock", HTTP_POST, [&](PsychicRequest *request){
@@ -225,16 +226,38 @@ void WebCfgServer::initialize()
#endif #endif
}); });
/* PsychicUploadHandler *updateHandler = new PsychicUploadHandler();
_psychicServer->on("/uploadota", HTTP_POST, updateHandler->onUpload([&](PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool final)
[&](PsychicRequest *request) {},
[&](PsychicRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final)
{ {
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in."); if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
return handleOtaUpload(request, filename, index, data, len, final); return handleOtaUpload(request, filename, index, data, len, final);
} }
); );
*/
updateHandler->onRequest([&](PsychicRequest *request) {
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
String result;
if (!Update.hasError())
{
Log->print("Update code or data OK Update.errorString() ");
Log->println(Update.errorString());
result = "<b style='color:green'>Update OK.</b>";
esp_err_t res = request->reply(200,"text/html",result.c_str());
restartEsp(RestartReason::OTACompleted);
return res;
}
else {
result = " Update.errorString() " + String(Update.errorString());
Log->print("ERROR : error ");
Log->println(result.c_str());
esp_err_t res = request->reply(500, "text/html", result.c_str());
restartEsp(RestartReason::OTAAborted);
return res;
}
});
_psychicServer->on("/uploadota", HTTP_POST, updateHandler);
//Update.onProgress(printProgress); //Update.onProgress(printProgress);
} }
@@ -295,27 +318,27 @@ esp_err_t WebCfgServer::buildOtaHtml(PsychicRequest *request, bool debug)
bool manifestSuccess = false; bool manifestSuccess = false;
JsonDocument doc; JsonDocument doc;
NetworkClientSecure *client = new NetworkClientSecure; NetworkClientSecure *clientOTAUpdate = new NetworkClientSecure;
if (client) { if (clientOTAUpdate) {
client->setCACertBundle(x509_crt_imported_bundle_bin_start, x509_crt_imported_bundle_bin_end - x509_crt_imported_bundle_bin_start); clientOTAUpdate->setCACertBundle(x509_crt_imported_bundle_bin_start, x509_crt_imported_bundle_bin_end - x509_crt_imported_bundle_bin_start);
{ {
HTTPClient https; HTTPClient httpsOTAClient;
https.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); httpsOTAClient.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
https.setTimeout(2500); httpsOTAClient.setTimeout(2500);
https.useHTTP10(true); httpsOTAClient.useHTTP10(true);
if (https.begin(*client, GITHUB_OTA_MANIFEST_URL)) { if (httpsOTAClient.begin(*clientOTAUpdate, GITHUB_OTA_MANIFEST_URL)) {
int http_responseCode = https.GET(); int httpResponseCodeOTA = httpsOTAClient.GET();
if (http_responseCode == HTTP_CODE_OK || http_responseCode == HTTP_CODE_MOVED_PERMANENTLY) if (httpResponseCodeOTA == HTTP_CODE_OK || httpResponseCodeOTA == HTTP_CODE_MOVED_PERMANENTLY)
{ {
DeserializationError jsonError = deserializeJson(doc, https.getStream()); DeserializationError jsonError = deserializeJson(doc, httpsOTAClient.getStream());
if (!jsonError) { manifestSuccess = true; } if (!jsonError) { manifestSuccess = true; }
} }
https.end(); httpsOTAClient.end();
} }
} }
delete client; delete clientOTAUpdate;
} }
if(!manifestSuccess) if(!manifestSuccess)
@@ -469,35 +492,32 @@ void WebCfgServer::printProgress(size_t prg, size_t sz) {
Log->printf("Progress: %d%%\n", (prg*100)/_otaContentLen); Log->printf("Progress: %d%%\n", (prg*100)/_otaContentLen);
} }
void WebCfgServer::handleOtaUpload(PsychicRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) esp_err_t WebCfgServer::handleOtaUpload(PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool final)
{ {
if(!request->url().endsWith("/uploadota")) return; if(!request->url().endsWith("/uploadota")) return(ESP_FAIL);
if(filename == "") if(filename == "")
{ {
Log->println("Invalid file for OTA upload"); Log->println("Invalid file for OTA upload");
return; return(ESP_FAIL);
} }
if (!index) if (!Update.hasError()) {
{ if (!index){
Update.clearError();
Log->println("Starting manual OTA update"); Log->println("Starting manual OTA update");
_otaContentLen = request->contentLength(); _otaContentLen = request->contentLength();
if(_partitionType == 1 && _otaContentLen > 1600000) if(_partitionType == 1 && _otaContentLen > 1600000)
{ {
Log->println("Uploaded OTA file too large, are you trying to upload a Nuki Hub binary instead of a Nuki Hub updater binary?"); Log->println("Uploaded OTA file too large, are you trying to upload a Nuki Hub binary instead of a Nuki Hub updater binary?");
return; return(ESP_FAIL);
} }
else if(_partitionType == 2 && _otaContentLen < 1600000) else if(_partitionType == 2 && _otaContentLen < 1600000)
{ {
Log->println("Uploaded OTA file is too small, are you trying to upload a Nuki Hub updater binary instead of a Nuki Hub binary?"); Log->println("Uploaded OTA file is too small, are you trying to upload a Nuki Hub updater binary instead of a Nuki Hub binary?");
return; return(ESP_FAIL);
}
int cmd = U_FLASH;
if (!Update.begin(UPDATE_SIZE_UNKNOWN, cmd)) {
Update.printError(Serial);
} }
_otaStartTs = esp_timer_get_time() / 1000; _otaStartTs = esp_timer_get_time() / 1000;
@@ -522,35 +542,58 @@ void WebCfgServer::handleOtaUpload(PsychicRequest *request, String filename, siz
#endif #endif
Log->print("handleFileUpload Name: "); Log->print("handleFileUpload Name: ");
Log->println(filename); Log->println(filename);
if (!Update.begin(UPDATE_SIZE_UNKNOWN, U_FLASH)) {
if (!Update.hasError())
{
Update.abort();
}
Log->print("ERROR : update.begin error Update.errorString() ");
Log->println(Update.errorString());
return(ESP_FAIL);
}
} }
if (_otaContentLen == 0) return; if ((len) && (!Update.hasError())) {
if (Update.write(data, len) != len) { if (Update.write(data, len) != len) {
Update.printError(Serial); if (!Update.hasError())
restartEsp(RestartReason::OTAAborted); {
Update.abort();
}
Log->print("ERROR : update.write error Update.errorString() ");
Log->println(Update.errorString());
return(ESP_FAIL);
}
} }
/* if ((final) && (!Update.hasError())) {
if (final) { if (Update.end(true)) {
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "Please wait while the device reboots"); Log->print("Update Success: ");
response->addHeader("Refresh", "20"); Log->print(index+len);
response->addHeader("Location", "/"); Log->println(" written");
request->send(response); }
if (!Update.end(true)){ else {
Update.printError(Serial); if (!Update.hasError())
restartEsp(RestartReason::OTAAborted); {
} else { Update.abort();
}
Log->print("ERROR : update end error Update.errorString() ");
Log->println(Update.errorString());
return(ESP_FAIL);
}
}
Log->print(F("Progress: 100%")); Log->print(F("Progress: 100%"));
Log->println(); Log->println();
Log->print("handleFileUpload Total Size: "); Log->print("handleFileUpload Total Size: ");
Log->println(index+len); Log->println(index+len);
Log->println("Update complete"); Log->println("Update complete");
Log->flush(); Log->flush();
restartEsp(RestartReason::OTACompleted); return(ESP_OK);
} }
else
{
return(ESP_FAIL);
} }
*/
} }
esp_err_t WebCfgServer::buildConfirmHtml(PsychicRequest *request, const String &message, uint32_t redirectDelay, bool redirect) esp_err_t WebCfgServer::buildConfirmHtml(PsychicRequest *request, const String &message, uint32_t redirectDelay, bool redirect)

View File

@@ -104,7 +104,7 @@ private:
esp_err_t sendFavicon(PsychicRequest *request); esp_err_t sendFavicon(PsychicRequest *request);
void buildHtmlHeader(PsychicStreamResponse *response, String additionalHeader = ""); void buildHtmlHeader(PsychicStreamResponse *response, String additionalHeader = "");
void waitAndProcess(const bool blocking, const uint32_t duration); void waitAndProcess(const bool blocking, const uint32_t duration);
void handleOtaUpload(PsychicRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); esp_err_t handleOtaUpload(PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool final);
void printProgress(size_t prg, size_t sz); void printProgress(size_t prg, size_t sz);
PsychicHttpServer* _psychicServer = nullptr; PsychicHttpServer* _psychicServer = nullptr;

View File

@@ -19,10 +19,12 @@
#include "Logger.h" #include "Logger.h"
#include "PreferencesKeys.h" #include "PreferencesKeys.h"
#include "RestartReason.h" #include "RestartReason.h"
/*
#ifdef DEBUG_NUKIHUB #ifdef DEBUG_NUKIHUB
#include <WString.h> #include <WString.h>
#include <MycilaWebSerial.h> #include <MycilaWebSerial.h>
#endif #endif
*/
char log_print_buffer[1024]; char log_print_buffer[1024];
@@ -490,6 +492,9 @@ void setup()
if(!doOta) if(!doOta)
{ {
psychicServer = new PsychicHttpServer; psychicServer = new PsychicHttpServer;
psychicServer->config.max_uri_handlers = 40;
psychicServer->config.stack_size = 8192;
psychicServer->listen(80);
if(forceEnableWebServer || preferences->getBool(preference_webserver_enabled, true)) if(forceEnableWebServer || preferences->getBool(preference_webserver_enabled, true))
{ {
@@ -497,18 +502,18 @@ void setup()
webCfgServer->initialize(); webCfgServer->initialize();
psychicServer->onNotFound([](PsychicRequest* request) { return request->redirect("/"); }); psychicServer->onNotFound([](PsychicRequest* request) { return request->redirect("/"); });
} }
/*
#ifdef DEBUG_NUKIHUB #ifdef DEBUG_NUKIHUB
else psychicServer->onNotFound([](PsychicRequest* request) { return request->redirect("/webserial"); }); else psychicServer->onNotFound([](PsychicRequest* request) { return request->redirect("/webserial"); });
if(preferences->getBool(preference_webserial_enabled, false)) if(preferences->getBool(preference_webserial_enabled, false))
{ {
//WebSerial.setAuthentication(preferences->getString(preference_cred_user), preferences->getString(preference_cred_password)); WebSerial.setAuthentication(preferences->getString(preference_cred_user), preferences->getString(preference_cred_password));
//WebSerial.begin(asyncServer); WebSerial.begin(asyncServer);
//WebSerial.setBuffer(1024); WebSerial.setBuffer(1024);
} }
#endif #endif
*/
psychicServer->listen(80);
} }
} }
#endif #endif