diff --git a/data/script.js b/data/script.js index 0b00a6e0..ba803b3c 100644 --- a/data/script.js +++ b/data/script.js @@ -1 +1,133 @@ -function aref(e){setTimeout(function(){ref("")},1e3*e)}function ref(e){var o=(new Date).getTime();return document.getElementById("bmp").src="?a="+e+"&q="+o,!1}function about(){document.getElementById("doc").innerHTML='

openHASP

Copyright© 2019-2021 Francis Van Roie
MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Based on the previous work of the following open source developers:

HASwitchPlate

Copyright© 2019 Allen Derusha allen @derusha.org
MIT License

LVGL

Copyright© 2021 LVGL Kft
MIT License

zi Font Engine

Copyright© 2020-2021 Francis Van Roie
MIT License

TFT_eSPI Library

Copyright© 2020 Bodmer (https://github.com/Bodmer) All rights reserved.
FreeBSD License

includes parts from the Adafruit_GFX library
Copyright© 2012 Adafruit Industries. All rights reserved
BSD License

ArduinoJson

Copyright© 2014-2021 Benoit BLANCHON
MIT License

PubSubClient

Copyright© 2008-2015 Nicholas O'Leary
MIT License

ArduinoLog

Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, dhylands, Josha blemasle, mfalkvidd
MIT License

QR Code generator

Copyright© Project Nayuki
MIT License

SimpleFTPServer

Copyright© 2017 Renzo Mischianti www.mischianti.org All right reserved.
MIT License

AceButton

Copyright© 2018 Brian T. Park
MIT License

'} \ No newline at end of file +function aref(e) { setTimeout(function() { ref("") }, 1e3 * e) } + +function ref(e) { var o = (new Date).getTime(); return document.getElementById("bmp").src = "?a=" + e + "&q=" + o, !1 } + +function about() { document.getElementById("doc").innerHTML = '

openHASP

Copyright© 2019-2021 Francis Van Roie
MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Based on the previous work of the following open source developers:

HASwitchPlate

Copyright© 2019 Allen Derusha allen @derusha.org
MIT License

LVGL

Copyright© 2021 LVGL Kft
MIT License

zi Font Engine

Copyright© 2020-2021 Francis Van Roie
MIT License

TFT_eSPI Library

Copyright© 2020 Bodmer (https://github.com/Bodmer) All rights reserved.
FreeBSD License

includes parts from the Adafruit_GFX library
Copyright© 2012 Adafruit Industries. All rights reserved
BSD License

ArduinoJson

Copyright© 2014-2021 Benoit BLANCHON
MIT License

PubSubClient

Copyright© 2008-2015 Nicholas O'Leary
MIT License

ArduinoLog

Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, dhylands, Josha blemasle, mfalkvidd
MIT License

QR Code generator

Copyright© Project Nayuki
MIT License

SimpleFTPServer

Copyright© 2017 Renzo Mischianti www.mischianti.org All right reserved.
MIT License

AceButton

Copyright© 2018 Brian T. Park
MIT License

' } + +function handleSubmit(event) { + event.preventDefault(); + const data = new FormData(event.target); + const value = Object.fromEntries(data.entries()); + console.log({ value }); +} + +function info() { + console.log(this.response); + data = JSON.parse(this.response); + console.log(data); + var table = ""; + for (let header in data) { table += ``; for (let key in data[header]) { table += ``; } } + table += "
${header}
${key}: ${data[header][key]}
"; + document.getElementById("info").innerHTML = table; +} + +function loader(method, uri, func) { + window.addEventListener("load", function() { + var rq = new XMLHttpRequest(); + rq.addEventListener("load", func); + rq.open(method, uri); + rq.send(); + }) +} + +function fill() { + data = JSON.parse(this.response); + form = document.forms.item(0); + populate(form, data); +} + +function filler(method, uri) { + window.addEventListener("load", function() { + var rq = new XMLHttpRequest(); + rq.addEventListener("load", fill); + rq.open(method, uri); + rq.send(); + }) +} + +function filler2(method, uri) { + var rq = new XMLHttpRequest(); + rq.addEventListener("load", fill); + rq.open(method, uri); + rq.send(); +} + +/** https://github.com/dannyvankooten/populate.js + * Populate form fields from a JSON object. + * + * @param form object The form element containing your input fields. + * @param data array JSON data to populate the fields with. + * @param basename string Optional basename which is added to `name` attributes + */ +function populate(form, data, basename) { + for (var key in data) { + if (!data.hasOwnProperty(key)) { + continue; + } + + var name = key; + var value = data[key]; + + if ('undefined' === typeof value) { + value = ''; + } + + if (null === value) { + value = ''; + } + + // handle array name attributes + if (typeof(basename) !== "undefined") { + name = basename + "[" + key + "]"; + } + + if (value.constructor === Array) { + name += '[]'; + } else if (typeof value == "object") { + populate(form, value, name); + continue; + } + + // only proceed if element is set + var element = form.elements.namedItem(name); + if (!element) { + continue; + } + + var type = element.type || element[0].type; + + switch (type) { + default: element.value = value; + break; + + case 'radio': + var values = value.constructor === Array ? value : [value]; + for (var j = 0; j < element.length; j++) { + element[j].checked = values.indexOf(Number(element[j].value)) > -1; + } + break; + + case 'checkbox': + var values = value.constructor === Array ? value : [value]; + element.checked = values.indexOf(Number(element.value)) > -1; + break; + + case 'select-multiple': + var values = value.constructor === Array ? value : [value]; + for (var k = 0; k < element.options.length; k++) { + element.options[k].selected = (values.indexOf(element.options[k].value) > -1); + } + break; + + case 'select': + case 'select-one': + element.value = value.toString() || value; + break; + + case 'date': + element.value = new Date(value).toISOString().split('T')[0]; + break; + } + + } +}; \ No newline at end of file diff --git a/data/script.js.gz b/data/script.js.gz index a093c05f..732b8f5c 100644 Binary files a/data/script.js.gz and b/data/script.js.gz differ diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h index c4f8fdab..f2341d4d 100644 --- a/include/lv_conf_v7.h +++ b/include/lv_conf_v7.h @@ -360,7 +360,7 @@ typedef void* lv_indev_drv_user_data_t; /*Type of user data in the in * FONT USAGE *===================*/ -#if TFT_WIDTH>=320 || TFT_WIDTH>=480 +#if TFT_HEIGHT>=480 || TFT_WIDTH>=480 #ifndef HASP_FONT_1 #define HASP_FONT_1 robotocondensed_regular_16_latin1 /* 5% Width */ diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index 61c03126..8e40b9ba 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -482,10 +482,10 @@ bool guiGetConfig(const JsonObject& settings) settings[FPSTR(FP_GUI_ROTATION)] = gui_settings.rotation; if(gui_settings.show_pointer != settings[FPSTR(FP_GUI_POINTER)].as()) changed = true; - settings[FPSTR(FP_GUI_POINTER)] = gui_settings.show_pointer; + settings[FPSTR(FP_GUI_POINTER)] = (uint8_t)gui_settings.show_pointer; if(gui_settings.invert_display != settings[FPSTR(FP_GUI_INVERT)].as()) changed = true; - settings[FPSTR(FP_GUI_INVERT)] = gui_settings.invert_display; + settings[FPSTR(FP_GUI_INVERT)] = (uint8_t)gui_settings.invert_display; /* Check CalData array has changed */ JsonArray array = settings[FPSTR(FP_GUI_CALIBRATION)].as(); @@ -545,8 +545,10 @@ bool guiSetConfig(const JsonObject& settings) changed |= configSet(gui_settings.backlight_pin, settings[FPSTR(FP_GUI_BACKLIGHTPIN)], F("guiBacklightPin")); changed |= configSet(guiSleepTime1, settings[FPSTR(FP_GUI_IDLEPERIOD1)], F("guiSleepTime1")); changed |= configSet(guiSleepTime2, settings[FPSTR(FP_GUI_IDLEPERIOD2)], F("guiSleepTime2")); - changed |= configSet(gui_settings.rotation, settings[FPSTR(FP_GUI_ROTATION)], F("gui_settings.rotation")); - changed |= configSet(gui_settings.invert_display, settings[FPSTR(FP_GUI_INVERT)], F("guiInvertDisplay")); + changed |= + configSet(gui_settings.rotation, settings[FPSTR(FP_GUI_ROTATION)], F("gui_settings.rotation")); + changed |= + configSet(gui_settings.invert_display, settings[FPSTR(FP_GUI_INVERT)], F("guiInvertDisplay")); hasp_set_sleep_time(guiSleepTime1, guiSleepTime2); diff --git a/src/log/hasp_debug.cpp b/src/log/hasp_debug.cpp index 8d7aca39..ba76afdd 100644 --- a/src/log/hasp_debug.cpp +++ b/src/log/hasp_debug.cpp @@ -139,8 +139,8 @@ bool debugGetConfig(const JsonObject& settings) { bool changed = false; - if(debugAnsiCodes != settings[FPSTR(FP_DEBUG_ANSI)].as()) changed = true; - settings[FPSTR(FP_DEBUG_ANSI)] = debugAnsiCodes; + if(debugAnsiCodes != settings[FPSTR(FP_DEBUG_ANSI)]) changed = true; + settings[FPSTR(FP_DEBUG_ANSI)] = (uint8_t)debugAnsiCodes; if(debugSerialBaud != settings[FPSTR(FP_CONFIG_BAUD)].as()) changed = true; settings[FPSTR(FP_CONFIG_BAUD)] = debugSerialBaud; diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 612afcc3..14038270 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -322,8 +322,8 @@ bool saveConfig() #endif } else if(save == String(PSTR("gui"))) { - settings[FPSTR(FP_GUI_POINTER)] = webServer.hasArg(PSTR("cur")); - settings[FPSTR(FP_GUI_INVERT)] = webServer.hasArg(PSTR("inv")); + settings[FPSTR(FP_GUI_POINTER)] = webServer.hasArg(PSTR("cursor")); + settings[FPSTR(FP_GUI_INVERT)] = webServer.hasArg(PSTR("invert")); updated = guiSetConfig(settings.as()); } else if(save == String(PSTR("debug"))) { @@ -461,7 +461,7 @@ static void webHandleScreenshot() //////////////////////////////////////////////////////////////////////////////////////////////////// static void add_json(String& data, JsonDocument& doc) { - char buffer[512]; + char buffer[800]; size_t len = serializeJson(doc, buffer, sizeof(buffer)); if(doc.isNull()) return; // empty document @@ -475,37 +475,77 @@ static void webHandleApi() { // http://plate01/about if(!httpIsAuthenticated(F("api"))) return; + DynamicJsonDocument doc(800); + String contentType = getContentType(F(".json")); String endpoint((char*)0); endpoint = webServer.pathArg(0); if(!strcasecmp_P(endpoint.c_str(), PSTR("info"))) { - String htmldata((char*)0); - htmldata.reserve(HTTP_PAGE_SIZE); - DynamicJsonDocument doc(512); - - htmldata = "{"; + String jsondata((char*)0); + jsondata.reserve(HTTP_PAGE_SIZE); + jsondata = "{"; hasp_get_info(doc); - add_json(htmldata, doc); + add_json(jsondata, doc); #if HASP_USE_MQTT > 0 mqtt_get_info(doc); - add_json(htmldata, doc); + add_json(jsondata, doc); #endif network_get_info(doc); - add_json(htmldata, doc); + add_json(jsondata, doc); haspDevice.get_info(doc); - add_json(htmldata, doc); + add_json(jsondata, doc); - htmldata[htmldata.length() - 1] = '}'; // Replace last comma with a bracket + jsondata[jsondata.length() - 1] = '}'; // Replace last comma with a bracket - String contentType = getContentType(F(".json")); - webServer.send(200, contentType, htmldata); + webServer.send(200, contentType, jsondata); + + } else { + webServer.send(400, contentType, "Bad Request"); } } +static void webHandleApiConfig() +{ // http://plate01/about + if(!httpIsAuthenticated(F("api"))) return; + + DynamicJsonDocument doc(800); + String contentType = getContentType(F(".json")); + String endpoint((char*)0); + endpoint = webServer.pathArg(0); + + JsonObject settings = doc.to(); // Settings are invalid, force creation of an empty JsonObject + + if(!strcasecmp_P(endpoint.c_str(), PSTR("wifi"))) { + wifiGetConfig(settings); + } else if(!strcasecmp_P(endpoint.c_str(), PSTR("mqtt"))) { + mqttGetConfig(settings); + } else if(!strcasecmp_P(endpoint.c_str(), PSTR("http"))) { + httpGetConfig(settings); + } else if(!strcasecmp_P(endpoint.c_str(), PSTR("gui"))) { + guiGetConfig(settings); + } else if(!strcasecmp_P(endpoint.c_str(), PSTR("debug"))) { + debugGetConfig(settings); + } else { + webServer.send(400, contentType, "Bad Request"); + return; + } + + if(!settings[FPSTR(FP_CONFIG_PASS)].isNull()) { + settings[FPSTR(FP_CONFIG_PASS)] = D_PASSWORD_MASK; + } + + doc.shrinkToFit(); + const size_t size = measureJson(doc) + 1; + char jsondata[size]; + memset(jsondata, 0, size); + serializeJson(doc, jsondata, size); + webServer.send(200, contentType, jsondata); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// static void webHandleAbout() { // http://plate01/about @@ -518,39 +558,6 @@ static void webHandleAbout() String httpMessage((char*)0); httpMessage.reserve(HTTP_PAGE_SIZE); - /* - httpMessage += F("

openHASP

Copyright© 2019-2022 Francis Van Roie "); - httpMessage += mitLicense; - httpMessage += F("

Based on the previous work of the following open source developers.


"); - httpMessage += F("

HASwitchPlate

Copyright© 2019 Allen Derusha allen@derusha.org"); - httpMessage += mitLicense; - httpMessage += F("

LVGL

Copyright© 2021 LVGL Kft"); - httpMessage += mitLicense; - httpMessage += F("

TFT_eSPI Library

Copyright© 2020 Bodmer (https://github.com/Bodmer) - All " "rights reserved.
FreeBSD License

"); httpMessage += F("

includes parts from the - Adafruit_GFX library
Copyright© 2012 Adafruit Industries. " "All rights reserved
BSD - License

"); httpMessage += F("

ArduinoJson

Copyright© 2014-2021 Benoit BLANCHON"); - httpMessage += mitLicense; - httpMessage += F("

PubSubClient

Copyright© 2008-2015 Nicholas O'Leary"); - httpMessage += mitLicense; - httpMessage += F("

FreeType

Copyright© 1996-2002, 2006 David Turner, Robert Wilhelm, " - "and Werner Lemberg.
FreeType License

"); - httpMessage += - F("

ArduinoLog

Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, " - "dhylands, Josha blemasle, mfalkvidd"); - httpMessage += mitLicense; - #if HASP_USE_SYSLOG > 0 - // Replaced with WiFiUDP client - // httpMessage += F("

Syslog

Copyright© 2016 Martin Sloup"); - // httpMessage += mitLicense; - #endif - #if HASP_USE_QRCODE > 0 - httpMessage += F("

QR Code generator

Copyright© Project Nayuki"); - httpMessage += mitLicense; - #endif - httpMessage += F("

AceButton

Copyright© 2018 Brian T. Park"); - httpMessage += mitLicense; - */ httpMessage += "
"; httpMessage += FPSTR(MAIN_MENU_BUTTON); @@ -574,32 +581,7 @@ static void webHandleInfoJson() htmldata += haspDevice.get_hostname(); htmldata += F("
"); - htmldata += "
"; - + htmldata += "
"; htmldata += FPSTR(MAIN_MENU_BUTTON); webSendHeader(haspDevice.get_hostname(), htmldata.length(), false); @@ -844,8 +826,13 @@ static void handleFileUpload() } if(filename.length() < 32) { fsUploadFile = HASP_FS.open(filename, "w"); - LOG_TRACE(TAG_HTTP, F("handleFileUpload Name: %s"), filename.c_str()); - haspProgressMsg(fsUploadFile.name()); + if(!fsUploadFile || fsUploadFile.isDirectory()) { + LOG_WARNING(TAG_HTTP, F(D_FILE_SAVE_FAILED), filename.c_str()); + fsUploadFile.close(); + } else { + LOG_TRACE(TAG_HTTP, F("handleFileUpload Name: %s"), filename.c_str()); + haspProgressMsg(fsUploadFile.name()); + } } else { LOG_ERROR(TAG_HTTP, F("Filename %s is too long"), filename.c_str()); } @@ -862,12 +849,15 @@ static void handleFileUpload() if(fsUploadFile) { LOG_INFO(TAG_HTTP, F("Uploaded %s (%u bytes)"), fsUploadFile.name(), upload->totalSize); fsUploadFile.close(); + + // Redirect to /config/hasp page. This flushes the web buffer and frees the memory + webServer.sendHeader(String(F("Location")), String(F("/config/hasp")), true); + webServer.send_P(302, PSTR("text/plain"), ""); + } else { + webServer.send_P(400, PSTR("text/plain"), "Bad Request"); } haspProgressVal(255); - // Redirect to /config/hasp page. This flushes the web buffer and frees the memory - webServer.sendHeader(String(F("Location")), String(F("/config/hasp")), true); - webServer.send_P(302, PSTR("text/plain"), ""); // httpReconnect(); } } @@ -1079,7 +1069,7 @@ static void webHandleMqttConfig() httpMessage += F("
"); // Group Name @@ -1087,7 +1077,7 @@ static void webHandleMqttConfig() httpMessage += F("
"); // Broker @@ -1095,14 +1085,14 @@ static void webHandleMqttConfig() httpMessage += F("
"); // Mqtt Port httpMessage += F("
"); httpMessage += F("
"); // Mqtt User @@ -1110,7 +1100,7 @@ static void webHandleMqttConfig() httpMessage += F("
"); // Mqtt Password @@ -1118,7 +1108,7 @@ static void webHandleMqttConfig() httpMessage += F("
"); // Submit & End Form @@ -1126,6 +1116,8 @@ static void webHandleMqttConfig() httpMessage += F(""); add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config")); + httpMessage += ""; + webSendHeader(haspDevice.get_hostname(), httpMessage.length(), false); webServer.sendContent(httpMessage); } @@ -1156,18 +1148,18 @@ static void webHandleGuiConfig() httpMessage += F("
"); httpMessage += F("
"); // Long Idle httpMessage += F("
"); httpMessage += F("
"); // Rotation - int8_t rotation = settings[FPSTR(FP_GUI_ROTATION)].as(); + int8_t rotation = -1; // settings[FPSTR(FP_GUI_ROTATION)].as(); httpMessage += F("
"); httpMessage += F("
"); // Invert - httpMessage += F("
"); - httpMessage += F("
()) httpMessage += F(" checked"); + httpMessage += F("
"); + httpMessage += F("
()) httpMessage += F(" checked"); httpMessage += F(">Invert Colors
"); // Cursor - httpMessage += F("
"); - httpMessage += F("
()) httpMessage += F(" checked"); + httpMessage += F("
"); + httpMessage += F("
()) httpMessage += F(" checked"); httpMessage += F(">Show Pointer
"); // Backlight @@ -1224,6 +1216,8 @@ static void webHandleGuiConfig() add_form_button(httpMessage, F(D_HTTP_ANTIBURN), F("/config/gui?brn=1")); add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config")); + httpMessage += F(""); + webSendHeader(haspDevice.get_hostname(), httpMessage.length(), false); webServer.sendContent(httpMessage); } @@ -1260,7 +1254,7 @@ static void webHandleWifiConfig() httpMessage += F("
"); // Wifi Password @@ -1268,9 +1262,9 @@ static void webHandleWifiConfig() httpMessage += F("
"); // Submit & End Form @@ -1283,6 +1277,8 @@ static void webHandleWifiConfig() } #endif + httpMessage += F(""); + webSendHeader(haspDevice.get_hostname(), httpMessage.length(), false); webServer.sendContent(httpMessage); } @@ -1369,16 +1365,16 @@ static void webHandleHttpConfig() httpMessage += F("
"); httpMessage += F("
"); // Password httpMessage += F("
"); httpMessage += F("
"); // Submit & End Form @@ -1386,6 +1382,7 @@ static void webHandleHttpConfig() httpMessage += F("
"); httpMessage += F("" D_HTTP_CONFIGURATION ""); + httpMessage += F(""); webSendHeader(haspDevice.get_hostname(), httpMessage.length(), false); webServer.sendContent(httpMessage); @@ -1791,13 +1788,13 @@ static void webHandleDebugConfig() httpMessage += F("
"); httpMessage += F("
"); // Invert httpMessage += F("
"); - httpMessage += F("
()) httpMessage += F(" checked"); + httpMessage += F("
()) httpMessage += F(" checked"); httpMessage += F(">Use ANSI Colors
"); #if HASP_USE_SYSLOG > 0 @@ -1806,14 +1803,14 @@ static void webHandleDebugConfig() httpMessage += F("
"); // Syslog Port httpMessage += F("
"); httpMessage += F("
"); // Syslog Facility @@ -1829,9 +1826,9 @@ static void webHandleDebugConfig() uint8_t proto = settings[FPSTR(FP_CONFIG_PROTOCOL)].as(); httpMessage += F("
"); httpMessage += F("
IETF (RFC 5424)   BSD (RFC 3164)"); httpMessage += F("
"); #endif @@ -1843,6 +1840,7 @@ static void webHandleDebugConfig() // ******************************************************************* add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config")); + httpMessage += F(""); webSendHeader(haspDevice.get_hostname(), httpMessage.length(), false); webServer.sendContent(httpMessage); @@ -2301,7 +2299,8 @@ void httpSetup() webServer.on(F("/vars.css"), webSendCssVars); // webServer.on(F("/js"), webSendJavascript); webServer.onNotFound(httpHandleNotFound); - webServer.on(UriBraces(F("/api/{}")), webHandleApi); + webServer.on(UriBraces(F("/api/{}/")), webHandleApi); + webServer.on(UriBraces(F("/api/config/{}/")), webHandleApiConfig); #if HASP_USE_WIFI > 0 // These two endpoints are needed in STA and AP mode @@ -2474,16 +2473,17 @@ size_t httpClientWrite(const uint8_t* buf, size_t size) size_t bytes_sent = 0; while(bytes_sent < size) { if(!webServer.client()) return bytes_sent; - if(size - bytes_sent >= 2048) { - bytes_sent += webServer.client().write(buf + bytes_sent, 2048); + if(size - bytes_sent >= 20480) { + bytes_sent += webServer.client().write(buf + bytes_sent, 20480); // 2048 + delay(1); // Fixes the freeze } else { bytes_sent += webServer.client().write(buf + bytes_sent, size - bytes_sent); + return bytes_sent; } // Serial.println(bytes_sent); // stm32_eth_scheduler(); // already in write // webServer.client().flush(); - delay(1); // Fixes the freeze } return bytes_sent; }