如何使用 Indy 下载文件。错误 "iohandler value is not valid"

How to download file with Indy. Error "iohandler value is not valid"

我有这个适用于 HTTP 的函数。现在,随着 HTTPS 的广泛传播,它不再起作用了。我收到“IOHandler 值无效”错误。

所以,我创建了一个 SSLIOHandler 对象,如下所示,但现在我收到一个新错误:

Exception class EIdOSSLUnderlyingCryptoError with message 'Error connecting with SSL. error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version'

如何正确设置 SSLIOHandler 对象?

{ Only suitable for small files because the whole download will be saved to RAM before writing it to disk. }
function DownloadFile(CONST SourceURL, DestFileName: string; OUT ErrorMsg: String): Boolean;
VAR
  Indy: TIDHTTP;
  Stream: TFileStream;
  IDAntiFreeze: TIDAntiFreeze;
  IOHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
  Indy:= TIDHTTP.Create(NIL);
  IOHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(NIL);
  IDAntiFreeze:= TIDAntiFreeze.Create(NIL);
  Stream:= TFileStream.Create(DestFileName, fmCreate);
  TRY
    IOHandler.Destination := SourceURL;
    IOHandler.Host := SourceURL;
    IOHandler.MaxLineAction := maException;
    //IOHandler.Port := 587;
    //IOHandler.DefaultPort := 0;
    //IOHandler.OnStatusInfo := SSLIOHandlerStatusInfo;

    Indy.ConnectTimeout          := 0;                   { Indy default value: zero }
    Indy.ReadTimeout             := -1;                  { Indy default value: -1 }
    Indy.HandleRedirects         := TRUE;                {  }
    Indy.AllowCookies            := FALSE;
    Indy.Request.UserAgent       := 'Mozilla/4.0';
    Indy.Request.Connection      := 'Keep-Alive';
    Indy.Request.ProxyConnection := 'Keep-Alive';
    Indy.Request.CacheControl    := 'no-cache';
    Indy.IOHandler:= IOHandler;

    // Indy.OnWork:= HttpWork;

    TRY
      Indy.Get(SourceURL, Stream);
      Result:= TRUE;
    EXCEPT
      On E: Exception DO
        begin
          Result:= FALSE;
          ErrorMsg := E.Message + ' (' + IntToStr(Indy.ResponseCode) + ')';
        end;
    END;
  FINALLY
    FreeAndNil(Stream);
    FreeAndNil(IDAntiFreeze);
    FreeAndNil(IOHandler);
    FreeAndNil(Indy);
  END;
end;

PS:libeay32.dllssleay32.dll 存在于应用程序的文件夹中。

您没有以任何方式配置 TIdSSLIOHandlerSocketOpenSSL 的 TLS 设置。默认情况下,它仅启用 TLS 1.0(已知问题:https://github.com/IndySockets/Indy/issues/181),但有可能该网站需要 TLS 1.1+。

尝试添加这个:

IOHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];

此外,附带说明一下,您根本不需要配置 IOHandler 的 DestinationHostPort 属性。 TIdHTTP 将在内部为您处理。