123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- {$mode objfpc}
- {$h+}
- unit pkglnet;
- interface
- uses
- SysUtils, Classes,
- uriparser,
- lnet, lftp, lhttp, pkgdownload,pkgoptions, fprepos;
- Type
- { TLNetDownloader }
- TLNetDownloader = Class(TBaseDownloader)
- private
- FQuit: Boolean;
- FFTP: TLFTPClient;
- FHTTP: TLHTTPClient;
- FOutStream: TStream;
- URI: TURI;
- protected
- // callbacks
- function OnHttpClientInput(ASocket: TLHTTPClientSocket; ABuffer: pchar;
- ASize: Integer): Integer;
- procedure OnLNetDisconnect(aSocket: TLSocket);
- procedure OnHttpDoneInput(aSocket: TLHTTPClientSocket);
- procedure OnLNetError(const msg: string; aSocket: TLSocket);
- procedure OnFTPControl(aSocket: TLSocket);
- procedure OnFTPReceive(aSocket: TLSocket);
- procedure OnFTPSuccess(aSocket: TLSocket; const aStatus: TLFTPStatus);
- procedure OnFTPFailure(aSocket: TLSocket; const aStatus: TLFTPStatus);
- // overrides
- function FTPDownload(Const URL : String; Dest : TStream): Boolean; override;
- function HTTPDownload(Const URL: String; Dest: TStream): Boolean; override;
- public
- constructor Create(AOwner : TComponent); override;
- end;
- implementation
- uses
- pkgglobals,
- pkgmessages;
- { TLNetDownloader }
- function TLNetDownloader.OnHttpClientInput(ASocket: TLHTTPClientSocket;
- ABuffer: pchar; ASize: Integer): Integer;
- begin
- Result:=FOutStream.Write(aBuffer[0], aSize);
- end;
- procedure TLNetDownloader.OnLNetDisconnect(aSocket: TLSocket);
- begin
- FQuit:=True;
- end;
- procedure TLNetDownloader.OnHttpDoneInput(aSocket: TLHTTPClientSocket);
- begin
- ASocket.Disconnect;
- FQuit:=True;
- end;
- procedure TLNetDownloader.OnLNetError(const msg: string; aSocket: TLSocket);
- begin
- Error(msg);
- FQuit:=True;
- end;
- procedure TLNetDownloader.OnFTPControl(aSocket: TLSocket);
- var
- s: string;
- begin
- FFTP.GetMessage(s); // have to empty OS buffer, write the info if you wish to debug
- end;
- procedure TLNetDownloader.OnFTPReceive(aSocket: TLSocket);
- const
- BUF_SIZE = 65536; // standard OS recv buffer size
- var
- Buf: array[1..BUF_SIZE] of Byte;
- begin
- FOutStream.Write(Buf[1], FFTP.GetData(Buf[1], BUF_SIZE));
- end;
- procedure TLNetDownloader.OnFTPSuccess(aSocket: TLSocket;
- const aStatus: TLFTPStatus);
- begin
- FFTP.Disconnect;
- FQuit:=True;
- end;
- procedure TLNetDownloader.OnFTPFailure(aSocket: TLSocket;
- const aStatus: TLFTPStatus);
- begin
- FFTP.Disconnect;
- Error(SErrDownloadFailed,['FTP',EncodeURI(URI),'']);
- FQuit:=True;
- end;
- function TLNetDownloader.FTPDownload(Const URL: String; Dest: TStream): Boolean;
- begin
- Result := False;
- FOutStream:=Dest;
- Try
- { parse URL }
- URI:=ParseURI(URL);
- if URI.Port = 0 then
- URI.Port := 21;
- FFTP.Connect(URI.Host, URI.Port);
- while not FFTP.Connected and not FQuit do
- FFTP.CallAction;
- if not FQuit then begin
- Result := FFTP.Authenticate(URI.Username, URI.Password);
- if Result then
- Result := FFTP.ChangeDirectory(URI.Path);
- if Result then
- Result := FFTP.Retrieve(URI.Document);
- while not FQuit do
- FFTP.CallAction;
- end;
- finally
- FOutStream:=nil;
- end;
- end;
- function TLNetDownloader.HTTPDownload(Const URL: String; Dest: TStream): Boolean;
- begin
- Result := False;
- FOutStream:=Dest;
- Try
- { parse aURL }
- URI := ParseURI(URL);
- if URI.Port = 0 then
- URI.Port := 80;
- FHTTP.Host := URI.Host;
- FHTTP.Method := hmGet;
- FHTTP.Port := URI.Port;
- FHTTP.URI := URI.Path + URI.Document;
- FHTTP.SendRequest;
- FQuit:=False;
- while not FQuit do
- FHTTP.CallAction;
- if FHTTP.Response.Status<>HSOK then
- Error(SErrDownloadFailed,['HTTP',EncodeURI(URI),FHTTP.Response.Reason])
- else
- Result := True;
- Finally
- FOutStream:=nil; // to be sure
- end;
- end;
- constructor TLNetDownloader.Create(AOwner: TComponent);
- begin
- inherited;
- FFTP:=TLFTPClient.Create(Self);
- FFTP.Timeout:=1000;
- FFTP.StatusSet:=[fsRetr]; // watch for success/failure of retreives only
- FFTP.OnError:=@OnLNetError;
- FFTP.OnControl:=@OnFTPControl;
- FFTP.OnReceive:=@OnFTPReceive;
- FFTP.OnSuccess:=@OnFTPSuccess;
- FFTP.OnFailure:=@OnFTPFailure;
- FHTTP:=TLHTTPClient.Create(Self);
- FHTTP.Timeout := 1000; // go by 1s times if nothing happens
- FHTTP.OnDisconnect := @OnLNetDisconnect;
- FHTTP.OnDoneInput := @OnHttpDoneInput;
- FHTTP.OnError := @OnLNetError;
- FHTTP.OnInput := @OnHttpClientInput;
- end;
- initialization
- RegisterDownloader('lnet',TLNetDownloader);
- end.
|