mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 01:01:05 +01:00 
			
		
		
		
	* ignore errors in initial download * fixed crash with selecting mirror without doing an update git-svn-id: trunk@10076 -
		
			
				
	
	
		
			179 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{$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
 | 
						|
    procedure FTPDownload(Const URL : String; Dest : TStream); override;
 | 
						|
    procedure HTTPDownload(Const URL : String; Dest : TStream); 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;
 | 
						|
 | 
						|
procedure TLNetDownloader.FTPDownload(const URL: String; Dest: TStream);
 | 
						|
begin
 | 
						|
  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
 | 
						|
      FFTP.Authenticate(URI.Username, URI.Password);
 | 
						|
      FFTP.ChangeDirectory(URI.Path);
 | 
						|
      FFTP.Retrieve(URI.Document);
 | 
						|
      while not FQuit do
 | 
						|
        FFTP.CallAction;
 | 
						|
    end;
 | 
						|
  finally
 | 
						|
    FOutStream:=nil;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TLNetDownloader.HTTPDownload(const URL: String; Dest: TStream);
 | 
						|
begin
 | 
						|
  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]);
 | 
						|
  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.
 |