使用Indy下载文件TIdHTTP

问题描述:

我目前有一个程序从我的VPS下载文件并提取它。我想直接从原始网站下载,但它不想工作。我希望把它下载链接:使用Indy下载文件TIdHTTP

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

取而代之的是:

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

编辑:使用此链接:

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

而且不工作,即使在使用SSL协议时也是如此。

我正在使用RAD Studio 10.2 Tokyo。

我发现下面的职位,但我挣扎将其添加到我的当前项目:

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. 
+0

[此链接](https://bintray.com/oxidemod/builds/download_file?file_path=Oxide-Rust.zip)被重定向到[本页](https://dl.bintray.com/oxidemod/)你需要在'TDownload'类的'constructor'处调用'httpclient.HandleRedirects:= True;'在'httpclient:= TIdHTTP.Create(nil)'之后调用'httpclient.HandleRedirects:= True;'' TIdHTTP'处理它,关于其他链接,它只是工作正常。另外'TIdHTTP'可以在新的Indy版本内部处理https urls,所以你不必创建'SSL'handler,除非你也有。 – RepeatUntil

+0

它不会下载。没有什么事。没有输出。没有错误没有任何东西 – Newb101

+0

当使用调试模式时,我得到这个 第一次机会例外,在$ 776BB802。异常类EIdOSSLCouldNotLoadSSLLibrary,消息'无法加载SSL库。'。过程pRSM。exe(4280) – Newb101

这个网址:

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

返回一个HTTP 302重定向到该网址:

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

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

如果您使用的是Delphi 10.2东京版或更高版本,您也可以使用Delphi自己的System.Net.HttpClient.THTTPClient代替。它不需要任何外部SSL库,例如TIdHTTP。请务必将THTTPClient.HandleRedirects属性设置为true。

+0

调试后,我收到一个错误,说无法加载ssl库。我曾尝试下载Openssl并将文件添加到项目目录中,但我仍然得到相同的错误 – Newb101

+0

得到最新的OpenSSL http://indy.fulgan.com/SSL/ – Newb101

您需要为SSL分配一个IOHandler。

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

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

然后只要确保您的OpenSSL DLLs在您的路径或与可执行文件相同的文件夹中。

+1

后得到它的工作你说的是技术上的真实。是的,SSLIOHandler确实需要分配。但是,在过去几年中,现代Indy版本默认可以为您完成这项任务:[用于TIdHTTP的新HTTPS功能](http://www.indyproject.org/sockets/blogs/changelog/20141222.aspx) –

+0

非常酷。我不知道这个。 –

+0

调试后,我收到一条错误,说无法加载ssl库。我已经尝试下载Openssl并将文件添加到项目目录,但我仍然得到相同的错误 – Newb101