使用 Indy TIdHTTP 下载文件

Downloading files using Indy TIdHTTP

我目前有一个程序可以从我的 VPS 下载文件并将其解压缩。我想让它直接从原始网站下载,但它不想工作。我想让它下载这个 link:

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

而不是这个:

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

编辑:使用这个 link:

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

也不起作用,即使使用 SSL 协议也是如此。

我正在使用 RAD Studio 10.2 Tokyo。

我找到了以下 post,但我正在努力将其添加到我当前的项目中:

Downloaded files using TIdHTTP INDY 10

这是我当前的项目代码:

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.

这个url:

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

Returns 一个 HTTP 302 重定向到这个 url:

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

因此,您需要处理 HTTP 重定向。将 TIdHTTP.HandleRedirects 属性 设置为 true(默认为 false)。

如果您使用的是 Delphi 10.2 Tokyo 或更高版本,您也可以使用 Delphi 自己的 System.Net.HttpClient.THTTPClient instead. It does not need any external SSL libraries, like TIdHTTP does. Be sure to set the THTTPClient.HandleRedirects 属性 为真。

您需要为 SSL 分配 IOHandler。

在您的 uses 子句中包含 IdSSLOpenSSL,并在您创建 httpclient 后添加以下内容。

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

然后确保您的 OpenSSL DLL 位于您的路径中或与可执行文件位于同一文件夹中。