View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0005719 | JEDI VCL | 00 JVCL Components | public | 2011-11-24 09:32 | 2012-09-10 14:15 |
Reporter | tetardd | Assigned To | obones | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Product Version | 3.45 | ||||
Target Version | Fixed in Version | 3.46 | |||
Summary | 0005719: TJvHttpUrlGrabberThread should not have FContinue private variable | ||||
Description | TJvHttpUrlGrabberThread = class(TJvCustomUrlGrabberThread) protected FContinue: Boolean; function GetGrabber: TJvHttpUrlGrabber; procedure Grab; override; public property Grabber: TJvHttpUrlGrabber read GetGrabber; end; The FContinue variable is present in the ancestor to allow for download operations to be canceled (in the OnProgress event). The FContinue variable in TJvHttpUrlGrabberThread prevents this cancelling to take place. (I believe the OnProgress sets the ancestors's FContinue to False while the Grab of this object check its own FContinue that's never set to False). It should be removed (and the Grab method corrected to access the ancestor's Continue property rather than its own FContinue variable. | ||||
Additional Information | This is how the should look (my modifications marked with David Tetard): TJvHttpUrlGrabberThread = class(TJvCustomUrlGrabberThread) protected // Removed by David Tetard: TJvCustomUrlGrabberThread already has it. // FContinue: Boolean; function GetGrabber: TJvHttpUrlGrabber; procedure Grab; override; public property Grabber: TJvHttpUrlGrabber read GetGrabber; end; ******************** procedure TJvHttpUrlGrabberThread.Grab; var hSession, hHostConnection, hDownload: HINTERNET; HostName, FileName, strUserName, strPassword: string; UserName, Password: PChar; Port: Cardinal; Buffer: PChar; dwBufLen, dwIndex, dwBytesRead, dwTotalBytes: DWORD; HasSize: Boolean; Buf: array [0..1024] of Byte; begin Buffer := nil; // Modified by David Tetard: // FContinue := True; Continue := True; hSession := nil; hHostConnection := nil; hDownload := nil; try try Grabber.ParseUrl(Grabber.Url, Grabber.GetSupportedProtocolMarker, HostName, FileName, strUserName, strPassword, Port); if strUserName = '' then strUserName := Grabber.UserName; if strPassword = '' then strPassword := Grabber.Password; if Port = 0 then Port := Grabber.Port; // Setup the PChars for the call to InternetConnect if strUserName = '' then UserName := nil else UserName := PChar(strUserName); if strPassword = '' then Password := nil else Password := PChar(strPassword); ErrorText := ''; //Connect to the web SetGrabberStatus(gsConnecting); case Grabber.ProxyMode of pmNoProxy: hSession := InternetOpen(PChar(Grabber.Agent), INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0); pmSysConfig: hSession := InternetOpen(PChar(Grabber.Agent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); pmManual: hSession := InternetOpen(PChar(Grabber.Agent), INTERNET_OPEN_TYPE_PROXY, PChar(Grabber.ProxyAddresses), PChar(Grabber.ProxyIgnoreList), 0); end; if hSession = nil then begin ErrorText := SysErrorMessage(GetLastError); Synchronize(Error); Exit; end; InternetSetStatusCallback(hSession, PFNInternetStatusCallback(@DownloadCallBack)); // Connect to the host hHostConnection := InternetConnect(hSession, PChar(HostName), Port, UserName, Password, INTERNET_SERVICE_HTTP, 0, DWORD(Self)); if Terminated then Exit; if hHostConnection = nil then begin ErrorText := GetLastInternetError; Buffer := nil; Synchronize(Error); Exit; end; // InternetSetStatusCallback(hHostConnection, PFNInternetStatusCallback(@DownloadCallBack)); //Request the file hDownload := HttpOpenRequest(hHostConnection, 'GET', PChar(FileName), 'HTTP/1.0', PChar(Grabber.Referer), nil, INTERNET_FLAG_RELOAD or INTERNET_FLAG_PRAGMA_NOCACHE, 0); if hDownload = nil then begin ErrorText := GetLastInternetError; Synchronize(Error); Exit; end; // InternetSetStatusCallback(hDownload, PFNInternetStatusCallback(@DownloadCallBack)); if Grabber.ProxyMode in [pmManual, pmSysConfig] then begin // if manual mode and valid session, we set proxy user name and password InternetSetOption(hDownload, INTERNET_OPTION_PROXY_USERNAME, PChar(Grabber.ProxyUserName), Length(Grabber.ProxyUserName)+1); InternetSetOption(hDownload, INTERNET_OPTION_PROXY_PASSWORD, PChar(Grabber.ProxyPassword), Length(Grabber.ProxyPassword)+1); end; //Send the request HttpSendRequest(hDownload, nil, 0, nil, 0); if Terminated then Exit; Grabber.Stream := TMemoryStream.Create; dwIndex := 0; dwBufLen := 1024; GetMem(Buffer, dwBufLen * SizeOf(Char)); HttpQueryInfo(hDownload, HTTP_QUERY_STATUS_CODE , Buffer, dwBufLen, dwIndex); Grabber.FHTTPStatus := Buffer; dwIndex := 0; dwBufLen := 1024; HasSize := HttpQueryInfo(hDownload, HTTP_QUERY_CONTENT_LENGTH, Buffer, dwBufLen, dwIndex); if Terminated then Exit; if HasSize then Grabber.SetSize(StrToInt(StrPas(Buffer))) else Grabber.SetSize(0); dwTotalBytes := 0; SetGrabberStatus(gsGrabbing); if HasSize then begin dwBytesRead := 1; // Modified by David Tetard: while (dwBytesRead > 0) and not Terminated and {F}Continue do begin if not InternetReadFile(hDownload, @Buf, SizeOf(Buf), dwBytesRead) then dwBytesRead := 0 else begin Inc(dwTotalBytes, dwBytesRead); Grabber.SetBytesRead(dwTotalBytes); Grabber.Stream.Write(Buf, dwBytesRead); DoProgress; end; // Be CPU friendly. SleepEx(0, True); end; SetGrabberStatus(gsStopping); // Modified by David Tetard: if {F}Continue and not Terminated then Synchronize(Ended); end else begin while InternetReadFile(hDownload, @Buf, SizeOf(Buf), dwBytesRead) and not Terminated do begin if dwBytesRead = 0 then Break; Grabber.Stream.Write(Buf, dwBytesRead); Synchronize(UpdateGrabberProgress); // Be CPU friendly. SleepEx(0, True); end; SetGrabberStatus(gsStopping); // Modified by David Tetard: if {F}Continue and not Terminated then Synchronize(Ended); end; except end; finally // Free all stuff's if Buffer <> nil then FreeMem(Buffer); // Release all handles if (hDownload <> nil) and not InternetCloseHandle(hDownload) then begin ErrorText := GetLastInternetError; Synchronize(Error); end; if (hHostConnection <> nil) and not InternetCloseHandle(hHostConnection) then begin ErrorText := GetLastInternetError; Synchronize(Error); end; if (hSession <> nil) and not InternetCloseHandle(hSession) then begin ErrorText := GetLastInternetError; Synchronize(Error); end; end; end; | ||||
Tags | No tags attached. | ||||
Date Modified | Username | Field | Change |
---|---|---|---|
2011-11-24 09:32 | tetardd | New Issue | |
2012-02-22 14:50 | obones | Assigned To | => obones |
2012-02-22 14:50 | obones | Note Added: 0019445 | |
2012-02-22 14:50 | obones | Status | new => confirmed |
2012-02-23 09:37 | obones | Status | confirmed => resolved |
2012-02-23 09:37 | obones | Fixed in Version | => Daily / SVN |
2012-02-23 09:37 | obones | Resolution | open => fixed |
2012-09-10 14:15 | obones | Fixed in Version | Daily / SVN => 3.46 |