2015-02-11 3 views
2

Я пытаюсь загрузить файл с помощью indy10 http-компонентов TIdHttp при получении прогресса, я только что установил библиотеки в папке приложения, используя код для http-URL-адреса. работ и прогресс, но с HTTPS он просто ничего не делает, и это не вызывает каких-либо исключений:/Как загрузить файл с прогрессом с помощью IdHTTP через https

with TIdHTTP.Create(nil) do 
    begin 
    IOHndl:=TIdSSLIOHandlerSocketOpenSSL.Create(nil); 
    Request.BasicAuthentication:=True; 
    HandleRedirects:=True; 
    IOHandler:=IOHndl; 
    OnWork:=FOnWork; 
    OnWorkBegin:=FOnWorkBegin; 
    OnWorkEnd:=FOnWorkEnd; 
    Get(FUrl,FStream); 
end; 

с наилучшими пожеланиями

+0

Единственный раз, когда программа действительно «ничего не делает», когда она завершена. Используйте отладчик для приостановки вашей программы и просмотра стека вызовов. Это покажет вам, что действительно делает программа. –

+0

@RobKennedy, большинство людей знает, что он имеет в виду. И не нужно троллировать вопрос –

+0

Может быть, «большинство людей» знают, но я не знаю, @Jens. Здесь нам не нужны более неточные вопросы. Я указал, как это неточно, и дал совет, как это исправить. Если * вы знаете, то, может быть, вы можете объяснить мне: что делает программа * на самом деле? –

ответ

3

Сначала вы должны создать небольшой класс, чтобы обернуть компонент HTTP:

unit IdHTTPProgressU; 

interface 

uses 
    Classes, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdSSLOpenSSL; 

{$M+} 

type 
    TIdHTTPProgress = class(TIdHTTP) 
    private 
    FProgress: Integer; 
    FBytesToTransfer: Int64; 
    FOnChange: TNotifyEvent; 
    IOHndl: TIdSSLIOHandlerSocketOpenSSL; 
    procedure HTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); 
    procedure HTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); 
    procedure HTTPWorkEnd(Sender: TObject; AWorkMode: TWorkMode); 
    procedure SetProgress(const Value: Integer); 
    procedure SetOnChange(const Value: TNotifyEvent); 
    public 
    Constructor Create(AOwner: TComponent); 
    procedure DownloadFile(const aFileUrl: string; const aDestinationFile: String); 
    published 
    property Progress: Integer read FProgress write SetProgress; 
    property BytesToTransfer: Int64 read FBytesToTransfer; 
    property OnChange: TNotifyEvent read FOnChange write SetOnChange; 
    end; 

implementation 

uses 
    Sysutils; 
{ TIdHTTPProgress } 

constructor TIdHTTPProgress.Create(AOwner: TComponent); 
begin 
    inherited; 
    IOHndl := TIdSSLIOHandlerSocketOpenSSL.Create(nil); 
    Request.BasicAuthentication := True; 
    HandleRedirects := True; 
    IOHandler := IOHndl; 
    ReadTimeout := 30000; 
    OnWork := HTTPWork; 
    OnWorkBegin := HTTPWorkBegin; 
    OnWorkEnd := HTTPWorkEnd; 
end; 

procedure TIdHTTPProgress.DownloadFile(const aFileUrl: string; const aDestinationFile: String); 
var 
    LDestStream: TFileStream; 
    aPath: String; 
begin 
    Progress := 0; 
    FBytesToTransfer := 0; 
    aPath := ExtractFilePath(aDestinationFile); 
    if aPath <> '' then 
    ForceDirectories(aPath); 

    LDestStream := TFileStream.Create(aDestinationFile, fmCreate); 
    try 
    Get(aFileUrl, LDestStream); 
    finally 
    FreeAndNil(LDestStream); 
    end; 
end; 

procedure TIdHTTPProgress.HTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); 
begin 
    if BytesToTransfer = 0 then // No Update File 
    Exit; 

    Progress := Round((AWorkCount/BytesToTransfer) * 100); 
end; 

procedure TIdHTTPProgress.HTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); 
begin 
    FBytesToTransfer := AWorkCountMax; 
end; 

procedure TIdHTTPProgress.HTTPWorkEnd(Sender: TObject; AWorkMode: TWorkMode); 
begin 
    FBytesToTransfer := 0; 
    Progress := 100; 
end; 

procedure TIdHTTPProgress.SetOnChance(const Value: TNotifyEvent); 
begin 
    FOnChance := Value; 
end; 

procedure TIdHTTPProgress.SetProgress(const Value: Integer); 
begin 
    FProgress := Value; 
    if Assigned(FOnChance) then 
    FOnChance(Self); 
end; 

end. 

я не буду идти к детали с Calss: Просто сказать, что это bacally обертывания компонент TIdHTTP в и назначить 3 события: OnBegin, onWork и OnEnd

Метод DownloadFile ли на самом деле скачать,

Тогда когда вы должны использовать его, вы можете сделать следующее:
Поместите кнопку и PrograssBar в пустой форме. Добавьте IdHTTPProgressU в список использования.

Объявите vaiable из TIdHTTPProgress и местного onChangeEvent

Вашего определения формы должен Лекк так:

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    ProgressBar1: TProgressBar; 
    procedure FormCreate(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    private 
    procedure IdHTTPProgressOnChange(Sender : TObject); 
    public 
    IdHTTPProgress: TIdHTTPProgress; 
    end; 

Тогда вы просто должны реализовать методы:

{ TForm1 } 

    procedure TForm1.Button1Click(Sender: TObject); 
    begin 
     IdHTTPProgress.OnChange := IdHTTPProgressOnChance; 
      IdHTTPProgress.OnChance := IdHTTPProgressOnChance; 
    IdHTTPProgress.DownloadFile('https://wordpress.org/latest.zip', 'latest.zip'); 
    end; 

    procedure TForm1.FormCreate(Sender: TObject); 
    begin 
     IdHTTPProgress := TIdHTTPProgress.Create(Self); 
    end; 

    procedure TForm1.IdHTTPProgressOnChance(Sender: TObject); 
    begin 
     ProgressBar1.Position := TIdHTTPProgress(Sender).Progress; 
     Application.ProcessMessages; 
    end; 

То о Это. Дайте это при попытке.

+1

Что не так с кодом в вопросе? Ваш код не демонстрирует HTTPS; в вопросе говорится, что простой HTTP уже работает отлично, так что проблема в том, что ваш код действительно разрешен? (Кроме того, слово, которое вы хотите, - это * изменение *, а не * шанс *. Подробнее см. Словарь.) –

+0

@RobKennedy Я пропустил часть HTTPS, но не сделал различий. Теперь я добавил https, и мой пример работает stille. –