This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

TCPnet hanging in cgi_func()

Hi all,
I have a problem with a cgi handler I'm writing. My cgi_func() needs to format and output an html table. I took the inspiration from the tcp.cgi handler in HTTP Demo code.
I experience the problem of the http server getting stuck sometimes when I request my cgi url: the page itself is not displayed in the browser and I cannot access any other page.

I found out the problem is that I made the assumption of a minimum size for the output buffer passed to cgi_func() by the caller. This was because of the following comment from the function skeleton in http_cgi.c:

/* buflen - length of this buffer (500-1400 bytes - depends on MSS) */

Do I read the wrong value for the minimum size (500) or should I set up the function to be able to work with any buflen (at worst down to a single byte)?

The point is that in cgi_func() I'm cycling over my table's row and using the len |= 0x8000 trick to get the function called again. But if I miss to write a single byte due to the buffer being shorter than the size of a single row in my table, the function get called back again (this is ok, since the table is not over yet) with buflen ALWAYS having the same (too short value).

Is this supposed to be the correct behaviour? If so is there a minimum value for buflen I can assume in order to correctly dimension my iterative task?

TIA

Parents
  • Yes, you are correct. I forgot that the cgi_func() behaviour has been changed. HTTP server engine repeats calling cgi_func() so many times until the buffer is considered full. Then the packet is sent. This change was introduced with RL-ARM version 3.10 and results in a great increase of HTTP Server performance.

    First time, the cgi_func gets called with a big buffer. When this function returns, HTTP server checks if there is enough remaining space in the buffer. If this is true, cgi_func is called again with a buffer pointing at the end of previous call and the buffer size is reduced accordingly. If you want to force HTTP server to send data no matter how much space is left in the buffer, cgi_func() should return with flag 0x4000 or-ed with the length.

    Flag values for cgi_func return are:
    - 0x8000 = repeated call to cgi_func
    - 0x4000 = force sending a constructed packet

    When you see that the buflen is small, copy some data to the buffer and retur with len or-ed with 0x4000. This will force HTTP Server to transmit a packet and call next time with a full buffer size.

    Franc

Reply
  • Yes, you are correct. I forgot that the cgi_func() behaviour has been changed. HTTP server engine repeats calling cgi_func() so many times until the buffer is considered full. Then the packet is sent. This change was introduced with RL-ARM version 3.10 and results in a great increase of HTTP Server performance.

    First time, the cgi_func gets called with a big buffer. When this function returns, HTTP server checks if there is enough remaining space in the buffer. If this is true, cgi_func is called again with a buffer pointing at the end of previous call and the buffer size is reduced accordingly. If you want to force HTTP server to send data no matter how much space is left in the buffer, cgi_func() should return with flag 0x4000 or-ed with the length.

    Flag values for cgi_func return are:
    - 0x8000 = repeated call to cgi_func
    - 0x4000 = force sending a constructed packet

    When you see that the buflen is small, copy some data to the buffer and retur with len or-ed with 0x4000. This will force HTTP Server to transmit a packet and call next time with a full buffer size.

    Franc

Children
  • Franc,
    thanks for your clarifying addendum! I was figuring it out by noting that buflen was monotonically decreasing at each call on repeated loops of the same http session.

    The flag trick also suggest me a different way to fix my cgi_func() other than locally buffering my html table's row source and copying it according to the available room in the buffer. I'll try flushing the buffer as soon as it gets too small to host a single row of my table.

    I suggest to update this online documentation page for cgi_func(): http://www.keil.com/support/man/docs/rlarm/rlarm_cgi_func.htm . In particular the sentence:

    "If the return value's most significant bit is set to 1, the TCPnet script interpreter calls the cgi_func function again WITH THE SAME VALUE FOR the arguments env, BUFLEN, and pcgi, which holds the same content as previously set. The argument buf is adjusted according to the number of bytes that were written to the output buffer."

    ...should be changed to reflect the changes in buflen argument at each call in repeated loops.

    I also suggest to accordingly update the comments in the HTTP_CGI.C template and, maybe, the example code of the handler for tcp.cgi. It should make the user aware that no assumption can be made about the lower value for buflen (i.e. by trying the flushing flag)

    Thanks again
    Andrea