unit Unit_Download_Url;
interface
uses
Winapi.Windows,
Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.StdCtrls, VCLTee.TeCanvas,
Vcl.Buttons, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
IdHTTP, IdSSLOpenSSL, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL;
type
TForm1 =
class(TForm)
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
SpeedButton3: TSpeedButton;
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
//******************************************************************************
implementation
{$R *.dfm}
type
THTTPFileDownload =
class(TIdHTTP)
private
FProgress: Integer;
FWorkCount, FBytesTransfered, FBytesToTransfer, FBytesTransferedEnd: Int64;
FOnChange, FOnEnd: TNotifyEvent;
IOHndl: TIdSSLIOHandlerSocketOpenSSL;
procedure ResetVars;
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);
procedure SetOnEnd(
const Value: TNotifyEvent);
public
constructor Create(AOwner: TComponent);
destructor Destroy;
override;
function DownloadFile(
const aFileUrl:
string;
const aDestinationFile:
string): Boolean;
property Progress: Integer
read FProgress
write SetProgress;
property WorkCount: Int64
read FWorkCount
write FWorkCount;
property BytesTransfered: Int64
read FBytesTransfered
write FBytesTransfered;
property BytesTransferedEnd: Int64
read FBytesTransferedEnd
write FBytesTransferedEnd;
property BytesToTransfer: Int64
read FBytesToTransfer;
property OnChange: TNotifyEvent
read FOnChange
write SetOnChange;
property OnEnd: TNotifyEvent
read FOnEnd
write SetOnEnd;
end;
//******************************************************************************
constructor THTTPFileDownload.Create(AOwner: TComponent);
begin
inherited;
IOHndl := TIdSSLIOHandlerSocketOpenSSL.Create(
nil);
Request.BasicAuthentication := True;
HandleRedirects := True;
IOHandler := IOHndl;
ReadTimeout := 3000;
ConnectTimeout := 3000;
IOHndl.ReadTimeout := 3000;
IOHndl.ConnectTimeout := 3000;
OnWork := HTTPWork;
OnWorkBegin := HTTPWorkBegin;
OnWorkEnd := HTTPWorkEnd;
end;
destructor THTTPFileDownload.Destroy;
begin
IOHndl.Free;
inherited;
end;
procedure THTTPFileDownload.ResetVars;
begin
Progress := 0;
FWorkCount := 0;
FBytesToTransfer := 0;
FBytesTransfered := 0;
end;
function THTTPFileDownload.DownloadFile(
const aFileUrl:
string;
const aDestinationFile:
string): Boolean;
var
LDestStream: TFileStream;
aPath:
string;
begin
try
ResetVars;
aPath := ExtractFilePath(aDestinationFile);
if aPath <> '
'
then
ForceDirectories(aPath);
LDestStream := TFileStream.Create(aDestinationFile, fmCreate);
try
Get(aFileUrl, LDestStream);
Result := True;
finally
FreeAndNil(LDestStream);
end;
except
Result := False;
end;
end;
procedure THTTPFileDownload.HTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
begin
if BytesToTransfer = 0
then // No Update File
Exit;
WorkCount := AWorkCount;
Progress := Round((AWorkCount / BytesToTransfer) * 100);
BytesTransfered := (BytesToTransfer
div 100) * Progress;
end;
procedure THTTPFileDownload.HTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64);
begin
FBytesToTransfer := AWorkCountMax;
end;
procedure THTTPFileDownload.HTTPWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
FBytesTransferedEnd := FBytesTransfered;
if Assigned(FOnEnd)
then
FOnEnd(Self);
FWorkCount := 0;
FBytesToTransfer := 0;
ResetVars;
Progress := 100;
end;
procedure THTTPFileDownload.SetOnChange(
const Value: TNotifyEvent);
begin
FOnChange := Value;
end;
procedure THTTPFileDownload.SetOnEnd(
const Value: TNotifyEvent);
begin
FOnEnd := Value;
end;
procedure THTTPFileDownload.SetProgress(
const Value: Integer);
begin
FProgress := Value;
if Assigned(FOnChange)
then
FOnChange(Self);
end;
//******************************************************************************
//******************************************************************************
procedure TForm1.SpeedButton1Click(Sender: TObject);
// forciert TSL 1.2
var
DL: THTTPFileDownload;
begin
DL := THTTPFileDownload.Create(
nil);
try
DL.IOHndl.SSLOptions.SSLVersions := [sslvTLSv1_2];
// erzwingt TSL-Protokoll 1.2
DL.DownloadFile('
https://www.delphipraxis.net/','
C:\Termin\xxx.pdf');
// das geht vermutlich, es kommt jedenfalls keine Fehlermeldung,
// doch was genau passiert liegt im Nebel und debuggen würde zu lange dauern,
// weil ich pdf Files in der VM nicht mit Doppelklick öffnen kann.
DL.DownloadFile('
https://....Link.pdf','
C:\Termin\xxx.pdf');
// => zeigt auf meine Datei im Internet
// ---------------------------
//Benachrichtigung über Debugger-Exception
//---------------------------
//Im Projekt Project_Download_Url.exe ist eine Exception der Klasse EIdHTTPProtocolException mit der Meldung 'HTTP/1.1 500 Internal Server Error' aufgetreten.
//---------------------------
//Anhalten Fortsetzen Hilfe
//---------------------------
finally
DL.Free;
end;
end;
//******************************************************************************
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
ShowMessage(idHTTP1.Get('
https://192.124.249.57/documents/shared/margins/margins.pdf'));
// ---------------------------
//Benachrichtigung über Debugger-Exception
//---------------------------
//Im Projekt Project_Download_Url.exe ist eine Exception der Klasse EIdOSSLUnderlyingCryptoError mit der Meldung 'Fehler beim Verbinden mit SSL.
//error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version' aufgetreten.
//---------------------------
//Anhalten Fortsetzen Hilfe
//---------------------------
// gefolgt von
//---------------------------
//Project_download_url
//---------------------------
//Fehler beim Verbinden mit SSL.//
//error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version.
//---------------------------
//OK
//---------------------------
end;
end.