I believe I found the reason of the problem. The following happens.

If a HTTP request is delayed and the answer is prepared in a file and it's content size is only few bytes (that is the scenario, which I use mostly), then the *http_send()* in the *httpd.c* return a wrong value.

The callback function which used from the httpd webserver is *http_continue()*. This function contains the following code (I removed the debug code for better readability)

/struct http_state *hs = (struct http_state *)connection;
LWIP_ASSERT_CORE_LOCKED();
if (hs && (hs->pcb) && (hs->handle)) {
  if (http_send(hs->pcb, hs)) {
    /* If we wrote anything to be sent, go ahead and send it now. */
    altcp_output(hs->pcb);
  }
}
/
If http_send() is called and the file is read and could be read within this call then somewhere in this function the following decision will be processed

/if ((hs->left == 0) && (fs_bytes_left(hs->handle) <= 0)) {
  /* We reached the end of the file so this request is done.
   * This adds the FIN flag right into the last data segment. */
  LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n"));
  http_eof(pcb, hs);
  return 0;
}/

And if this decision is true, because all data from file could be read. Now *http_send()* returns 0, which means back in *http_continue()* the call of *altcp_output()* (which is in fact *tcp_output() *) is not done. That means any pending data to send will happen if the TCP timer elapsed (that's why I see so long answer delays). I now changed the return value of the above code from "_return 0_" to "_return data_to_send_" (which holds the correct return value in this case). And now I see the response times I expected.

Is my analysis correct and this is a bug in the web server code ?

Kind regards
Roland


Am 03.10.24 um 15:39 schrieb Trampas Stern:
First off it is recommended that the command line parser run in a different context for each application.  For example when I run multiple command line interfaces each one gets its own parser.  This way things like history and such are local to each interface and commands run independently.  This should solve your dead lock and be more reasonable for users. It may require some mutexes elsewhere in your code.

I have seen latency issues with TCP and LWIP as it will often cache responses and process them after some time period. I mitigate this by calling the tcp_output() function to flush the tcp_write() and decrease latency.

regards,
Trampas





On Wed, Oct 2, 2024 at 10:27 AM Info via lwip-users <lwip-users@nongnu.org> wrote:

    Does nobody have the time to give me some advise where the problem
    could be ?

    Any help would really be very welcome.

    Kind regards
    Roland


    Am 17.09.24 um 09:32 schrieb Info via lwip-users:
    Hi

    I got a step further with my investigation. The "delayed" answer
    is related to the TCP_TMR_INTERVAL, it is set to 250 ms. If I set
    this value to 100ms for example, the answer from the web server
    is sent faster (means after about 100 ms the answer is received).

    I have attached three Wireshark capture showing the communication
    of different settings:

    HTTPD_answer _in_CGI_handler :
      The answer file is completly created in the CGI handler (which
    is more or less our answer timing reference)
    HTTPD_async_read_250ms_tcp_timer :
      The answer file is available after the helper task has been
    running (calling tcpip_callback() at the end) and
    TCP_TMR_INTERVAL is set to 250
    HTTPD_async_read_100ms_tcp_timer :
      The answer file is available after the helper task has been
    running (calling tcpip_callback() at the end) and
    TCP_TMR_INTERVAL is set to 100

    Lowering TCP_TMR_INTERVAL could help, but I'm not sure if this is
    the correct way ?
    Maybe I missed something before calling tcpip_callback(), which
    calls http_continue() (the callback function and arguments passed
    by fs_read_async() ).

    Any help or tips are welcome.

    Kind regards,
    Roland

    Am 13.09.24 um 15:35 schrieb Info via lwip-users:
    Hi

    I'm using the web server (httpd) from the lwIP (V2.13) with
    FreeRTOS. The web server is running fine so far. A socket server
    is also running (in it's own task) to implement a small command
    line. The web server also has the ability to access the command
    line over HTTP requests. Both the web and the socket server
    using the same command line parser functionality. The parser is
    protected with a semaphore, because not all commands on the
    command line are fully reentrant.

    Problem: If both the socket and the web server using the parser
    at the same time a deadlock could occurs, that is because the
    web server is running in the TCP task context and the socket
    server is trying to use the TCP task from inside the command
    line parser.

    I enabled the LWIP_HTTPD_FS_ASYNC_READ and it's functionality
    and added the required code. The CGI handler now creates an
    empty response file and sends a message to the helper task. The
    helper task receives the message, calls the command line parser
    and initiate to send back the answer via a tcpip_callback() call.

    With this implementation, it is possible to call the command
    line parser outside of the TCP task context and not blocking the
    TCP task.

    That works so far, but the answer time of this solution is 10
    times slower, than to call the command line parser directly in
    the CGI handler. I measured the time between the receive of the
    HTTP request and the call of the callback function passed by
    tcpip_callback() and that is not the problem. It is something in
    the lwIP that slow down the answer.

    Question:
    - What could be the reason of the longer response time (about
    250ms instead of 20ms) ?
    - Is it possible to let the web server (httpd) in it's own task
    ? Has anyone done it already ?

    Thank you very much for your help.

    Regards, Roland


    _______________________________________________
    lwip-users mailing list
    lwip-users@nongnu.org
    https://lists.nongnu.org/mailman/listinfo/lwip-users


    _______________________________________________
    lwip-users mailing list
    lwip-users@nongnu.org
    https://lists.nongnu.org/mailman/listinfo/lwip-users

    _______________________________________________
    lwip-users mailing list
    lwip-users@nongnu.org
    https://lists.nongnu.org/mailman/listinfo/lwip-users

_______________________________________________
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to