9

我有以下任务:使用 HTTPS 和身份验证下载文件。Indy 似乎是要走的路,但由于某种原因,它到目前为止还行不通。我有以下内容:

  • 我用于下载的 TIdHTTP 组件
  • 用于创建 URL 的 TIdURI 组件
  • 应该提供安全连接的 TIdSSLIOHandlerSocketOpenSSL 组件。所需的 DLL 位于二进制文件夹中。

该站点还需要身份验证,我在 URL 中包含了用户/密码,如下例所示。简而言之,这是代码:

URI := TIdURI.Create('https://test.example.com/');
URI.Username := ParamUserName;
URI.Password := ParamPassword;

HTTP := TIdHTTP.Create(nil);
if URI.Protocol = 'https' then
begin
  IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  IOHandler.SSLOptions.Method := sslvSSLv3;
  HTTP.IOHandler := IOHandler;
end;

HTTP.Get(URI.GetFullURI([ofAuthInfo]), FileStream);

使用此代码,我非常快地得到“读取超时”EIdReadTimeout 异常。在浏览器中测试 URL 没有问题。关于缺少什么或我做错了什么的任何想法?

4

3 回答 3

11

我最终放弃了 Indy 和 OpenSSL,使用 WinInet 进行下载。这是对我有用的代码:

function Download(URL, User, Pass, FileName: string): Boolean;
const
  BufferSize = 1024;
var
  hSession, hURL: HInternet;
  Buffer: array[1..BufferSize] of Byte;
  BufferLen: DWORD;
  F: File;
begin
   Result := False;
   hSession := InternetOpen('', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0) ;

   // Establish the secure connection
   InternetConnect (
     hSession,
     PChar(FullURL),
     INTERNET_DEFAULT_HTTPS_PORT,
     PChar(User),
     PChar(Pass),
     INTERNET_SERVICE_HTTP,
     0,
     0
   );

  try
    hURL := InternetOpenURL(hSession, PChar(URL), nil, 0, 0, 0) ;
    try
      AssignFile(f, FileName);
      Rewrite(f,1);
      try
        repeat
          InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen) ;
          BlockWrite(f, Buffer, BufferLen)
        until BufferLen = 0;
      finally
        CloseFile(f) ;
        Result := True;
      end;
    finally
      InternetCloseHandle(hURL)
    end
  finally
    InternetCloseHandle(hSession)
  end;
end;
于 2010-02-11T12:48:57.273 回答
2

我也见过同样的事情。将 TIdHTTP.ReadTimeout 设置为零可以解决我的问题。

...
HTTP.IOHandler := IOHandler;
HTTP.ReadTimeout := 0;
于 2010-02-11T13:40:32.547 回答
1

除非正确安装了一些额外的库,否则所有用于安全连接的 SSL 相关功能都将失败。

1.)下载库

2.)解压缩并将两个 DLL 复制到您的项目文件夹(或系统路径中的某个位置)

你的问题代码对我来说很好。

——莱因哈德

于 2010-02-11T13:19:23.090 回答