Note that there are some explanatory texts on larger screens.

plurals
  1. POThe connection does not timeout while downloading file from internet
    primarykey
    data
    text
    <p>Related to a post of mine ( <a href="https://stackoverflow.com/questions/3122306/how-to-retrieve-a-file-from-internet-via-http">How to retrieve a file from Internet via HTTP?</a> ) about how to easily and robustly download a file from Internet, I have found a possible solution - however is not working as it was supposed to work.</p> <p>According to MS documentation, the code below is supposed to time-out at 500ms after I disconnect myself from internet. However, it looks like it totally ignores the 'INTERNET_OPTION_RECEIVE_TIMEOUT' setting. The application freezes during download. It takes about 20-30 to this function to realize that there the Internet connection is down and to give the control back to the GUI.</p> <p>Anybody knows why?</p> <pre><code>function GetBinFileHTTP (const aUrl: string; const pStream: TStream; wTimeOut: Word= 500; wSleep: Word= 500; wAttempts: Word= 10): Integer; CONST BufferSize = 1024; VAR hSession, hService: HINTERNET; Buffer : array[0..BufferSize-1] of Char; dwBytesRead, dwBytesAvail: DWORD; lSucc : LongBool; lRetries, dwTimeOut: Integer; begin Result:= 0; if NOT IsConnectedToInternet then begin Result:= -1; EXIT; end; hSession := InternetOpen(PChar(ExtractFileName(Application.ExeName)), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); { The INTERNET_OPEN_TYPE_PRECONFIG flag specifies that if the user has configured Internet Explorer to use a proxy server, WinInet will use it as well. } if NOT Assigned(hSession) then begin Result:= -4; EXIT; end; TRY hService := InternetOpenUrl(hSession, PChar(aUrl), nil, 0, INTERNET_FLAG_RELOAD, 0); if NOT Assigned(hService) then Exit; TRY FillChar(Buffer, SizeOf(Buffer), 0); { Set time out } dwTimeOut:= wTimeOut; InternetSetOption(hService, INTERNET_OPTION_RECEIVE_TIMEOUT, @dwTimeOut, SizeOf(dwTimeOut)); { use INTERNET_FLAG_RELOAD instead of NIL to redownload the file instead of using the cache } InternetSetOption(hService, INTERNET_OPTION_CONNECT_TIMEOUT, @dwTimeOut, SizeOf(dwTimeOut)); REPEAT lRetries := 0; REPEAT lSucc:= InternetQueryDataAvailable( hService, dwBytesAvail, 0, 0); if NOT lSucc then Sleep( wSleep ); if lRetries &gt; wAttempts then Result:= -2; UNTIL lSucc OR (Result= -2); if NOT InternetReadFile(hService, @Buffer, BufferSize, dwBytesRead) then begin Result:= -3; { Error: File not found/File cannot be downloaded } EXIT; end; if dwBytesRead = 0 then Break; pStream.WriteBuffer(Buffer[0], dwBytesRead); UNTIL False; FINALLY InternetCloseHandle(hService); end; FINALLY InternetCloseHandle(hSession); end; Result:= 1; end; </code></pre> <p>Here is the documentation:</p> <pre><code>{ INTERNET_OPTION_CONNECT_TIMEOUT Sets or retrieves an unsigned long integer value that contains the time-out value to use for Internet connection requests. If a connection request takes longer than this time-out value, the request is canceled. When attempting to connect to multiple IP addresses for a single host (a multihome host), the timeout limit is cumulative for all of the IP addresses. This option can be used on any HINTERNET handle, including a NULL handle. It is used by InternetQueryOption and InternetSetOption. INTERNET_OPTION_RECEIVE_TIMEOUT Sets or retrieves an unsigned long integer value that contains the time-out value to receive a response to a request. If the response takes longer than this time-out value, the request is canceled. This option can be used on any HINTERNET handle, including a NULL handle. It is used by InternetQueryOption and InternetSetOption. For using WinInet synchronously, only the default value for this flag can be changed by calling InternetSetOption and passing NULL in the hInternet parameter. INTERNET_OPTION_CONTROL_RECEIVE_TIMEOUT - Identical to INTERNET_OPTION_RECEIVE_TIMEOUT. This is used by InternetQueryOption and InternetSetOption. } </code></pre> <p>Edit: I disconnect the Internet by unplugging the cable or (for wireless) from software AFTER the application starts the download (I chose to download large file). It simulates the web site going offline.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload