Newb101
Newb101

Reputation: 147

Downloading files using Indy TIdHTTP

I currently have a program that downloads a file from my VPS and extracts it. I want to make it download straight from the original website, but it doesn't want to work. I want to make it download this link:

https://bintray.com/oxidemod/builds/download_file?file_path=Oxide-Rust.zip

Instead of this:

http://41.185.91.51/RSM/Oxide-Rust.zip

Edit: Using this link:

https://dl.bintray.com/oxidemod/builds/Oxide-Rust.zip

Also doesnt work, even when using the SSL protocol.

I'm using RAD Studio 10.2 Tokyo.

I found the following post, but I'm struggling to add it to my current project:

Downloaded files using TIdHTTP INDY 10

Here is my current project code:

unit uOxideModInstaller;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.ComCtrls,
  Vcl.StdCtrls, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdHTTP, System.Zip;

type

  TDownload = class;

  Tfrmoxidemodinstaller = class(TForm)
    lbl1: TLabel;
    pb1: TProgressBar;
    btn1: TButton;
    btn2: TButton;
    lblstatus: TLabel;
    procedure btn2Click(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TDownload = class(TThread)
  private
    httpclient: TIdHTTP;
    url: string;
    filename: string;
    maxprogressbar: integer;
    progressbarstatus: integer;
    procedure ExtractZip(ZipFile: string; ExtractPath: string);
    procedure idhttp1Work(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCount: Int64);
    procedure idhttp1WorkBegin(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCountMax: Int64);
    procedure UpdateProgressBar;
    procedure SetMaxProgressBar;
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: boolean; aurl, afilename: string);
    destructor Destroy; override;
  end;

var
  frmoxidemodinstaller: Tfrmoxidemodinstaller;

implementation

{$R *.dfm}
{ Thread }

constructor TDownload.Create(CreateSuspended: boolean; aurl, afilename: string);
begin
  inherited Create(CreateSuspended);
  httpclient := TIdHTTP.Create(nil);
  httpclient.OnWorkBegin := idhttp1WorkBegin;
  httpclient.OnWork := idhttp1Work;
  url := aurl;
  filename := afilename;
end;

procedure TDownload.idhttp1Work(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCount: Int64);
begin
  progressbarstatus := AWorkCount;
  Queue(UpdateProgressBar);

end;

procedure TDownload.idhttp1WorkBegin(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCountMax: Int64);
begin
  maxprogressbar := AWorkCountMax;
  Queue(SetMaxProgressBar);
end;

procedure TDownload.Execute;
var
  Stream: TMemoryStream;
begin
  Stream := TMemoryStream.Create;
  try
    httpclient.Get(url, Stream);
    Stream.SaveToFile(filename);
  finally
    Stream.Free;
  end;
end;

procedure TDownload.UpdateProgressBar;
var
  ZipFile: string;
begin
  frmoxidemodinstaller.pb1.Position := progressbarstatus;
  frmoxidemodinstaller.lblstatus.Caption := 'Downloading...';

  if frmoxidemodinstaller.pb1.Position = frmoxidemodinstaller.pb1.Max then
  begin
    frmoxidemodinstaller.lblstatus.Caption := 'Done Downloading. Installing...';
    Sleep(2000);
    ExtractZip('oxide.zip', GetCurrentDir);
  end;
end;

procedure TDownload.SetMaxProgressBar;
begin
  frmoxidemodinstaller.pb1.Max := maxprogressbar;
end;

destructor TDownload.Destroy;
begin
  FreeAndNil(httpclient);
  inherited Destroy;
end;

{ TForm1 }

procedure TDownload.ExtractZip(ZipFile, ExtractPath: string);
begin
  if TZipFile.IsValid(ZipFile) then
  begin
    TZipFile.ExtractZipFile(ZipFile, ExtractPath);
    frmoxidemodinstaller.lblstatus.Caption := 'Oxide Installed!';
    DeleteFile(ZipFile);
  end
  else
  begin
    ShowMessage('Error installing oxide!');
    frmoxidemodinstaller.lblstatus.Caption := 'Error Installing Oxide!';
  end;
end;

procedure Tfrmoxidemodinstaller.btn1Click(Sender: TObject);
var
  DownloadThread: TDownload;
  link: string;
begin
  link := 'http://41.185.91.51/RSM/Oxide-Rust.zip';
  DownloadThread := TDownload.Create(true, link, 'oxide.zip');
  DownloadThread.FreeOnTerminate := true;
  DownloadThread.Start;
end;

procedure Tfrmoxidemodinstaller.btn2Click(Sender: TObject);
begin
  Close;
end;

end.

Upvotes: 1

Views: 6498

Answers (2)

Kike Pérez
Kike Pérez

Reputation: 139

This url:

https://bintray.com/oxidemod/builds/download_file?file_path=Oxide-Rust.zip

Returns an HTTP 302 redirect to this url:

https://dl.bintray.com/oxidemod/builds/Oxide-Rust.zip

Because of this, you need to handle HTTP redirections. Set the TIdHTTP.HandleRedirects property to true (it is false by default).

If you are using Delphi 10.2 Tokyo or later, you can alternatively use Delphi's own System.Net.HttpClient.THTTPClient instead. It does not need any external SSL libraries, like TIdHTTP does. Be sure to set the THTTPClient.HandleRedirects property to true.

Upvotes: 4

Bruce McGee
Bruce McGee

Reputation: 15334

You need to assign an IOHandler for SSL.

Include IdSSLOpenSSL in your uses clause and add the following after you create httpclient.

httpclient.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(httpclient);

Then just make sure your OpenSSL DLLs are in your path or in the same folder as the executable.

Upvotes: 1

Related Questions