Error in long-ish responses using AsyncWebServer_Teensy41

Tetrahelix

New member
Hi everyone,

I've been using the Teensy 4.1 for a while now, on a project where I'm measuring a bunch of stuff with various ADCs and exposing their outputs over HTTP using the AsyncWebServer_Teensy41 library. Everything's mostly working fine, but occasionally I get this weird error where some of the sent bytes aren't what I'm trying to send.

The error always happens at the start of a TCP packet (the TCP payload, never in any of the headers) when a HTTP response is split between multiple TCP packets. In my repro code (below) it always happens to the 5th TCP packet in a response, but in my main project I've seen it elsewhere (even the first packet, breaking the HTTP header), and not in a consistent location. Sometimes there's some extra garbage added to the end of the last packet too.

I've spent several days trying to track down the cause with no luck, so I just threw together some minimal code that reproduces the problem. I'm using platformio through VSCode. Here's the platformio.ini and main.cpp:
Code:
[env:teensy41]
platform = teensy
board = teensy41
framework = arduino
lib_deps =
  ssilverman/QNEthernet@^0.27.0
  khoih-prog/Teensy41_AsyncTCP@^1.1.0
  khoih-prog/AsyncWebServer_Teensy41@^1.7.0
Code:
#include "QNEthernet.h"
using namespace qindesign::network;
#include <AsyncWebServer_Teensy41.h>

AsyncWebServer server(80);

void setup() {
  Serial.begin(115200);
  delay(500);

  Ethernet.begin({192,168,0,214}, {255,255,255,0}, {192,168,0,1});

  if (!Ethernet.waitForLocalIP(5000)) {
    while (true) {
      delay(1);
    }
  } else {
    Serial.print(F("Connected! IP address:"));
    Serial.println(Ethernet.localIP());
  }

  delay(2000);

  server.on("/", [](AsyncWebServerRequest * request) {
    AsyncResponseStream *response = request->beginResponseStream("text/plain");
    for (int i = 0; i < 10; i++) {
      response->write(R"(
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4F
50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6F
70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7F
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8F
90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9F
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AF
B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BF
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CF
D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DF
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EF
F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FF
)");
    }
    request->send(response);
  });

  server.begin();
  Serial.print("Server started @ ");
  Serial.println(Ethernet.localIP());
}

void loop() {
}

Here's the output:
1715052072705.png


Wireshark capture showing the bad data is at the start of a TCP payload: first 7 (maybe 8?) bytes are incorrect. Not always replaced with the same value, changing the code somewhere else changes the value.
1715052171016.png


Any help figuring this out would be appreciated.
 
I’m just guessing here, but is it possible to turn off “nonCopyingSend”, or some such, when sending the reply? If so, does it help?

See here:
 
Thank you so much for finding that! I didn't think to look in the QNEthernet github. That fix doesn't exactly work for me with the method I'm using, but should help me track it down.

Although with the other comments in that issue, I may look harder for another library or write a really basic http parser instead.
 
Back
Top