How to download files using just my Lazarus application? lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Jvan · 2021-03-05 19:24 The server generate a file and a URL to download it. What I need is my Lazarus app downloading that file into a a folder selected by the user. Thanks. ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-05 19:57 Hi Jvan, Under the fcl-web package you have have fphttpclient. There's an example on how to use it on the wiki: fphttpclient If you don't mind adding third party code, there's also Synapse which you can install via the Online Package Manager Cheers, Gus ---------------------------------------------------------------------- Remy Lebeau · 2021-03-05 19:58 Quote from: gcarreno on March 05, 2021, 08:57:21 pmIf you don't mind adding third party code, there's also Synapse which you can install via the Online Package Manager Or Indy, which is also in the OPM, and has an HTTP client. ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-05 20:10 Hi Remy, Don't ask me why, but I never liked Indy. I guess I got too used to Synapse and now that FPC has fphhtpclient, I'm investing it it just because you can ditch third party's. Cheers, Gus ---------------------------------------------------------------------- balazsszekely · 2021-03-05 20:55 @gcarreno QuoteDon't ask me why, but I never liked Indy.Indy it's a good alternative. I have a client-server application running for years, I never had any issues whatsoever. ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-05 21:10 Hey GetMem, Quote from: GetMem on March 05, 2021, 09:55:04 pmIndy it's a good alternative. I have a client-server application running for years, I never had any issues whatsoever. Don't get me wrong, I never said it was bad or inefficient or anything degrading to it's performance. I was just stating an opinion. And, also, why I left it out. Maybe I shouldn't, but I did and I'm sorry. Cheers, Gus ---------------------------------------------------------------------- Remy Lebeau · 2021-03-05 23:19 Quote from: gcarreno on March 05, 2021, 09:10:15 pmDon't ask me why, but I never liked Indy. To each their own.  Some people love it, some people hate it.  It is not for everyone.  But the option is available. ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-05 23:52 Hi Remy Quote from: Remy Lebeau on March 06, 2021, 12:19:06 amBut the option is available. Absolutely and again, totally mea culpa for not mentioning it  Cheers, Gus ---------------------------------------------------------------------- Jvan · 2021-03-23 00:41 Quote from: gcarreno on March 06, 2021, 12:52:03 amHi Remy Quote from: Remy Lebeau on March 06, 2021, 12:19:06 amBut the option is available. Absolutely and again, totally mea culpa for not mentioning it  Cheers, Gus I have a problem with a exception message. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,  fphttpclient,  fpopenssl,  openssl; type   { TForm1 }   TForm1 = class(TForm)    Button1: TButton;    edtDescargarDe: TEdit;    edtGuardarEn: TEdit;    Label1: TLabel;    Label2: TLabel;    procedure Button1Click(Sender: TObject);  private   public   end; var  Form1: TForm1;  Client: TFPHttpClient;  FS: TStream;  SL: TStringList; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject);var  vFilename: String;  vDownloadFrom: String;begin       vFilename := edtGuardarEn.Text;  //'DESCARGAR_FILE.docx'  vDownloadFrom := edtDescargarDe.Text;  InitSSLInterface;  Client := TFPHttpClient.Create(nil);  FS := TFileStream.Create(vFilename, fmCreate or fmOpenWrite);  try    try      { Allow redirections }    Client.AllowRedirect := true;      Client.Get(vDownloadFrom, vFilename);    except      on E: EHttpClient do        ShowMessage(E.Message)      else        raise;    end;  finally    FS.Free;    Client.Free;    ShowMessage('OK');  end;end; end. The file that I wanto to download was created, but it is empty. ---------------------------------------------------------------------- lucamar · 2021-03-23 00:48 Since it is a docx file, that's probably your antivirus kicking in to check that it has no macro virus and locking it while trying to do it. Though I might be completely wrong ... Just to make sure: your local server won't be looking for the file at exactly that location, will it? ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-23 01:56 Hey Jvan, Quote from: Jvan on March 23, 2021, 01:41:33 amI have a problem with a exception message. Ok, first make sure that you have no problem with the Anti-Virus, like @Lucamar said. Then you'll have to tell me what version of FPC(Specifically FPC) you're using. There's been some changes from 3.0.4 to 3.2.0 that need to be addressed with some well placed {$IFDEF} mainly because of SLL and the wiki page is not correct. I still need to contribute to that. I have a working version, both on 3.0.4 and 3.2.0 and with macOS(somebody had some problem on macOS due to library versions changing on Big Sur and I think my code solved it), on a private project that I can share if you want to. Cheers, Gus ---------------------------------------------------------------------- balazsszekely · 2021-03-23 05:27 @Jvan Just replace Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  Client.Get(vDownloadFrom, vFilename);with Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Client.Get(vDownloadFrom, fs); ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-23 06:18 Hi GetMem, Quote from: GetMem on March 23, 2021, 06:27:24 am@Jvan Just replace Yes he does create the TFileStream and never uses it(but Free's it at the end), but the Get() has 2 overloads, one with Filename: String and another with Filestream: TFileStream. So syntactically and logically the code snippet is correct. But HAAAA, the file is opened by the TFileStream, Open/Written/Closed by the Get() and then Closed on the FS.Free(). That could mess some of the things!!! @JVan: Please correct that unfortunate sequence of events, by either removing all code pertaining to FS, or just replace stuff like @GetMem said. If after that you still have issues, I'll share my code that is safe across FPC 3.0.4/3.2.0. Cheers, Gus ---------------------------------------------------------------------- alaa123456789 · 2021-03-23 16:50 https://youtu.be/O4Mj76O1-SQ ---------------------------------------------------------------------- Handoko · 2021-03-23 16:56 That's great. Nice to see Lazarus tutorials in videos. I'm waiting for you next videos. Thank you for creating the video tutorial. ---------------------------------------------------------------------- BSaidus · 2021-03-23 16:56 Quote from: gcarreno on March 05, 2021, 09:10:15 pmDon't ask me why, but I never liked Indy. Hi @gcarreno I can certify you that Indy is the best package, library, for internet working for Lazarus/Delphi. I've never seen such library like Indy. Thanks to Remy for maintening it. ---------------------------------------------------------------------- Handoko · 2021-03-23 17:04 Yes, Indy is great. I tried lNet to do FTP download. I liked the name suggests, lightweight. Unfortunately, not sure what I did wrong, not always but I found it sometimes stopped downloading before finished. I changed the code to use Indy, it worked perfectly on the first attempt. Thank you the Indy team. ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-23 23:51 Hi alaa123456789, I welcome the fact that you have a very good tutorial on how to use curl, wget and the URLMon thing(I was unaware it's a unit, I'll have to find it and look at it)!! But it's a tad off topic since the OP is using fp-web and your suggestion is to add external dependencies on executables apart from the SSL *.dlls. I'm glad you could show your work, but it really doesn't solve his initial problem. Cheers, Gus ---------------------------------------------------------------------- Blade · 2021-03-24 00:25 Quote from: alaa123456789 on March 23, 2021, 05:50:33 pmhttps://youtu.be/O4Mj76O1-SQ Great videos.  Please do make more. ---------------------------------------------------------------------- Blade · 2021-03-24 00:40 Quote from: Handoko on March 23, 2021, 06:04:35 pmYes, Indy is great. I tried lNet to do FTP download. I liked the name suggests, lightweight. Unfortunately, not sure what I did wrong, not always but I found it sometimes stopped downloading before finished. I changed the code to use Indy, it worked perfectly on the first attempt. Thank you the Indy team. Your endorsement got me to try it too.  Yes, it does work well. ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-24 00:51 Hi BSaidus, Quote from: BSaidus on March 23, 2021, 05:56:56 pmHi @gcarreno I can certify you that Indy is the best package, library, for internet working for Lazarus/Delphi. I've never seen such library like Indy. Thanks to Remy for maintening it. Well, there's also fp-web, lNet(Small L Big N) and synapse. fp-web has fphttpclient, which isn't that bad for http/s needs. synapse is a full range package: http/s, ftp. smtp, pop3, dns, etc but it hasn't been maintained in a long time, so it's starting to age. lNet is also a full range package with lightweight in mind and I'm not sure of how it's been maintained. Now that you tell me that Indy has been maintained by Remy, I'll have to maybe not overlook it so much in the future Cheers, Gus ---------------------------------------------------------------------- alaa123456789 · 2021-03-24 17:24 Quote from: gcarreno on March 24, 2021, 12:51:14 amHi alaa123456789, I welcome the fact that you have a very good tutorial on how to use curl, wget and the URLMon thing(I was unaware it's a unit, I'll have to find it and look at it)!! But it's a tad off topic since the OP is using fp-web and your suggestion is to add external dependencies on executables apart from the SSL *.dlls. I'm glad you could show your work, but it really doesn't solve his initial problem. Cheers, Gus urlmon is a unit in fp not external thanks ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-25 01:10 Hey alaa123456789, Quote from: alaa123456789 on March 24, 2021, 06:24:49 pmurlmon is a unit in fp not external Ahh, I see, thank you very much for that tidbit, really appreciated!! Cheers, Gus ---------------------------------------------------------------------- avra · 2021-03-25 07:47 Here you can find example of file download with progress indicator: https://bitbucket.org/avra/ct2laz/src/master/downloader.pas It does not use any third party libraries. ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-25 11:42 Hey avra, That code is rather old, 2013. It does not get around the issues with compiling on both 3.0.4 and 3.2.0 with SSL support. There is something rather fishy around the Progress code; DoProgress() seems to never be called. The {$mode objfpc} is used but the function is assigned without the @. And that was just at a glance... But nonetheless, many thanks for a solid start with means to grow. Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-25 11:47 Hey Jvan, I've been promising but I haven't delivered, so attached is my code of a form that downloads multiple files with progress on both the number of files and the size of each file. It also has all the necessary {$IFDEF} to compile AND work with SSL with both 3.0.4 and 3.2.0+. Cheers, Gus ---------------------------------------------------------------------- avra · 2021-03-26 07:30 Quote from: gcarreno on March 25, 2021, 12:42:12 pmThat code is rather old, 2013. It does not get around the issues with compiling on both 3.0.4 and 3.2.0 with SSL support.In first message from topic starter, I do not see a request for new or ssl. I've just checked and the way it is - it compiles with FPC 3.3.1 SVN63837. And it compiled with every FPC since 2017 when I first used it. Quote from: gcarreno on March 25, 2021, 12:42:12 pmThere is something rather fishy around the Progress code; DoProgress() seems to never be called. The {$mode objfpc} is used but the function is assigned without the @.Did you load ct2laz project into Lazarus, compile it and press [CT => LAZ] button to start downloading and check if progress is shown? If download didn't work you wouldn't have so many pl_* components in OPM. As always, patches are welcome. It's open source, after all. Quote from: gcarreno on March 25, 2021, 12:42:12 pmBut nonetheless, many thanks for a solid start with means to grow.You're welcome. Cheers! ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-26 10:12 Hey Avra, I didn't mean to be offensive, and if I did, I do apologise quite profusely. When I said old I mean it doesn't take into account that pre 3.2.0 you needed: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  fphttpclient, fpopenssl, openssl, ssockets, sslsockets; And this call back: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure GetSocketHandler(Sender: TObject;  const UseSSL: Boolean; out AHandler: TSocketHandler);begin  AHandler := TSSLSocketHandler.Create;  TSSLSocketHandler(AHandler).SSLType := stTLSv1_2;end; And the code to be called this way: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i InitSSLInterface;http:= TFPHTTPClient.Create(nil);try  http.OnGetSocketHandler:=@GetSocketHandler;  http.Get(AURL, AFilename);finally  http.Free;end; In comparison, post 3.2.0 you only need this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  fphttpclient, opensslsockets; You DON'T need the callback and the code is called this way: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i http:= TFPHTTPClient.Create(nil);try  http.Get(AURL, AFilename);finally  http.Free;end; Now, the code without the callback actually compiles pre 3.2.0, but when you try SSL, no go. And with the Internet vying to drop HTTP because it's unsecure, you need HTTPS support, right? The code that I attached compiles AND works with both pre and post 3.2.0 AND with both HTTP and HTTPS. Your code may compile and work for HTTP, but due to the Internet going all HTTPS, it's showing a bit of age. Just saying And no I did not test your ct2laz code, and for that I apologise if I'm making all the wrong assumptions and putting my foot in my mouth. I tend to, sometimes, do that, sorry!! Cheers, GUs ---------------------------------------------------------------------- Jvan · 2021-03-26 20:50 Thanks, it works. ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-27 06:57 Hey Jvan, Quote from: Jvan on March 26, 2021, 09:50:15 pmThanks, it works. In the end, what made it work? Cheers, Gus