Paul,
Thanks for the fix, but there is one other thing that is wrong in this bit of code.
session->request.content_len -= res;
if (res == 0)
break;
This should be
if (res > 0)
session->request.content_len -= res;
else
break;
Without this change it is possible to be stuck in this loop if httpd_read returns -1.
The reason I bring this up is because I had connections getting stuck in a Close Wait state and would never clear.
What I found is a POST to a cgi script could be sent with data, but the content length is longer than the actual data.
Example:
"POST /blah.cgi HTTP/1.1\x0d\x0a"
"Host: 192.168.1.99\x0d\x0a"
"Content-Length: 2000\x0d\x0a"
"Connection: close\x0d\x0a\x0d\x0a"
"BlahBlah"
if ((cp1 = strrchr(cp, '.')) != 0)//<------- this is found in the above example
{
if (0 == strcasecmp(cp1, ".cgi")) //<-------- .cgi is found in the above example
{
cgi = 1; //<---------- set because we found .cgi in the above example
// search cgi script
*cp1 = 0;
res = httpd_cgi(server, session, cp + 1); //<-------- returns -1 because blah.cgi is not in our cgi link table
*cp1 = '.';
}
}
if (cgi || session->request.content_len) //<-------- both are true in the above example. content_len is = equal to 2000 in the above example.
{
if (res < 0) //<---------- this is true because httpd_cgi did not find the .cgi
{
if (res != -2)
cgi = 0;
while (session->request.content_len) //<------- is equal to 2000 in the first loop and 1992 the second loop
{
//The call below will return -1 when all of the remaining bytes in the POST request after the header are read (BlahBlah = 8 bytes)
//So res = 8 in the first pass through the loop, and -1 in the second pass through the loop.
res = httpd_read(sesion, buf, (int)((session.content_len > sizeof(buf))? sizeof(buf) : session->request.content_len));
if (res > 0) // only subtract if httpd_read copied 1 or more bytes to buf.
session->request.content_len -= res; // first time through content_len will equal 2000 - 8, or 1992
else //<--------- if httpd_read returns -1 (or 0) we will break out of the loop
break;
}
}
...
...
Hope this helps someone else out there.
Another suggestion is setting DEFAULT_KEEPALIVE to (1) in rtcs.h. I had connections stuck in ESTABLISHED mode and would never close. For my application this was not desireable, nor would I think it would be for a web interface. Someone could connect and then just leave it open forever. Or worse, make multiple connections and never close them.
Thanks all
Larry DeMuth