From da8025f886a69580ca54ef551a8b1aeae470e583 Mon Sep 17 00:00:00 2001 From: Pablo2048 Date: Sat, 27 Feb 2021 18:58:53 +0100 Subject: [PATCH] Aktualizace na posledni lorol verzi --- .../ESP_AsyncFSBrowser/data/.exclude.files | 3 +- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 117524 -> 118766 bytes examples/ESP_AsyncFSBrowser/data/edit_gz | Bin 0 -> 4503 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 32927 -> 32927 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes .../ESP_AsyncFSBrowser/data/worker-json.js.gz | Bin 0 -> 6923 bytes examples/SmartSwitch/SmartSwitch.ino | 114 +- examples/SmartSwitch/data/.exclude.files | 1 + examples/SmartSwitch/data/acefull.js.gz | Bin 117524 -> 118766 bytes examples/SmartSwitch/data/edit_gz | Bin 0 -> 4503 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 32927 -> 32927 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes examples/SmartSwitch/data/worker-json.js.gz | Bin 0 -> 6923 bytes extras/README.md | 5 +- extras/do_ed_fs.bat | 9 + extras/{do.bat => do_emb.bat} | 14 +- extras/update_ace.bat | 7 +- src/AsyncWebSocket.cpp | 138 +- src/AsyncWebSocket.h | 38 +- src/ESPAsyncWebServer.h | 26 +- src/SPIFFSEditor.cpp | 83 +- src/WebHandlerImpl.h | 13 + src/WebRequest.cpp | 46 +- src/edit.htm | 1138 ++++++++--------- src/edit.htm.gz.h | 2 +- 27 files changed, 879 insertions(+), 758 deletions(-) create mode 100644 examples/ESP_AsyncFSBrowser/data/edit_gz create mode 100644 examples/ESP_AsyncFSBrowser/data/worker-json.js.gz create mode 100644 examples/SmartSwitch/data/edit_gz create mode 100644 examples/SmartSwitch/data/worker-json.js.gz create mode 100644 extras/do_ed_fs.bat rename extras/{do.bat => do_emb.bat} (82%) diff --git a/examples/ESP_AsyncFSBrowser/data/.exclude.files b/examples/ESP_AsyncFSBrowser/data/.exclude.files index 955397f..a1c4278 100644 --- a/examples/ESP_AsyncFSBrowser/data/.exclude.files +++ b/examples/ESP_AsyncFSBrowser/data/.exclude.files @@ -1,2 +1,3 @@ -/*.js.gz +/*.gz +/edit_gz /.exclude.files diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 7e65c5f6d5ed9e3466cf5bb3a200e22d3db94a29..54069806c524a3c84eb31eedc650c3efa1686331 100644 GIT binary patch delta 6382 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 delta 5130 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 diff --git a/examples/ESP_AsyncFSBrowser/data/edit_gz b/examples/ESP_AsyncFSBrowser/data/edit_gz new file mode 100644 index 0000000000000000000000000000000000000000..be687a3942deeecdc96ea3fc3a2302c7b73408b7 GIT binary patch literal 4503 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 literal 0 HcmV?d00001 diff --git a/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz index 23cfa33a5a3c13868e41875c80ce8fc5ea3ae8d0..6bab483026a8fb0ef25353f10db64a75d38d99b3 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gTv$5x{d5J8UQ;~2C@JE delta 18 ZcmbQ=$TYu^iCw;%gJby#rH$+}8UQ+d24?^O diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index 69a5f29ca6063e498b83bf508c974fccdaaaeb02..b256b50c0d2da0779833d602f8ee30a686eac6eb 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54i5Kc>o&4qSq}hD5(rQL delta 18 acmcb8pXv5}CU*I54vys~ls2+oSq}hCLI?%` diff --git a/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz index 9523daf4b0d7d24e64d4724c04d17d218d7ae976..9cbfd2049f4dc579c777e291376a775707d0a573 100644 GIT binary patch delta 21 dcmZ4Yo^9QGHg@@L4i3*}>l)d&vNJB<4gg`42#5dx delta 21 dcmZ4Yo^9QGHg@@L4vv*4lp5K$vNJB<4gg=~2tEJ+ diff --git a/examples/ESP_AsyncFSBrowser/data/worker-json.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-json.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..fec1f65b323b3e5e21bf3b6a4945fe7623628312 GIT binary patch literal 6923 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 MEMMAX) memch = 0; EEPROM.get(EEBEGIN + memch*sizeof(ee), ChkEE); @@ -199,6 +200,20 @@ void readEE() { } } +void doOut(){ + if (ledOut != ledState){ // only if changed + digitalWrite(ledPin, ledState); //consolidated here + ledOut = ledState; //update + if (ledState == LED_OFF){ + ws.textAll("led,ledoff"); + Serial.println(F("LED-OFF")); + } else { + ws.textAll("led,ledon"); + Serial.println(F("LED-ON")); + } + } +} + void showTime() { byte tmpch = 0; @@ -208,13 +223,13 @@ void showTime() now = time(nullptr); const tm* tm = localtime(&now); ws.printfAll("Now,Clock,%02d:%02d,%d", tm->tm_hour, tm->tm_min, tm->tm_wday); - if ((2==tm->tm_hour )&&(2==tm->tm_min)) { + if ((2==tm->tm_hour )&&(2==tm->tm_min)){ configTzTime(MYTZ, "pool.ntp.org"); Serial.print(F("Sync Clock at 02:02\n")); } Serial.printf("RTC: %02d:%02d\n", tm->tm_hour, tm->tm_min); - if (sched == 0) { // automatic + if (sched == 0){ // automatic if ((tm->tm_wday > 0)&&(tm->tm_wday < 6)) tmpch = 0; //Mon - Fri else if (tm->tm_wday == 6) tmpch = 1; //Sat else if (tm->tm_wday == 0) tmpch = 2; //Sun @@ -222,7 +237,7 @@ void showTime() tmpch = sched - 1; //and stays } - if (tmpch != memch) { // update if different + if (tmpch != memch){ // update if different memch = tmpch; readEE(); ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); @@ -237,20 +252,18 @@ void showTime() else { //enable smart if different if (((bmi < emi)&&(bmi <= xmi)&&(xmi < emi))|| - ((emi < bmi)&&((bmi <= xmi)||(xmi < emi)))) { + ((emi < bmi)&&((bmi <= xmi)||(xmi < emi)))){ heat_enabled = true; } else heat_enabled = false; } - if (heat_enabled_prev) { // smart control (delayed one cycle) - if (((t - HYST) < ee.tempe)&&(ledState == LED_OFF)) { // OFF->ON once + if (heat_enabled_prev){ // smart control (delayed one cycle) + if (((t + HYST) < ee.tempe)&&(ledState == LED_OFF)){ // OFF->ON once ledState = LED_ON; - digitalWrite(ledPin, ledState); // apply change ws.textAll("led,ledon"); } - if ((((t + HYST) > ee.tempe)&&(ledState == LED_ON))||(!heat_enabled)) { // ON->OFF once, also turn off at end of period. + if ((((t - HYST) > ee.tempe)&&(ledState == LED_ON))||(!heat_enabled)){ // ->OFF ledState = LED_OFF; - digitalWrite(ledPin, ledState); // apply change ws.textAll("led,ledoff"); } @@ -263,7 +276,7 @@ void showTime() void updateDHT(){ float h1 = dht.readHumidity(); float t1 = dht.readTemperature(); //Celsius or dht.readTemperature(true) for Fahrenheit - if (isnan(h1) || isnan(t1)) { + if (isnan(h1) || isnan(t1)){ Serial.println(F("Failed to read from DHT sensor!")); } else { h = h1 + DHT_H_CORR; @@ -279,17 +292,9 @@ void analogSample() void checkPhysicalButton() { - if (digitalRead(btnPin) == LOW) { - if (btnState != LOW) { // btnState is used to avoid sequential toggles + if (digitalRead(btnPin) == LOW){ + if (btnState != LOW){ // btnState is used to avoid sequential toggles ledState = !ledState; - digitalWrite(ledPin, ledState); - if (ledState == LED_OFF) { - ws.textAll("led,ledoff"); - Serial.println(F("LED-OFF")); - } else { - ws.textAll("led,ledon"); - Serial.println(F("LED-ON")); - } } btnState = LOW; } else { @@ -297,17 +302,17 @@ void checkPhysicalButton() } } -void mytimer() { +void mytimer(){ ++count; //200ms increments checkPhysicalButton(); - if ((count % 25) == 1) { // update temp every 5 seconds + if ((count % 25) == 1){ // update temp every 5 seconds analogSample(); udht = true; } - if ((count % 50) == 0) { // update temp every 10 seconds + if ((count % 50) == 0){ // update temp every 10 seconds ws.cleanupClients(); } - if (count >= 150) { // cycle every 30 sec + if (count >= 150){ // cycle every 30 sec showTime(); count = 0; } @@ -385,22 +390,21 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); if(info->opcode == WS_TEXT){ - for(size_t i=0; i < info->len; i++) { //debug + for(size_t i=0; i < info->len; i++){ //debug msg += (char) data[i]; } - if(data[0] == 'L') { // LED - if(data[1] == '1') { + if(data[0] == 'L'){ // LED + if(data[1] == '1'){ ledState = LED_ON; ws.textAll("led,ledon"); // for others } - else if(data[1] == '0') { + else if(data[1] == '0'){ ledState = LED_OFF; ws.textAll("led,ledoff"); } - digitalWrite(ledPin, ledState); // apply change - } else if(data[0] == 'T') { // timeset - if (len > 11) { + } else if(data[0] == 'T'){ // timeset + if (len > 11){ data[3] = data[6] = data[9] = data[12] = 0; // cut strings ee.hstart = (uint8_t) atoi((const char *) &data[1]); ee.mstart = (uint8_t) atoi((const char *) &data[4]); @@ -411,8 +415,8 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT memch = 255; // to force showTime()to send Setting showTime(); } - } else if(data[0] == 'W') { // temperatureset - if (len > 3) { + } else if(data[0] == 'W'){ // temperatureset + if (len > 3){ if (ee.tempe != (float) atof((const char *) &data[1])){ ee.tempe = (float) atof((const char *) &data[1]); Serial.printf("[%u] Temp set %+2.1f\n", client->id(), ee.tempe); @@ -421,7 +425,7 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT showTime(); } } - } else if ((data[0] == 'Z')&&(len > 2)) { // sched + } else if ((data[0] == 'Z')&&(len > 2)){ // sched data[2] = 0; if (sched != (uint8_t) atoi((const char *) &data[1])){ sched = (uint8_t) atoi((const char *) &data[1]); @@ -434,7 +438,7 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT } else { char buff[3]; - for(size_t i=0; i < info->len; i++) { + for(size_t i=0; i < info->len; i++){ sprintf(buff, "%02x ", (uint8_t) data[i]); msg += buff ; } @@ -457,12 +461,12 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT Serial.printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT)?"text":"binary", info->index, info->index + len); if(info->opcode == WS_TEXT){ - for(size_t i=0; i < len; i++) { + for(size_t i=0; i < len; i++){ msg += (char) data[i]; } } else { char buff[3]; - for(size_t i=0; i < len; i++) { + for(size_t i=0; i < len; i++){ sprintf(buff, "%02x ", (uint8_t) data[i]); msg += buff ; } @@ -488,7 +492,7 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT void setup(){ Serial.begin(115200); - Serial.setDebugOutput(true); + //Serial.setDebugOutput(true); //Wifi #ifdef USE_WFM @@ -511,7 +515,7 @@ void setup(){ //WiFi.softAP(hostName); // Core SVN 5179 use STA as default interface in mDNS (#7042) WiFi.mode(WIFI_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { + if (WiFi.waitForConnectResult() != WL_CONNECTED){ Serial.print(F("STA: Failed!\n")); WiFi.disconnect(false); delay(1000); @@ -545,15 +549,14 @@ void setup(){ EEPROM.begin(EEALL); //EEPROM.get(EECH, memch); //current channel, no need readEE(); // populate structure if healthy - digitalWrite(ledPin, ledState); Serial.printf("Timer set %02d:%02d - %02d:%02d\n", ee.hstart, ee.mstart, ee.hstop, ee.mstop); Serial.printf("Temp set %+2.1f\n", ee.tempe); //FS #ifdef USE_FatFS - if (MYFS.begin(false,"/ffat",3)) { //limit the RAM usage, bottom line 8kb + 4kb takes per each file, default is 10 + if (MYFS.begin(false,"/ffat",3)){ //limit the RAM usage, bottom line 8kb + 4kb takes per each file, default is 10 #else - if (MYFS.begin()) { + if (MYFS.begin()){ #endif Serial.print(F("FS mounted\n")); } else { @@ -654,7 +657,7 @@ void setup(){ #ifdef USE_AUTH_STAT if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); #endif - request->onDisconnect([]() { + request->onDisconnect([](){ #ifdef ESP32 ESP.restart(); #elif defined(ESP8266) @@ -672,11 +675,23 @@ void setup(){ #ifdef USE_AUTH_STAT if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); #endif - request->onDisconnect([]() { - WiFi.disconnect(true); + request->onDisconnect([](){ #ifdef ESP32 +/* + //https://github.com/espressif/arduino-esp32/issues/400#issuecomment-499631249 + //WiFi.disconnect(true); // doesn't work on esp32, below needs #include "esp_wifi.h" + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //load the flash-saved configs + esp_wifi_init(&cfg); //initiate and allocate wifi resources (does not matter if connection fails) + if(esp_wifi_restore()!=ESP_OK){ + Serial.print(F("WiFi is not initialized by esp_wifi_init ")); + } else { + Serial.print(F("WiFi Configurations Cleared!")); + } +*/ + WiFi.disconnect(true, true); // Works on esp32 ESP.restart(); #elif defined(ESP8266) + WiFi.disconnect(true); ESP.reset(); #endif }); @@ -714,7 +729,7 @@ void setup(){ //OTA ArduinoOTA.setHostname(hostName); - ArduinoOTA.onStart([]() { + ArduinoOTA.onStart([](){ Serial.print(F("OTA Started ...\n")); MYFS.end(); // Clean FS ws.textAll("Now,OTA"); // for all clients @@ -730,5 +745,6 @@ void loop(){ updateDHT(); udht = false; } + doOut(); ArduinoOTA.handle(); } diff --git a/examples/SmartSwitch/data/.exclude.files b/examples/SmartSwitch/data/.exclude.files index 4aacf0d..a1c4278 100644 --- a/examples/SmartSwitch/data/.exclude.files +++ b/examples/SmartSwitch/data/.exclude.files @@ -1,2 +1,3 @@ /*.gz +/edit_gz /.exclude.files diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 7e65c5f6d5ed9e3466cf5bb3a200e22d3db94a29..54069806c524a3c84eb31eedc650c3efa1686331 100644 GIT binary patch delta 6382 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 delta 5130 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 diff --git a/examples/SmartSwitch/data/edit_gz b/examples/SmartSwitch/data/edit_gz new file mode 100644 index 0000000000000000000000000000000000000000..be687a3942deeecdc96ea3fc3a2302c7b73408b7 GIT binary patch literal 4503 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 literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index 23cfa33a5a3c13868e41875c80ce8fc5ea3ae8d0..6bab483026a8fb0ef25353f10db64a75d38d99b3 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gTv$5x{d5J8UQ;~2C@JE delta 18 ZcmbQ=$TYu^iCw;%gJby#rH$+}8UQ+d24?^O diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz index 69a5f29ca6063e498b83bf508c974fccdaaaeb02..b256b50c0d2da0779833d602f8ee30a686eac6eb 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54i5Kc>o&4qSq}hD5(rQL delta 18 acmcb8pXv5}CU*I54vys~ls2+oSq}hCLI?%` diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/worker-javascript.js.gz index 9523daf4b0d7d24e64d4724c04d17d218d7ae976..9cbfd2049f4dc579c777e291376a775707d0a573 100644 GIT binary patch delta 21 dcmZ4Yo^9QGHg@@L4i3*}>l)d&vNJB<4gg`42#5dx delta 21 dcmZ4Yo^9QGHg@@L4vv*4lp5K$vNJB<4gg=~2tEJ+ diff --git a/examples/SmartSwitch/data/worker-json.js.gz b/examples/SmartSwitch/data/worker-json.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..fec1f65b323b3e5e21bf3b6a4945fe7623628312 GIT binary patch literal 6923 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 acefull.js +type ace.js mode-html.js mode-json.js theme-monokai.js ext-searchbox.js > acefull.js "C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 acefull.js.gz acefull.js "C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-html.js.gz worker-html.js "C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-javascript.js.gz worker-javascript.js +"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-json.js.gz worker-json.js "C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-css.js.gz worker-css.js REM update SmartSwitch /data: @@ -25,6 +28,7 @@ pause copy acefull.js.gz ..\..\examples\SmartSwitch\data\acefull.js.gz copy worker-html.js.gz ..\..\examples\SmartSwitch\data\worker-html.js.gz copy worker-javascript.js.gz ..\..\examples\SmartSwitch\data\worker-javascript.js.gz +copy worker-json.js.gz ..\..\examples\SmartSwitch\data\worker-json.js.gz copy worker-css.js.gz ..\..\examples\SmartSwitch\data\worker-css.js.gz REM update ESP_AsyncFSBrowser /data: @@ -32,6 +36,7 @@ pause copy acefull.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\acefull.js.gz copy worker-html.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-html.js.gz copy worker-javascript.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-javascript.js.gz +copy worker-json.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-json.js.gz copy worker-css.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-css.js.gz REM delete temporary stuff diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 9ce9385..9ebab12 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -52,11 +52,15 @@ size_t webSocketSendFrameWindow(AsyncClient *client){ } size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool mask, uint8_t *data, size_t len){ - if(!client->canSend()) + if(!client->canSend()) { + // Serial.println("SF 1"); return 0; + } size_t space = client->space(); - if(space < 2) + if(space < 2) { + // Serial.println("SF 2"); return 0; + } uint8_t mbuf[4] = {0,0,0,0}; uint8_t headLen = 2; if(len && mask){ @@ -68,8 +72,10 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool } if(len > 125) headLen += 2; - if(space < headLen) + if(space < headLen) { + // Serial.println("SF 2"); return 0; + } space -= headLen; if(len > space) len = space; @@ -77,6 +83,7 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool uint8_t *buf = (uint8_t*)malloc(headLen); if(buf == NULL){ //os_printf("could not malloc %u bytes for frame header\n", headLen); + // Serial.println("SF 3"); return 0; } @@ -97,6 +104,7 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool if(client->add((const char *)buf, headLen) != headLen){ //os_printf("error adding %lu header bytes\n", headLen); free(buf); + // Serial.println("SF 4"); return 0; } free(buf); @@ -109,13 +117,16 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool } if(client->add((const char *)data, len) != len){ //os_printf("error adding %lu data bytes\n", len); + // Serial.println("SF 5"); return 0; } } if(!client->send()){ //os_printf("error sending frame: %lu\n", headLen+len); + // Serial.println("SF 6"); return 0; } + // Serial.println("SF"); return len; } @@ -149,6 +160,7 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t * data, size_t _data = new uint8_t[_len + 1]; if (_data) { + // Serial.println("BUFF alloc"); memcpy(_data, data, _len); _data[_len] = 0; } @@ -164,6 +176,7 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size) _data = new uint8_t[_len + 1]; if (_data) { + // Serial.println("BUFF alloc"); _data[_len] = 0; } @@ -185,6 +198,7 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(const AsyncWebSocketMes } if (_data) { + // Serial.println("BUFF alloc"); memcpy(_data, copy._data, _len); _data[_len] = 0; } @@ -202,6 +216,7 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBu _count = 0; if (copy._data) { + // Serial.println("BUFF alloc"); _data = copy._data; copy._data = nullptr; } @@ -211,6 +226,7 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBu AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer() { if (_data) { + // Serial.println("BUFF free"); delete[] _data; } } @@ -293,6 +309,7 @@ AsyncWebSocketBasicMessage::AsyncWebSocketBasicMessage(const char * data, size_t _opcode = opcode & 0x07; _mask = mask; _data = (uint8_t*)malloc(_len+1); + // Serial.println("MSG alloc"); if(_data == NULL){ _len = 0; _status = WS_MSG_ERROR; @@ -316,35 +333,43 @@ AsyncWebSocketBasicMessage::AsyncWebSocketBasicMessage(uint8_t opcode, bool mask AsyncWebSocketBasicMessage::~AsyncWebSocketBasicMessage() { - if(_data != NULL) + if(_data != NULL) { + // Serial.println("MSG free"); free(_data); + } } void AsyncWebSocketBasicMessage::ack(size_t len, uint32_t time) { (void)time; _acked += len; + // Serial.printf("ACK %u = %u | %u = %u\n", _sent, _len, _acked, _ack); if(_sent == _len && _acked == _ack){ + // Serial.println("ACK end"); _status = WS_MSG_SENT; } } size_t AsyncWebSocketBasicMessage::send(AsyncClient *client) { - if(_status != WS_MSG_SENDING) + if(_status != WS_MSG_SENDING){ + // Serial.println("MS 1"); return 0; + } if(_acked < _ack){ + // Serial.println("MS 2"); return 0; } if(_sent == _len){ - if(_acked == _ack) - _status = WS_MSG_SENT; + // Serial.println("MS 3"); + _status = WS_MSG_SENT; return 0; } if(_sent > _len){ + // Serial.println("MS 4"); _status = WS_MSG_ERROR; return 0; } - size_t toSend = _len - _sent; size_t window = webSocketSendFrameWindow(client); + // Serial.printf("Send %u %u %u\n", _len, _sent, toSend); if(window < toSend) { toSend = window; @@ -360,8 +385,14 @@ AsyncWebSocketBasicMessage::~AsyncWebSocketBasicMessage() { size_t sent = webSocketSendFrame(client, final, opCode, _mask, dPtr, toSend); _status = WS_MSG_SENDING; if(toSend && sent != toSend){ - _sent -= (toSend - sent); - _ack -= (toSend - sent); + size_t delta = (toSend - sent); + // Serial.printf("\ns:%u a:%u d:%u\n", _sent, _ack, delta); + _sent -= delta; + _ack -= delta + ((delta < 126)?2:4) + (_mask * 4); + // Serial.printf("s:%u a:%u\n", _sent, _ack); + if (!sent) { + _status = WS_MSG_ERROR; + } } return sent; } @@ -399,11 +430,13 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff if (buffer) { _WSbuffer = buffer; (*_WSbuffer)++; + // Serial.printf("INC WSbuffer == %u\n", _WSbuffer->count()); _data = buffer->get(); _len = buffer->length(); _status = WS_MSG_SENDING; //ets_printf("M: %u\n", _len); } else { + // Serial.println("BUFF ERROR"); _status = WS_MSG_ERROR; } @@ -413,40 +446,48 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() { if (_WSbuffer) { (*_WSbuffer)--; // decreases the counter. + // Serial.printf("DEC WSbuffer == %u\n", _WSbuffer->count()); } } void AsyncWebSocketMultiMessage::ack(size_t len, uint32_t time) { (void)time; _acked += len; + // Serial.printf("ACK %u = %u | %u = %u\n", _sent, _len, _acked, _ack); if(_sent >= _len && _acked >= _ack){ + // Serial.println("ACK end"); _status = WS_MSG_SENT; } //ets_printf("A: %u\n", len); } size_t AsyncWebSocketMultiMessage::send(AsyncClient *client) { - if(_status != WS_MSG_SENDING) + if(_status != WS_MSG_SENDING) { + // Serial.println("MS 1"); return 0; + } if(_acked < _ack){ + // Serial.println("MS 2"); return 0; } if(_sent == _len){ + // Serial.println("MS 3"); _status = WS_MSG_SENT; return 0; } if(_sent > _len){ + // Serial.println("MS 4"); _status = WS_MSG_ERROR; //ets_printf("E: %u > %u\n", _sent, _len); return 0; } - size_t toSend = _len - _sent; size_t window = webSocketSendFrameWindow(client); + // Serial.printf("Send %u %u %u\n", _len, _sent, toSend); if(window < toSend) { toSend = window; } - + // Serial.printf("s:%u a:%u t:%u\n", _sent, _ack, toSend); _sent += toSend; _ack += toSend + ((toSend < 126)?2:4) + (_mask * 4); @@ -460,8 +501,14 @@ AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() { _status = WS_MSG_SENDING; if(toSend && sent != toSend){ //ets_printf("E: %u != %u\n", toSend, sent); - _sent -= (toSend - sent); - _ack -= (toSend - sent); + size_t delta = (toSend - sent); + // Serial.printf("\ns:%u a:%u d:%u\n", _sent, _ack, delta); + _sent -= delta; + _ack -= delta + ((delta < 126)?2:4) + (_mask * 4); + // Serial.printf("s:%u a:%u\n", _sent, _ack); + if (!sent) { + _status = WS_MSG_ERROR; + } } //ets_printf("S: %u %u\n", _sent, sent); return sent; @@ -496,16 +543,25 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async _server->_addClient(this); _server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0); delete request; - memset(&_pinfo,0,sizeof(_pinfo)); // + memset(&_pinfo,0,sizeof(_pinfo)); } AsyncWebSocketClient::~AsyncWebSocketClient(){ + // Serial.printf("%u FREE Q\n", id()); _messageQueue.free(); _controlQueue.free(); + _server->_cleanBuffers(); _server->_handleEvent(this, WS_EVT_DISCONNECT, NULL, NULL, 0); } +void AsyncWebSocketClient::_clearQueue(){ + while(!_messageQueue.isEmpty() && _messageQueue.front()->finished()){ + _messageQueue.remove(_messageQueue.front()); + } +} + void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ + // Serial.printf("%u onAck\n", id()); _lastMessageTime = millis(); if(!_controlQueue.isEmpty()){ auto head = _controlQueue.front(); @@ -520,15 +576,21 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ _controlQueue.remove(head); } } + if(len && !_messageQueue.isEmpty()){ _messageQueue.front()->ack(len, time); } + + _clearQueue(); + _server->_cleanBuffers(); + // Serial.println("RUN 1"); _runQueue(); } void AsyncWebSocketClient::_onPoll(){ if(_client->canSend() && (!_controlQueue.isEmpty() || !_messageQueue.isEmpty())){ + // Serial.println("RUN 2"); _runQueue(); } else if(_keepAlivePeriod > 0 && _controlQueue.isEmpty() && _messageQueue.isEmpty() && (millis() - _lastMessageTime) >= _keepAlivePeriod){ ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); @@ -536,15 +598,20 @@ void AsyncWebSocketClient::_onPoll(){ } void AsyncWebSocketClient::_runQueue(){ - while(!_messageQueue.isEmpty() && _messageQueue.front()->finished()){ - _messageQueue.remove(_messageQueue.front()); - } + _clearQueue(); + //size_t m0 = _messageQueue.isEmpty()? 0 : _messageQueue.length(); + //size_t m1 = _messageQueue.isEmpty()? 0 : _messageQueue.front()->betweenFrames(); + // Serial.printf("%u R C = %u %u\n", _clientId, m0, m1); if(!_controlQueue.isEmpty() && (_messageQueue.isEmpty() || _messageQueue.front()->betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front()->len() - 1)){ + // Serial.printf("%u R S C\n", _clientId); _controlQueue.front()->send(_client); } else if(!_messageQueue.isEmpty() && _messageQueue.front()->betweenFrames() && webSocketSendFrameWindow(_client)){ + // Serial.printf("%u R S M = ", _clientId); _messageQueue.front()->send(_client); } + + _clearQueue(); } bool AsyncWebSocketClient::queueIsFull(){ @@ -553,28 +620,38 @@ bool AsyncWebSocketClient::queueIsFull(){ } void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessage *dataMessage){ - if(dataMessage == NULL) + if(dataMessage == NULL){ + // Serial.printf("%u Q1\n", _clientId); return; + } if(_status != WS_CONNECTED){ + // Serial.printf("%u Q2\n", _clientId); delete dataMessage; return; } if(_messageQueue.length() >= WS_MAX_QUEUED_MESSAGES){ ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); + // Serial.printf("%u Q3\n", _clientId); delete dataMessage; } else { _messageQueue.add(dataMessage); + // Serial.printf("%u Q A %u\n", _clientId, _messageQueue.length()); } - if(_client->canSend()) + if(_client->canSend()) { + // Serial.printf("%u Q S\n", _clientId); + // Serial.println("RUN 3"); _runQueue(); + } } void AsyncWebSocketClient::_queueControl(AsyncWebSocketControl *controlMessage){ if(controlMessage == NULL) return; _controlQueue.add(controlMessage); - if(_client->canSend()) + if(_client->canSend()) { + // Serial.println("RUN 4"); _runQueue(); + } } void AsyncWebSocketClient::close(uint16_t code, const char * message){ @@ -607,19 +684,24 @@ void AsyncWebSocketClient::ping(uint8_t *data, size_t len){ _queueControl(new AsyncWebSocketControl(WS_PING, data, len)); } -void AsyncWebSocketClient::_onError(int8_t){} +void AsyncWebSocketClient::_onError(int8_t){ + //Serial.println("onErr"); +} void AsyncWebSocketClient::_onTimeout(uint32_t time){ + // Serial.println("onTime"); (void)time; _client->close(true); } void AsyncWebSocketClient::_onDisconnect(){ + // Serial.println("onDis"); _client = NULL; _server->_handleDisconnect(this); } void AsyncWebSocketClient::_onData(void *pbuf, size_t plen){ + // Serial.println("onData"); _lastMessageTime = millis(); uint8_t *data = (uint8_t*)pbuf; while(plen > 0){ @@ -664,9 +746,9 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen){ if(_pinfo.opcode){ _pinfo.message_opcode = _pinfo.opcode; _pinfo.num = 0; - } else _pinfo.num += 1; + } } - _server->_handleEvent(this, WS_EVT_DATA, (void *)&_pinfo, (uint8_t*)data, datalen); + if (datalen > 0) _server->_handleEvent(this, WS_EVT_DATA, (void *)&_pinfo, (uint8_t*)data, datalen); _pinfo.index += datalen; } else if((datalen + _pinfo.index) == _pinfo.len){ @@ -694,6 +776,8 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen){ _server->_handleEvent(this, WS_EVT_PONG, NULL, data, datalen); } else if(_pinfo.opcode < 8){//continuation or text/binary frame _server->_handleEvent(this, WS_EVT_DATA, (void *)&_pinfo, data, datalen); + if (_pinfo.final) _pinfo.num = 0; + else _pinfo.num += 1; } } else { //os_printf("frame error: len: %u, index: %llu, total: %llu\n", datalen, _pinfo.index, _pinfo.len); @@ -957,6 +1041,7 @@ void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer){ void AsyncWebSocket::textAll(const char * message, size_t len){ + //if (_buffers.length()) return; AsyncWebSocketMessageBuffer * WSBuffer = makeBuffer((uint8_t *)message, len); textAll(WSBuffer); } @@ -1229,6 +1314,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t if (buffer) { AsyncWebLockGuard l(_lock); + // Serial.printf("Add to global buffers = %u\n", _buffers.length() + 1); _buffers.add(buffer); } @@ -1238,9 +1324,9 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t void AsyncWebSocket::_cleanBuffers() { AsyncWebLockGuard l(_lock); - for(AsyncWebSocketMessageBuffer * c: _buffers){ if(c && c->canDelete()){ + // Serial.printf("Remove from global buffers = %u\n", _buffers.length() - 1); _buffers.remove(c); } } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index f06af2c..5ebf1cc 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -84,16 +84,16 @@ class AsyncWebSocketMessageBuffer { private: uint8_t * _data; size_t _len; - bool _lock; - uint32_t _count; + bool _lock; + uint32_t _count; public: AsyncWebSocketMessageBuffer(); AsyncWebSocketMessageBuffer(size_t size); - AsyncWebSocketMessageBuffer(uint8_t * data, size_t size); - AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &); - AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer &&); - ~AsyncWebSocketMessageBuffer(); + AsyncWebSocketMessageBuffer(uint8_t * data, size_t size); + AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &); + AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer &&); + ~AsyncWebSocketMessageBuffer(); void operator ++(int i) { (void)i; _count++; } void operator --(int i) { (void)i; if (_count > 0) { _count--; } ; } bool reserve(size_t size); @@ -102,9 +102,9 @@ class AsyncWebSocketMessageBuffer { uint8_t * get() { return _data; } size_t length() { return _len; } uint32_t count() { return _count; } - bool canDelete() { return (!_count && !_lock); } + bool canDelete() { return (!_count && !_lock); } - friend AsyncWebSocket; + friend AsyncWebSocket; }; @@ -145,9 +145,9 @@ class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage { size_t _sent; size_t _ack; size_t _acked; - AsyncWebSocketMessageBuffer * _WSbuffer; + AsyncWebSocketMessageBuffer * _WSbuffer; public: - AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer * buffer, uint8_t opcode=WS_TEXT, bool mask=false); + AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer * buffer, uint8_t opcode=WS_TEXT, bool mask=false); virtual ~AsyncWebSocketMultiMessage() override; virtual bool betweenFrames() const override { return _acked == _ack; } virtual void ack(size_t len, uint32_t time) override ; @@ -173,6 +173,7 @@ class AsyncWebSocketClient { void _queueMessage(AsyncWebSocketMessage *dataMessage); void _queueControl(AsyncWebSocketControl *controlMessage); void _runQueue(); + void _clearQueue(); public: void *_tempObject; @@ -205,6 +206,7 @@ class AsyncWebSocketClient { //data packets void message(AsyncWebSocketMessage *message){ _queueMessage(message); } bool queueIsFull(); + size_t queueLen() { return _messageQueue.length() + _controlQueue.length(); } size_t printf(const char *format, ...) __attribute__ ((format (printf, 2, 3))); #ifndef ESP32 @@ -216,7 +218,7 @@ class AsyncWebSocketClient { void text(char * message); void text(const String &message); void text(const __FlashStringHelper *data); - void text(AsyncWebSocketMessageBuffer *buffer); + void text(AsyncWebSocketMessageBuffer *buffer); void binary(const char * message, size_t len); void binary(const char * message); @@ -224,7 +226,7 @@ class AsyncWebSocketClient { void binary(char * message); void binary(const String &message); void binary(const __FlashStringHelper *data, size_t len); - void binary(AsyncWebSocketMessageBuffer *buffer); + void binary(AsyncWebSocketMessageBuffer *buffer); bool canSend() { return _messageQueue.length() < WS_MAX_QUEUED_MESSAGES; } @@ -286,7 +288,7 @@ class AsyncWebSocket: public AsyncWebHandler { void textAll(char * message); void textAll(const String &message); void textAll(const __FlashStringHelper *message); // need to convert - void textAll(AsyncWebSocketMessageBuffer * buffer); + void textAll(AsyncWebSocketMessageBuffer * buffer); void binary(uint32_t id, const char * message, size_t len); void binary(uint32_t id, const char * message); @@ -301,7 +303,7 @@ class AsyncWebSocket: public AsyncWebHandler { void binaryAll(char * message); void binaryAll(const String &message); void binaryAll(const __FlashStringHelper *message, size_t len); - void binaryAll(AsyncWebSocketMessageBuffer * buffer); + void binaryAll(AsyncWebSocketMessageBuffer * buffer); void message(uint32_t id, AsyncWebSocketMessage *message); void messageAll(AsyncWebSocketMultiMessage *message); @@ -332,11 +334,11 @@ class AsyncWebSocket: public AsyncWebHandler { virtual void handleRequest(AsyncWebServerRequest *request) override final; - // messagebuffer functions/objects. - AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); - AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); + // messagebuffer functions/objects. + AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); + AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); LinkedList _buffers; - void _cleanBuffers(); + void _cleanBuffers(); AsyncWebSocketClientLinkedList getClients() const; }; diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 498ae62..3aff61b 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -59,22 +59,14 @@ class AsyncResponseStream; #ifndef WEBSERVER_H typedef enum { - HTTP_GET = 0b0000000000000001, - HTTP_POST = 0b0000000000000010, - HTTP_DELETE = 0b0000000000000100, - HTTP_PUT = 0b0000000000001000, - HTTP_PATCH = 0b0000000000010000, - HTTP_HEAD = 0b0000000000100000, - HTTP_OPTIONS = 0b0000000001000000, - HTTP_PROPFIND = 0b0000000010000000, - HTTP_LOCK = 0b0000000100000000, - HTTP_UNLOCK = 0b0000001000000000, - HTTP_PROPPATCH = 0b0000010000000000, - HTTP_MKCOL = 0b0000100000000000, - HTTP_MOVE = 0b0001000000000000, - HTTP_COPY = 0b0010000000000000, - HTTP_RESERVED = 0b0100000000000000, - HTTP_ANY = 0b0111111111111111, + HTTP_GET = 0b00000001, + HTTP_POST = 0b00000010, + HTTP_DELETE = 0b00000100, + HTTP_PUT = 0b00001000, + HTTP_PATCH = 0b00010000, + HTTP_HEAD = 0b00100000, + HTTP_OPTIONS = 0b01000000, + HTTP_ANY = 0b01111111, } WebRequestMethod; #endif @@ -94,7 +86,7 @@ namespace fs { //if this value is returned when asked for data, packet will not be sent and you will be asked for data again #define RESPONSE_TRY_AGAIN 0xFFFFFFFF -typedef uint16_t WebRequestMethodComposite; +typedef uint8_t WebRequestMethodComposite; typedef std::function ArDisconnectHandler; /* diff --git a/src/SPIFFSEditor.cpp b/src/SPIFFSEditor.cpp index e7a592e..343ed79 100644 --- a/src/SPIFFSEditor.cpp +++ b/src/SPIFFSEditor.cpp @@ -1,14 +1,18 @@ #include "SPIFFSEditor.h" #include -#include "edit.htm.gz.h" +#define EDFS + +#ifndef EDFS + #include "edit.htm.gz.h" +#endif #ifdef ESP32 #define fullName(x) name(x) #endif #define SPIFFS_MAXLENGTH_FILEPATH 32 -const char *excludeListFile = "/.exclude.files"; +static const char excludeListFile[] PROGMEM = "/.exclude.files"; typedef struct ExcludeListS { char *item; @@ -103,7 +107,7 @@ static void loadExcludeList(fs::FS &_fs, const char *filename){ static bool isExcluded(fs::FS &_fs, const char *filename) { if(excludes == NULL){ - loadExcludeList(_fs, excludeListFile); + loadExcludeList(_fs, String(FPSTR(excludeListFile)).c_str()); } ExcludeList *e = excludes; while(e){ @@ -130,12 +134,12 @@ SPIFFSEditor::SPIFFSEditor(const String& username, const String& password, const {} bool SPIFFSEditor::canHandle(AsyncWebServerRequest *request){ - if(request->url().equalsIgnoreCase("/edit")){ + if(request->url().equalsIgnoreCase(F("/edit"))){ if(request->method() == HTTP_GET){ - if(request->hasParam("list")) + if(request->hasParam(F("list"))) return true; - if(request->hasParam("edit")){ - request->_tempFile = _fs.open(request->arg("edit"), "r"); + if(request->hasParam(F("edit"))){ + request->_tempFile = _fs.open(request->arg(F("edit")), "r"); if(!request->_tempFile){ return false; } @@ -147,7 +151,7 @@ bool SPIFFSEditor::canHandle(AsyncWebServerRequest *request){ #endif } if(request->hasParam("download")){ - request->_tempFile = _fs.open(request->arg("download"), "r"); + request->_tempFile = _fs.open(request->arg(F("download")), "r"); if(!request->_tempFile){ return false; } @@ -158,7 +162,7 @@ bool SPIFFSEditor::canHandle(AsyncWebServerRequest *request){ } #endif } - request->addInterestingHeader("If-Modified-Since"); + request->addInterestingHeader(F("If-Modified-Since")); return true; } else if(request->method() == HTTP_POST) @@ -178,8 +182,8 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ return request->requestAuthentication(); if(request->method() == HTTP_GET){ - if(request->hasParam("list")){ - String path = request->getParam("list")->value(); + if(request->hasParam(F("list"))){ + String path = request->getParam(F("list"))->value(); #ifdef ESP32 File dir = _fs.open(path); #else @@ -204,11 +208,11 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ continue; } if (output != "[") output += ','; - output += "{\"type\":\""; - output += "file"; - output += "\",\"name\":\""; + output += F("{\"type\":\""); + output += F("file"); + output += F("\",\"name\":\""); output += String(fname); - output += "\",\"size\":"; + output += F("\",\"size\":"); output += String(entry.size()); output += "}"; #ifdef ESP32 @@ -221,41 +225,44 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ dir.close(); #endif output += "]"; - request->send(200, "application/json", output); + request->send(200, F("application/json"), output); output = String(); } - else if(request->hasParam("edit") || request->hasParam("download")){ - request->send(request->_tempFile, request->_tempFile.fullName(), String(), request->hasParam("download")); + else if(request->hasParam(F("edit")) || request->hasParam(F("download"))){ + request->send(request->_tempFile, request->_tempFile.fullName(), String(), request->hasParam(F("download"))); } else { const char * buildTime = __DATE__ " " __TIME__ " GMT"; - if (request->header("If-Modified-Since").equals(buildTime)) { + if (request->header(F("If-Modified-Since")).equals(buildTime)) { request->send(304); } else { - AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", edit_htm_gz, edit_htm_gz_len); - response->addHeader("Content-Encoding", "gzip"); - response->addHeader("Last-Modified", buildTime); - request->send(response); +#ifdef EDFS + AsyncWebServerResponse *response = request->beginResponse(_fs, F("/edit_gz"), F("text/html"), false); +#else + AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), edit_htm_gz, edit_htm_gz_len); +#endif + response->addHeader(F("Content-Encoding"), F("gzip")); + response->addHeader(F("Last-Modified"), buildTime); + request->send(response); } } } else if(request->method() == HTTP_DELETE){ - if(request->hasParam("path", true)){ - - if(!(_fs.remove(request->getParam("path", true)->value()))){ + if(request->hasParam(F("path"), true)){ + if(!(_fs.remove(request->getParam(F("path"), true)->value()))){ #ifdef ESP32 - _fs.rmdir(request->getParam("path", true)->value()); // try rmdir for littlefs + _fs.rmdir(request->getParam(F("path"), true)->value()); // try rmdir for littlefs #endif } - request->send(200, "", "DELETE: "+request->getParam("path", true)->value()); + request->send(200, "", String(F("DELETE: "))+request->getParam(F("path"), true)->value()); } else request->send(404); } else if(request->method() == HTTP_POST){ - if(request->hasParam("data", true, true) && _fs.exists(request->getParam("data", true, true)->value())) - request->send(200, "", "UPLOADED: "+request->getParam("data", true, true)->value()); + if(request->hasParam(F("data"), true, true) && _fs.exists(request->getParam(F("data"), true, true)->value())) + request->send(200, "", String(F("UPLOADED: "))+request->getParam(F("data"), true, true)->value()); - else if(request->hasParam("rawname", true) && request->hasParam("raw0", true)){ - String rawnam = request->getParam("rawname", true)->value(); + else if(request->hasParam(F("rawname"), true) && request->hasParam(F("raw0"), true)){ + String rawnam = request->getParam(F("rawname"), true)->value(); if (_fs.exists(rawnam)) _fs.remove(rawnam); // delete it to allow a mode @@ -263,22 +270,22 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ uint16_t i = 0; fs::File f = _fs.open(rawnam, "a"); - while (request->hasParam("raw" + String(k), true)) { //raw0 .. raw1 + while (request->hasParam(String(F("raw")) + String(k), true)) { //raw0 .. raw1 if(f){ - i += f.print(request->getParam("raw" + String(k), true)->value()); + i += f.print(request->getParam(String(F("raw")) + String(k), true)->value()); } k++; } f.close(); - request->send(200, "", "IPADWRITE: " + rawnam + ":" + String(i)); + request->send(200, "", String(F("IPADWRITE: ")) + rawnam + ":" + String(i)); } else { request->send(500); } } else if(request->method() == HTTP_PUT){ - if(request->hasParam("path", true)){ - String filename = request->getParam("path", true)->value(); + if(request->hasParam(F("path"), true)){ + String filename = request->getParam(F("path"), true)->value(); if(_fs.exists(filename)){ request->send(200); } else { @@ -306,7 +313,7 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ if(f){ f.write((uint8_t)0x00); f.close(); - request->send(200, "", "CREATE: "+filename); + request->send(200, "", String(F("CREATE: "))+filename); } else { request->send(500); } diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index d121fa7..9b7ba1b 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -105,6 +105,13 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { } } else #endif + if (_uri.length() && _uri.startsWith("/*.")) { + String uriTemplate = String (_uri); + uriTemplate = uriTemplate.substring(uriTemplate.lastIndexOf(".")); + if (!request->url().endsWith(uriTemplate)) + return false; + } + else if (_uri.length() && _uri.endsWith("*")) { String uriTemplate = String(_uri); uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1); @@ -119,16 +126,22 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { } virtual void handleRequest(AsyncWebServerRequest *request) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onRequest) _onRequest(request); else request->send(500); } virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onUpload) _onUpload(request, filename, index, data, len, final); } virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onBody) _onBody(request, data, len, index, total); } diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 9320cba..0200ce9 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -94,11 +94,11 @@ AsyncWebServerRequest::~AsyncWebServerRequest(){ if(_tempFile){ _tempFile.close(); } - + if(_itemBuffer){ free(_itemBuffer); } - + } void AsyncWebServerRequest::_onData(void *buf, size_t len){ @@ -192,8 +192,16 @@ void AsyncWebServerRequest::_removeNotInterestingHeaders(){ void AsyncWebServerRequest::_onPoll(){ //os_printf("p\n"); - if(_response != NULL && _client != NULL && _client->canSend() && !_response->_finished()){ - _response->_ack(this, 0, 0); + if(_response != NULL && _client != NULL && _client->canSend()){ + if(!_response->_finished()){ + _response->_ack(this, 0, 0); + } else { + AsyncWebServerResponse* r = _response; + _response = NULL; + delete r; + + _client->close(); + } } } @@ -202,10 +210,12 @@ void AsyncWebServerRequest::_onAck(size_t len, uint32_t time){ if(_response != NULL){ if(!_response->_finished()){ _response->_ack(this, len, time); - } else { + } else if(_response->_finished()){ AsyncWebServerResponse* r = _response; _response = NULL; delete r; + + _client->close(); } } } @@ -276,24 +286,6 @@ bool AsyncWebServerRequest::_parseReqHead(){ _method = HTTP_HEAD; } else if(m == F("OPTIONS")){ _method = HTTP_OPTIONS; - } else if(m == F("PROPFIND")){ - _method = HTTP_PROPFIND; - } else if(m == F("LOCK")){ - _method = HTTP_LOCK; - } else if(m == F("UNLOCK")){ - _method = HTTP_UNLOCK; - } else if(m == F("PROPPATCH")){ - _method = HTTP_PROPPATCH; - } else if(m == F("MKCOL")){ - _method = HTTP_MKCOL; - } else if(m == F("MOVE")){ - _method = HTTP_MOVE; - } else if(m == F("COPY")){ - _method = HTTP_COPY; - } else if(m == F("RESERVED")){ - _method = HTTP_RESERVED; - } else if(m == F("ANY")){ - _method = HTTP_ANY; } String g; @@ -930,14 +922,6 @@ const __FlashStringHelper *AsyncWebServerRequest::methodToString() const { else if(_method & HTTP_PATCH) return F("PATCH"); else if(_method & HTTP_HEAD) return F("HEAD"); else if(_method & HTTP_OPTIONS) return F("OPTIONS"); - else if(_method & HTTP_PROPFIND) return F("PROPFIND"); - else if(_method & HTTP_LOCK) return F("LOCK"); - else if(_method & HTTP_UNLOCK) return F("UNLOCK"); - else if(_method & HTTP_PROPPATCH) return F("PROPPATCH"); - else if(_method & HTTP_MKCOL) return F("MKCOL"); - else if(_method & HTTP_MOVE) return F("MOVE"); - else if(_method & HTTP_COPY) return F("COPY"); - else if(_method & HTTP_RESERVED) return F("RESERVED"); return F("UNKNOWN"); } diff --git a/src/edit.htm b/src/edit.htm index 4943b8b..5d497ea 100644 --- a/src/edit.htm +++ b/src/edit.htm @@ -1,581 +1,581 @@ - - - ESP Editor - - - - - - - - - -
-
-
-
- - - + #uploader { + position: absolute; + top: 0; + right: 0; + left: 0; + height: 28px; + line-height: 24px; + padding-left: 10px; + background-color: #444; + color: #eee; + } + #tree { + position: absolute; + top: 28px; + bottom: 0; + left: 0; + width: 160px; + padding: 8px; + } + + #editor, + #preview { + position: absolute; + top: 28px; + right: 0; + bottom: 0; + left: 160px; + border-left: 1px solid #eee; + } + + #preview { + background-color: #eee; + padding: 5px; + } + + #loader { + position: absolute; + top: 36%; + right: 40%; + } + + .loader { + z-index: 10000; + border: 8px solid #b5b5b5; + border-top: 8px solid #3498db; + border-bottom: 8px solid #3498db; + border-radius: 50%; + width: 240px; + height: 240px; + animation: spin 2s linear infinite; + display: none; + } + + @keyframes spin { + 0% { + transform: rotate(0); + } + 100% { + transform: rotate(360deg); + } + } + + + + + + + +
+
+
+
+ + + \ No newline at end of file diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index b8b5c02..aa77e28 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -2,7 +2,7 @@ //File: edit.htm.gz, Size: 4503 #define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x9B,0xC8,0x22,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0x5A,0xE6,0xAE,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, 0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B,