mirror of
https://bitbucket.org/Dennis07/lina-components.git
synced 2024-11-24 08:02:12 +02:00
1c2743e97b
Signed-off-by: Dennis07 <den.goehlert@t-online.de>
351 lines
8.9 KiB
ObjectPascal
351 lines
8.9 KiB
ObjectPascal
unit uWebCtrls;
|
|
|
|
//////////////////////////////////////
|
|
/// Lina Web Controls Unit ///
|
|
/// **************************** ///
|
|
/// (c) 2014 Dennis Göhlert a.o. ///
|
|
//////////////////////////////////////
|
|
|
|
interface
|
|
|
|
uses
|
|
{ Standard-Units }
|
|
SysUtils, Classes,
|
|
{ Indy-Units }
|
|
idHTTP, idSSLOpenSSL, idComponent,
|
|
{ Andere Package-Units }
|
|
uBase, uSysTools;
|
|
|
|
type
|
|
{ Fehlermeldungen }
|
|
EInvalidWebAddress = class(Exception);
|
|
|
|
type
|
|
{ Ereignisse }
|
|
TDownloadWorkEvent = procedure(Sender: TObject; AWorkMode: TWorkMode) of object;
|
|
TDownloadWorkBeginEvent = procedure(Sender: TObject; AWorkMode: TWorkMode) of object;
|
|
TDownloadWorkEndEvent = procedure(Sender: TObject; AWorkMode: TWorkMode) of object;
|
|
|
|
type
|
|
{ Hilfsklassen }
|
|
TWebProtocol = String[8];
|
|
TWebProtocols = array[1..5] of TWebProtocol;
|
|
|
|
type
|
|
{ Hauptklassen }
|
|
TDownload = class(TComponent)
|
|
private
|
|
{ Private-Deklarationen }
|
|
idHTTPObject: TidHTTP;
|
|
SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
|
|
FAbout: TComponentAbout;
|
|
FAddress: String;
|
|
FProgress: Int64;
|
|
FProgressMax: Int64;
|
|
FSSL: Boolean;
|
|
{ Ereignisse }
|
|
FWorkEvent: TDownloadWorkEvent;
|
|
FWorkBeginEvent: TDownloadWorkBeginEvent;
|
|
FWorkEndEvent: TDownloadWorkEndEvent;
|
|
{ Methoden }
|
|
procedure SetAddress(Value: String);
|
|
procedure idHTTPObjectWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
|
|
procedure idHTTPObjectWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64);
|
|
procedure idHTTPObjectWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
|
|
protected
|
|
{ Protected-Deklarationen }
|
|
procedure Prepare;
|
|
public
|
|
{ Public-Deklarationen }
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
{ Fortschritt }
|
|
function GetProgress: Int64;
|
|
function GetProgressMax: Int64;
|
|
function GetProgressPercent: Byte;
|
|
{ Herunterladen }
|
|
function GetText: String;
|
|
procedure SaveToFile(const FileName: TFileName);
|
|
procedure SaveToStream(var Stream: TStream);
|
|
published
|
|
{ Published-Deklarationen }
|
|
{ Ereignisse }
|
|
property OnWork: TDownloadWorkEvent read FWorkEvent write FWorkEvent;
|
|
property OnWorkBegin: TDownloadWorkBeginEvent read FWorkBeginEvent write FWorkBeginEvent;
|
|
property OnWorkEnd: TDownloadWorkEndEvent read FWorkEndEvent write FWorkEndEvent;
|
|
{ Eigenschaften }
|
|
property About: TComponentAbout read FAbout;
|
|
property Address: String read FAddress write SetAddress;
|
|
property SSL: Boolean read FSSL write FSSL default False;
|
|
end;
|
|
|
|
var
|
|
WebProtocols: TWebProtocols;
|
|
WebProtocolsSimple: TWebProtocols;
|
|
WebProtocolsSpecial: TWebProtocols;
|
|
|
|
procedure InitializeProtocols;
|
|
function ValidProtocol(const Protocol: TWebProtocol; const Protocols: TWebProtocols): Boolean;
|
|
function StrIsURL(const S: String): Boolean;
|
|
|
|
procedure Register;
|
|
|
|
const
|
|
{ Web-Protokolle }
|
|
WP_HTTP: TWebProtocol = 'http://';
|
|
WP_HTTPS: TWebProtocol = 'https://';
|
|
WP_FTP: TWebProtocol = 'ftp://';
|
|
WP_CALL: TWebProtocol = 'callto:';
|
|
WP_MAIL: TWebProtocol = 'mailto:';
|
|
{ Meta-Daten }
|
|
DownloadComponent_Name = 'Download';
|
|
DownloadComponent_Version = 1.0;
|
|
DownloadComponent_Copyright = 'Copyright © 2014';
|
|
DownloadComponent_Author = 'Dennis Göhlert a.o.';
|
|
|
|
implementation
|
|
|
|
procedure Register;
|
|
begin
|
|
RegisterComponents(ComponentsPage,[TDownload]);
|
|
end;
|
|
|
|
procedure InitializeProtocols;
|
|
begin
|
|
WebProtocols[1] := WP_HTTP;
|
|
WebProtocols[2] := WP_HTTPS;
|
|
WebProtocols[3] := WP_FTP;
|
|
WebProtocols[4] := WP_CALL;
|
|
WebProtocols[5] := WP_MAIL;
|
|
WebProtocolsSimple[1] := WP_MAIL;
|
|
WebProtocolsSimple[2] := WP_CALL;
|
|
WebProtocolsSpecial[1] := WP_HTTP;
|
|
WebProtocolsSpecial[2] := WP_HTTPS;
|
|
WebProtocolsSpecial[3] := WP_FTP;
|
|
end;
|
|
|
|
function ValidProtocol(const Protocol: TWebProtocol;
|
|
const Protocols: TWebProtocols): Boolean;
|
|
var
|
|
Index: 1..5;
|
|
begin
|
|
InitializeProtocols;
|
|
Result := False;
|
|
for Index := Low(Protocols) to High(Protocols) do
|
|
begin
|
|
if Protocols[Index] = Protocol then
|
|
begin
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function StrIsURL(const S: String): Boolean;
|
|
{ Ein einfacher (iterativer) Parser, der überprüfen soll, ob ein String die
|
|
Anforderungen an eine URL-Internetadresse erfüllt.
|
|
Hier sei gesagt, dass dies KEINE vollständige Prüfung ist, sondern nur die
|
|
wichtigsten Kriterien beinhaltet.
|
|
Außerdem wird auch nicht überprüft, ob eine Adresse verfügbar ist. }
|
|
const
|
|
//Diese Zeichen sind zwar erlaubt, dürfen jedoch nicht doppelt hintereinander vorkommen
|
|
InvalidDoubleChars = [':','.'];
|
|
var
|
|
Index: Integer;
|
|
DomainLength: Integer;
|
|
Protocol: TWebProtocol;
|
|
ProtocolValid: Boolean;
|
|
DoubleSlashRequired: Boolean;
|
|
begin
|
|
Result := True;
|
|
ProtocolValid := False;
|
|
DoubleSlashRequired := False;
|
|
DomainLength := 0;
|
|
Protocol := '';
|
|
for Index := 1 to Length(S) do
|
|
begin
|
|
if (S[Index] in InvalidDoubleChars) and
|
|
(S[Index] = S[Index - 1]) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
if (S[Index] in Spaces) or
|
|
((S[Index] = ':') and (ProtocolValid = True)) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
if ProtocolValid = False then
|
|
begin
|
|
Protocol := Protocol + S[Index];
|
|
if S[Index] = ':' then
|
|
begin
|
|
ProtocolValid := True;
|
|
if ValidProtocol(Protocol,WebProtocolsSimple) = False then
|
|
begin
|
|
DoubleSlashRequired := True;
|
|
Continue;
|
|
end;
|
|
end;
|
|
if S[Index] = '/' then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
end else
|
|
begin
|
|
if S[Index] = '/' then
|
|
begin
|
|
if DoubleSlashRequired = True then
|
|
begin
|
|
Protocol := Protocol + S[Index];
|
|
DoubleSlashRequired := False;
|
|
end else
|
|
begin
|
|
if S[Index - 1] = '/' then
|
|
begin
|
|
if ValidProtocol(Protocol + S[Index],WebProtocolsSpecial) = False then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end else
|
|
begin
|
|
Protocol := Protocol + S[Index];
|
|
end;
|
|
end;
|
|
end;
|
|
end else
|
|
begin
|
|
if (DoubleSlashRequired = True) or ((S[Index - 1] = '/') and (S[Index - 2] <> '/') and (DomainLength = 0)) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end else
|
|
begin
|
|
DomainLength := DomainLength + 1;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
Result := (ProtocolValid and (DomainLength > 3));
|
|
end;
|
|
|
|
constructor TDownload.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
FAbout := TComponentAbout.Create(DownloadComponent_Name,DownloadComponent_Version,DownloadComponent_Copyright,DownloadComponent_Author);
|
|
idHTTPObject := TidHTTP.Create(Self);
|
|
idHTTPObject.HandleRedirects := True;
|
|
idHTTPObject.OnWork := idHTTPObjectWork;
|
|
idHTTPObject.OnWorkBegin := idHTTPObjectWorkBegin;
|
|
idHTTPObject.OnWorkEnd := idHTTPObjectWorkEnd;
|
|
SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(Self);
|
|
SSL := False;
|
|
end;
|
|
|
|
destructor TDownload.Destroy;
|
|
begin
|
|
FAbout.Free;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TDownload.SetAddress(Value: String);
|
|
begin
|
|
if (StrIsURL(Value) = True) or (Length(Value) = 0) then
|
|
begin
|
|
FAddress := Value;
|
|
end else
|
|
begin
|
|
raise EInvalidWebAddress.Create('"' + Value + '" is not a valid URL address');
|
|
end;
|
|
end;
|
|
|
|
procedure TDownload.idHTTPObjectWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
|
|
begin
|
|
FProgress := AWorkCount;
|
|
if Assigned(OnWork) then
|
|
begin
|
|
OnWork(Self,AWorkMode);
|
|
end;
|
|
end;
|
|
|
|
procedure TDownload.idHTTPObjectWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64);
|
|
begin
|
|
FProgressMax := AWorkCountMax;
|
|
if Assigned(OnWorkBegin) then
|
|
begin
|
|
OnWorkBegin(Self,AWorkMode);
|
|
end;
|
|
end;
|
|
|
|
procedure TDownload.idHTTPObjectWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
|
|
begin
|
|
if Assigned(OnWorkEnd) then
|
|
begin
|
|
OnWorkEnd(Self,AWorkMode);
|
|
end;
|
|
end;
|
|
|
|
function TDownload.GetProgress: Int64;
|
|
begin
|
|
Result := FProgress;
|
|
end;
|
|
|
|
function TDownload.GetProgressMax: Int64;
|
|
begin
|
|
Result := FProgressMax;
|
|
end;
|
|
|
|
function TDownload.GetProgressPercent: Byte;
|
|
begin
|
|
if FProgressMax > 0 then
|
|
begin
|
|
Result := (FProgress div FProgressMax) * 100;
|
|
end else
|
|
begin
|
|
{ Bei aktivierter SSL-Verschlüsselung wird keine insgesamte Dateigröße
|
|
übermittelt. Deshalb wird hier eine 0 angegeben, um das Ergebnis nicht
|
|
undefiniert zu lassen. }
|
|
Result := 0;
|
|
end;
|
|
end;
|
|
|
|
function TDownload.GetText: String;
|
|
begin
|
|
Prepare;
|
|
Result := idHTTPObject.Get(Address);
|
|
end;
|
|
|
|
procedure TDownload.SaveToFile(const FileName: TFileName);
|
|
var
|
|
FS: TFileStream;
|
|
begin
|
|
Prepare;
|
|
FS := TFileStream.Create(FileName,fmCreate or fmShareDenyWrite);
|
|
try
|
|
idHTTPObject.Get(Address,FS);
|
|
finally
|
|
FS.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TDownload.SaveToStream(var Stream: TStream);
|
|
begin
|
|
Prepare;
|
|
idHTTPObject.Get(Address,Stream);
|
|
end;
|
|
|
|
procedure TDownload.Prepare;
|
|
begin
|
|
if SSL = True then
|
|
begin
|
|
idHTTPObject.IOHandler := SSLHandler;
|
|
end else
|
|
begin
|
|
idHTTPObject := nil;
|
|
end;
|
|
end;
|
|
|
|
end.
|