mathieucarbou / ESPAsyncWebServer

Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040
https://mathieu.carbou.me/ESPAsyncWebServer/
GNU Lesser General Public License v3.0
83 stars 17 forks source link

[BUG] Crash with 3.3.16 #132

Closed philfifi closed 1 month ago

philfifi commented 1 month ago

Description

On ESP8266, the lib always crashes even on very simple request. It is working on 3.3.15.

Stack trace

0x40205cad in AsyncWebServerRequest::_parseReqHead() at .pio/libdeps/esp8266/ESPAsyncWebServer/src/WebRequest.cpp:235

The code is:

bool AsyncWebServerRequest::_parseReqHead() {
  // Split the head into method, url and version
  int index = _temp.indexOf(' ');
  String m = _temp.substring(0, index);
  index = _temp.indexOf(' ', index + 1);
  String u = _temp.substring(m.length() + 1, index);
  _temp = _temp.substring(index + 1);

  if (m == T_GET) {   // <----------------- line 235
    _method = HTTP_GET;
  } else if (m == T_POST) {

Printing _temp gives GET / HTTP/1.1

Printing m gives GET

Additional notes

Reproduced doing a simple curl 192.168.14.244. With other versions, the esp answers "not found".

Versions

HARDWARE: ESP8266 80MHz, 80KB RAM, 1MB Flash
PACKAGES: 
 - framework-arduinoespressif8266 @ 3.30102.0 (3.1.2) 
 - tool-esptool @ 1.413.0 (4.13) 
 - tool-esptoolpy @ 1.30000.201119 (3.0.0) 
 - tool-mklittlefs @ 1.203.210628 (2.3) 
 - tool-mkspiffs @ 1.200.0 (2.0) 
 - toolchain-xtensa @ 2.100300.220621 (10.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 39 compatible libraries
Scanning dependencies...
Dependency Graph
|-- ESPAsyncWebServer @ 3.3.16
|-- ESP8266WiFi @ 1.0
Building in debug mode

Code

My program looks like:


void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}

AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

    server.onNotFound(notFound);

    ws.onEvent(onWsEventEmpty);
    server.addHandler(&ws);

(exact same code as #85)

mathieucarbou commented 1 month ago

Thanks for the detailed report. Looking...

mathieucarbou commented 1 month ago

Rally weird...

This is the diff between 3.3.15 and 3.3.16:

https://github.com/mathieucarbou/ESPAsyncWebServer/compare/v3.3.15...v3.3.16

The only change is a fix in the macro definition.

@vortigont : FYI

mathieucarbou commented 1 month ago

I can reproduce... This is caused by the literals...

mathieucarbou commented 1 month ago

@vortigont : I understand what is happening.

When moving the strings as constants in the literals file, your forgot to use FPSTR at the places where these constants are used

See: https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html

mathieucarbou commented 1 month ago

Ok so this is too complex to fix that everywhere. So I will rollback and update the literals file to not use PROGMEM. Strings will be in RAM fro 8266, like in 3.3.15.

mathieucarbou commented 1 month ago

Released https://github.com/mathieucarbou/ESPAsyncWebServer/releases/tag/v3.3.17, which brings back the code like 3.3.15.

vortigont commented 1 month ago

Strings will be in RAM fro 8266, like in 3.3.15.

Ugh... can't wait the day when 8266 would perish

DRSDavidSoft commented 1 month ago

Ugh... can't wait the day when 8266 would perish

Out of curiosity, what architecture difference between ESP32 and ESP8266 required the use of PROGMEM in ESP8266 for memory optimizations, while this isn't required for ESP32? As far as I could see, they are both Xtensa-based and use the same architecture.

The first commit to segregate the literals was first made in 18ed8fbe2af0ae99cb622238fa9bb845c3984cdd but it doesn't go into details about why it was applied. (Fun fact, the ~ESP8622~ instead of the correct ESP8266 bug was present from the very first there, so the macro definitions never worked in the first place except for 3.3.16 πŸ˜„)

This is the only information I could find about the use of PROGMEM. It doesn't say anything about ESP8266, though. https://esp32.com/viewtopic.php?t=20595

Lastly, wouldn't incorporating F() in the literals.h file help with this? According to the docs, it uses FPSTR and applies PROGMEM so you don't have to do it manually. I would appreciate to learn more and dig more into this. πŸ‘πŸ»

mathieucarbou commented 1 month ago

@DRSDavidSoft : your answers are all in this good article : https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html