views:

688

answers:

1

I need a way to download a file from the Internet using Delphi via HTTP, Wich include an Progress event , I'm looking for a method wich uses the Indy components.

I am using Delphi 7.

Thanks in advance.

+5  A: 

I've coded this example, using just one HTTP GET, with Indy 10, hope it works with Indy 9 too:

uses
  {...} IdHTTP, IdComponent;

type
  TFormMain = class(TForm)
    {...}
  private
    {...}
    procedure HttpWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
  end;
{...}

procedure TFormMain.Button1Click(Sender: TObject);
var
  Http: TIdHTTP;
  MS: TMemoryStream;
begin
  Http := TIdHTTP.Create(nil);
  try
    MS := TMemoryStream.Create;
    try
      Http.OnWork:= HttpWork;

      Http.Get('http://live.sysinternals.com/ADExplorer.exe', MS);
      MS.SaveToFile('C:\ADExplorer.exe');

    finally
      MS.Free;
    end;
  finally
    Http.Free;
  end;
end;

procedure TFormMain.HttpWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
var
  Http: TIdHTTP;
  ContentLength: Int64;
  Percent: Integer;
begin
  Http := TIdHTTP(ASender);
  ContentLength := Http.Response.ContentLength;

  if (Pos('chunked', LowerCase(Http.Response.TransferEncoding)) = 0) and
     (ContentLength > 0) then
  begin
    Percent := 100*AWorkCount div ContentLength;

    MemoOutput.Lines.Add(IntToStr(Percent));
  end;
end;
ulrichb
The Response.ContentLength value is not always valid. In particular, in HTTP 1.1 replies that use the "chunked" transfer encoding, the "Content-Length" header is not allowed to be used. During chunked transfers, the total size of the data is not known ahead of time, as the data is transmitted in multiple blocks, and each block has its own size internally.
Remy Lebeau - TeamB
Better? Now I use exactly the same conditions as in `TIdCustomHTTP.ReadResult()` inside the `IdHTTP.pas` unit
ulrichb