View Issue Details

IDProjectCategoryView StatusLast Update
0005719JEDI VCL00 JVCL Componentspublic2012-09-10 14:15
ReportertetarddAssigned Toobones 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.45 
Target VersionFixed in Version3.46 
Summary0005719: TJvHttpUrlGrabberThread should not have FContinue private variable
DescriptionTJvHttpUrlGrabberThread = 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 InformationThis 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;
TagsNo tags attached.

Activities

obones

2012-02-22 14:50

administrator   ~0019445

Yeah, I noticed that too, must fix

Issue History

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