Related to a post of mine ( How to retrieve a file from Internet via HTTP? ) about how to easily and robustly download a file from Internet, I have found a possible solution
The connect timeout obviously isn't applicable in your test because by the time you start your test (i.e., pull the plug), the connection has already been established. Indeed, the connection is already established before you even get around to setting the timeout option.
The validity of the receive timeout is also suspect, because you've already begun receiving the response, too.
The most promising-looking timeout is the disconnect timeout, but MSDN says that's not implemented yet.
It seems to me that the way to go is to use asynchronous operations. Use InternetReadFileEx
and use the irf_Async
and irf_No_Wait
flags. If too much time passes without receiving any data, close the connection. Another option is to stick with your synchronous calls, but then call InternetCloseHandle
from another thread if the download takes too long.
IMO, you should run this in a thread. Threading does not have to mean looping - it can be a "one and done" thread. Run it that way, and your GUI remains responsive until the thread finishes. I realize that this does not actually answer your question, but it will make your code better.
Also, if you disconnect the internet during the first loop where you're checking for data, I think it will retry 10 times. You should detect, and then quit right away.
Lastly, I don't think you should use EXIT when you've got handles and stuff open. Break instead, so that you still run through the disconnects. I would expect your code to tie up the socket. I saw this recently during a code review when there was an EXIT intead of a BREAK, and it's causing a memory leak because objects are created and never freed. I'd use the same rule here.
There is a documented bug in MS IE code. Can only be solved by using the code in a thread and re-implementing the time out mechanism.
Details:
"This acticle shows a workaround to the InternetSetOption API bug on setting timeout values by creating a second thread. InternetSetOption Does Not Set Timeout Values"
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q224318
(Link was reported broken. Blame MS not me)
Maybe somebody can help with implementing this bug fix also in Delphi. I personally don't have experience with C. Even the backbone in pseudo-Pascal will be nice.
Are you sure that you aren't hitting the INTERNET_OPTION_CONNECT_TIMEOUT? It will try to connect first, then receive.
In order to test the connect timeout, it must resolve, but never connect. In order to test the read timeout, it must connect, but never receive any data.
I generally set my connect timeout to 10 seconds, and the read timeout to 30 seconds. Anything longer than that, I consider down anyway.