Hi
I have taken a look at this and simulated a few possible solutions. However what you are trying to do opens up a "can of worms" at both TCP and HTTP levels. I will try to explain all below. But first the more simple answer:
BTW: what's the last if() doing in the above code (i.e. the one with the usPortLen)?
if ((usPortLen) && (HTTP_session->ptrFileStart == HTTP_session->ptrFile)) {
HTTP_session->ptrFileStart += FILE_HEADER;
}
This is simply checking for the very first data frame of the post sequence. There must be data (usPortLen != 0), since it is possible to have the very first frame of the post sequence without actually data content, and the file pointer is still at the first position of the file.
The line with += FILE_HEADER is moving the pointer which will be used to save data in a file to the first location after a short header. For more info about how the file system and this header work you can look at the document:
http://www.utasker.com/docs/uTasker/uTaskerFileSystem.PDFNow back to the more tricky stuff...
The best way to see exactly what is happening is to look at the network data using Ethereal.
The browser starts posting data and somewhere during the post sequence you return a web page informing that the post has failed during the transfer. This is OK. The page is served correctly but browsers don't display what has been sent while they are still in the process of posting (although the page is actually waiting to be displayed once the post has terminated).
What you want to do is to inform as fast as possible that the post has failed, even before the post has terminated, but the browser is against us here. What needs to be done is to stop the Browser posting so that it can finally display the error message.
When the HTTP server has served the error page it requests a close of the TCP connection (the HTTP server is working in HTTP1.0 mode and this is normal). And now we get into TCP teratory because you will see that a FIN is sent and the TCP state TCP_STATE_FIN_WAIT_1 is entered. However since the browser is busy posting data, the TCP connection will not close - this is allowed, so the Browser side will acknowledge the FIN but not send its own just yet. This puts TCP in the TCP_STATE_FIN_WAIT_2 state, waiting for the other side to finally finish what is is doing and terminate the connection.
Now we come to the question as to what do we actually do with the data which we are receiving although we don't want it. If we just ignore it (which is in fact what is happening in your test case) the Browser will get stubourn and repeat until it finally realises that the connection is in fact dead. This is the reason why it is taking a very long time.
It would be possible to immediately reset the connection so that the post really terminates immediately but the result is that the Browser displays its own error message rather than the nice side which you have just served. This is therefore also not a solution.
So you finally realise that the only way to display the error message is in fact to receive all of the data (dumping it on the way if you like). At the end, either the page which was served will finally be displayed by the browser or else you can serve it in response to the status of the download (which is how the uTasker demo does it).
My conclusion is that I can't find a way to stop the browser posting and display the message served without letting the post terminate normally. I wonder whether anyone else knows of a possibility!!What I have done is modified the TCP file slightly so that it automatically acks all received data when in the FIN_WAIT_1 and FIN_WAIT_2 states - find the file at
www.uTasker.com/software/test/tcp.zip (always use the project password). See the test define "MJB_13_7_2007". This will allow your code to work without the long delay, but it still won't actually be noticably faster than serving the page at the end of the complete sequence.
I am sorry that I can't suggest an alternative at the moment but I hope that what is seen is now understood.
Regards
Mark