pkglnet.pp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. {$mode objfpc}
  2. {$h+}
  3. unit pkglnet;
  4. interface
  5. uses
  6. SysUtils, Classes,
  7. lnet, lftp, lhttp, pkgdownload,pkgoptions, fprepos;
  8. Type
  9. { TLNetDownloader }
  10. TLNetDownloader = Class(TBaseDownloader)
  11. private
  12. FQuit: Boolean;
  13. FFTP: TLFTPClient;
  14. FHTTP: TLHTTPClient;
  15. FOutStream: TStream;
  16. protected
  17. // callbacks
  18. function OnHttpClientInput(ASocket: TLHTTPClientSocket; ABuffer: pchar;
  19. ASize: Integer): Integer;
  20. procedure OnLNetDisconnect(aSocket: TLSocket);
  21. procedure OnHttpDoneInput(aSocket: TLHTTPClientSocket);
  22. procedure OnLNetError(const msg: string; aSocket: TLSocket);
  23. procedure OnFTPControl(aSocket: TLSocket);
  24. procedure OnFTPReceive(aSocket: TLSocket);
  25. procedure OnFTPSuccess(aSocket: TLSocket; const aStatus: TLFTPStatus);
  26. procedure OnFTPFailure(aSocket: TLSocket; const aStatus: TLFTPStatus);
  27. // overrides
  28. procedure FTPDownload(Const URL : String; Dest : TStream); override;
  29. procedure HTTPDownload(Const URL : String; Dest : TStream); override;
  30. public
  31. constructor Create(AOwner : TComponent); override;
  32. end;
  33. implementation
  34. uses
  35. uriparser,
  36. pkgglobals,
  37. pkgmessages;
  38. { TLNetDownloader }
  39. function TLNetDownloader.OnHttpClientInput(ASocket: TLHTTPClientSocket;
  40. ABuffer: pchar; ASize: Integer): Integer;
  41. begin
  42. Result:=FOutStream.Write(aBuffer[0], aSize);
  43. end;
  44. procedure TLNetDownloader.OnLNetDisconnect(aSocket: TLSocket);
  45. begin
  46. FQuit:=True;
  47. end;
  48. procedure TLNetDownloader.OnHttpDoneInput(aSocket: TLHTTPClientSocket);
  49. begin
  50. ASocket.Disconnect;
  51. FQuit:=True;
  52. end;
  53. procedure TLNetDownloader.OnLNetError(const msg: string; aSocket: TLSocket);
  54. begin
  55. Error(msg);
  56. FQuit:=True;
  57. end;
  58. procedure TLNetDownloader.OnFTPControl(aSocket: TLSocket);
  59. var
  60. s: string;
  61. begin
  62. FFTP.GetMessage(s); // have to empty OS buffer, write the info if you wish to debug
  63. end;
  64. procedure TLNetDownloader.OnFTPReceive(aSocket: TLSocket);
  65. const
  66. BUF_SIZE = 65536; // standard OS recv buffer size
  67. var
  68. Buf: array[1..BUF_SIZE] of Byte;
  69. begin
  70. FOutStream.Write(Buf[1], FFTP.GetData(Buf[1], BUF_SIZE));
  71. end;
  72. procedure TLNetDownloader.OnFTPSuccess(aSocket: TLSocket;
  73. const aStatus: TLFTPStatus);
  74. begin
  75. FFTP.Disconnect;
  76. FQuit:=True;
  77. end;
  78. procedure TLNetDownloader.OnFTPFailure(aSocket: TLSocket;
  79. const aStatus: TLFTPStatus);
  80. begin
  81. FFTP.Disconnect;
  82. Error('Retrieve failed');
  83. FQuit:=True;
  84. end;
  85. procedure TLNetDownloader.FTPDownload(const URL: String; Dest: TStream);
  86. var
  87. URI: TURI;
  88. begin
  89. FOutStream:=Dest;
  90. Try
  91. { parse URL }
  92. URI:=ParseURI(URL);
  93. if URI.Port = 0 then
  94. URI.Port := 21;
  95. FFTP.Connect(URI.Host, URI.Port);
  96. while not FFTP.Connected and not FQuit do
  97. FFTP.CallAction;
  98. if not FQuit then begin
  99. FFTP.Authenticate(URI.Username, URI.Password);
  100. FFTP.ChangeDirectory(URI.Path);
  101. FFTP.Retrieve(URI.Document);
  102. while not FQuit do
  103. FFTP.CallAction;
  104. end;
  105. finally
  106. FOutStream:=nil;
  107. end;
  108. end;
  109. procedure TLNetDownloader.HTTPDownload(const URL: String; Dest: TStream);
  110. var
  111. URI: TURI;
  112. begin
  113. FOutStream:=Dest;
  114. Try
  115. { parse aURL }
  116. URI := ParseURI(URL);
  117. if URI.Port = 0 then
  118. URI.Port := 80;
  119. FHTTP.Host := URI.Host;
  120. FHTTP.Method := hmGet;
  121. FHTTP.Port := URI.Port;
  122. FHTTP.URI := '/' + URI.Document;
  123. FHTTP.SendRequest;
  124. FQuit:=False;
  125. while not FQuit do
  126. FHTTP.CallAction;
  127. Finally
  128. FOutStream:=nil; // to be sure
  129. end;
  130. end;
  131. constructor TLNetDownloader.Create(AOwner: TComponent);
  132. begin
  133. inherited;
  134. FFTP:=TLFTPClient.Create(Self);
  135. FFTP.Timeout:=1000;
  136. FFTP.StatusSet:=[fsRetr]; // watch for success/failure of retreives only
  137. FFTP.OnError:=@OnLNetError;
  138. FFTP.OnControl:=@OnFTPControl;
  139. FFTP.OnReceive:=@OnFTPReceive;
  140. FFTP.OnSuccess:=@OnFTPSuccess;
  141. FFTP.OnFailure:=@OnFTPFailure;
  142. FHTTP:=TLHTTPClient.Create(Self);
  143. FHTTP.Timeout := 1000; // go by 1s times if nothing happens
  144. FHTTP.OnDisconnect := @OnLNetDisconnect;
  145. FHTTP.OnDoneInput := @OnHttpDoneInput;
  146. FHTTP.OnError := @OnLNetError;
  147. FHTTP.OnInput := @OnHttpClientInput;
  148. end;
  149. initialization
  150. DownloaderClass:=TLNetDownloader;
  151. end.