Problem
My teensy is connected to 4 Serial devices and I use the Webserver provide access to them over a local network. I have a Raspberry Pi that is requesting data from the Webserver in multiple threads. It sometimes happens that the requests to the webserver are simultaneously (within 1 ms). Roughly 5% of the time the webserver send an invalid status line back. E.g. (0xb0 ce 00 20 b0 ce 00 20)200 OK
instead of HTTP/1.1 200 OK
. The string 200 OK
is always there and the payload is also intact, just HTTP/1.1
is scrambled. I tested this with wireshark. This causes an HttpRequestException: Received an invalid status line: '?? ?? 200 OK'.
in my C# application on the RPi (also on my local machine I just for development).
I tried to find the bug in the Webserver Code but could not find it. I only found the code where the header gets assembled
https://github.com/khoih-prog/AsyncWebServer_Teensy41/blob/main/src/AsyncWebResponses_Teensy41.cpp#L265
Workaround
I want to do a workaround in the C# (.Net 6) Application by catching the Exception and look at the status line. If it contains 200 OK
it is valid. But I cannot access response
in the following code:
HttpResponseMessage response;
try
{
response = await client.GetAsync(url);
}
catch (HttpRequestException exc)
{
Console.WriteLine($"Status Code: {exc.StatusCode}");
Console.WriteLine($"Request error: {exc.ToString()}");
Console.WriteLine($"Request error: {exc.Message}");
}
Output:
Request error: System.Net.Http.HttpRequestException: Received an invalid status line: '►? ►? 200 OK'.
at System.Net.Http.HttpConnection.ParseStatusLine(ReadOnlySpan`1 line, HttpResponseMessage response)
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at Program.readControllerVerion(String url) in C:XXXSANDBOXConsoleApp4(.NET6.0)Program.cs:line 62
Request error: Received an invalid status line: '►? ►? 200 OK'.
I could look if exc.message
contains Received an invalid status line:
and 200 OK
, but I’m not sure if that is the best way.
TCP
I noticed that there is a TCP Connection opened and closed for every http request even if I use one HttpClient
per thread. It seems that the TCP Connections are overlapping each other. Maybe that is causing the Teensy to messup the status line. Can I force the HTTP Client to reuse the TCP Connection?