delphi 无法以编程方式从Amazon CDN下载文件

dxpyg8gm  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(100)

我使用URLDownloadToFile从URL下载文件。通常它工作得很好。
但是,当我尝试从亚马逊CDN下载文件时,它总是会失败。
网址是:https://download.datanumen.com/downloads/file/dexr.exe,我可以从Chrome或FireFox手动下载,没有问题。
我的代码是:

//  Delete the cache before calling URLDownloadToFile
    DeleteUrlCacheEntry(strURL);

    HRESULT hr;
    
    hr = URLDownloadToFile(NULL, strURL, strFileName, 0, NULL);
    
    if (hr == INET_E_DOWNLOAD_FAILURE)
        hr = hr;

    if (hr != S_OK)
    {
        _com_error err(hr);

        _tprintf(_T("Error in download: %s.\r\n"), err.ErrorMessage());
    }

    IStream* stream;
    hr = URLOpenBlockingStream(0, LPCTSTR(strURL), &stream, 0, 0);

    if (hr != S_OK)
    {
        _com_error err(hr);

        _tprintf(_T("Error in download: %s.\r\n"), err.ErrorMessage());
    }

    return  (hr == S_OK);

字符串
结果如下:

Error in download: Unknown error 0x800C0005.
Error in download: Unknown error 0x800C0005.


由于返回错误是未知错误,我甚至不知道如何修复它。

更新

我尝试使用Downloading a file in Delphi中的代码来下载文件。
我的代码是:

function DownloadFile(const strURL: string; const strFileName: string): Boolean;
var
  IdHTTP1: TIdHTTP;
  http : TNetHTTPClient;
  Stream: TMemoryStream;
  Url, FileName: String;
begin
  Url := 'http://www.rejbrand.se';
  Filename := 'download.htm';

  IdHTTP1 := TIdHTTP.Create(nil);
  http := TNetHTTPClient.Create(nil);
  Stream := TMemoryStream.Create;
  try
    //IdHTTP1.Get(strURL, Stream);
    http.Get(strURL, stream);
    Stream.SaveToFile(strFileName);
  finally
    Stream.Free;
    IdHTTP1.Free;
  end;
end;


当使用TIdHTTP时,我得到以下异常:

Project DLVerify.exe raised exception class EIdOSSLUnderlyingCryptoError with message 'Error connecting with SSL.
error:1409442E:SSL routines:SSL3_READ_BYTES:tlsv1 alert protocol version'.


当使用TNetHTTPClient时,我得到以下异常:

Project DLVerify.exe raised exception class ENetHTTPClientException with message 'Error sending data: (12175) A security error occurred'.


所以似乎没有代码可以从URL下载。

更新2

我尝试将TLS更改为1.2和2.0,两者都失败了,结果相同:

function DownloadFile1(const strURL: string; const strFileName: string): Boolean;
var
  LHTTP: TIdHTTP;
  LHandler: TIdSSLIOHandlerSocketOpenSSL;
  responseFromServer, sWhichFail, sVer :string;
    Stream: TMemoryStream;
begin
  //ResponseMemo.Clear;

  LHTTP := TIdHTTP.Create(nil);
  try
    LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(LHTTP);
    LHandler.SSLOptions.SSLVersions := [sslvSSLv2, sslvSSLv23, sslvSSLv3, sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2];
    LHandler.SSLOptions.Mode := sslmClient;
    LHandler.SSLOptions.VerifyMode := [];
    LHandler.SSLOptions.VerifyDepth := 0;

    LHTTP.IOHandler := LHandler;
    LHTTP.AllowCookies := True;

       Stream := TMemoryStream.Create;
  try
    //IdHTTP1.Get(strURL, Stream);
    LHTTP.Get(strURL, stream);
    Stream.SaveToFile(strFileName);
  finally
    Stream.Free;
    LHTTP.Free;
  end;
end;


更新3:
使用

LHandler.SSLOptions.SSLVersions := [sslvTLSv1_1,sslvTLSv1_2];


得到一个不同的结果:

Project DLVerify.exe raised exception class EIdOSSLUnderlyingCryptoError with message 'Error connecting with SSL.
error:140740BF:SSL routines:SSL23_CLIENT_HELLO:no protocols available'.

arknldoa

arknldoa1#

Delphi 11 Update 2(28.0.46141.0937)附带的TIdHTTP(Indy 10.6.2.0)没有问题

implementation

uses
  IdHTTP, IdSSLOpenSSL;

procedure Download;
var
  http: TIdHTTP;
  ssl: TIdSSLIOHandlerSocketOpenSSL;
  ms: TMemoryStream;
begin
  //ShowMessage(http.Version);
  http := TIdHTTP.Create(nil);
  ms := TMemoryStream.Create;
  try
    ssl := TIdSSLIOHandlerSocketOpenSSL.Create(http);
    ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];

    http.IOHandler := ssl;

    http.Get('https://download.datanumen.com/downloads/file/dexr.exe', ms);
    ms.SaveToFile('c:\temp\dexr.exe');
  finally
    ms.Free;
    http.Free;
  end;
end;

字符串
openssl lib是1.0.2u(1.0.2.21)。
THTTPClient也一样,没有问题:

implementation

uses
  System.Net.HttpClient;

procedure Download2;
var
  http: THTTPClient;
  ms: TMemoryStream;
begin
  http := THTTPClient.Create;
  ms := TMemoryStream.Create;
  try
    http.Get('https://download.datanumen.com/downloads/file/dexr.exe', ms);
    ms.SaveToFile('c:\temp\dexr.exe');
  finally
    ms.Free;
    http.Free;
  end;
end;

相关问题