如何使用 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.dll
和 ssleay32.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 的 Destination
、Host
或 Port
属性。 TIdHTTP
将在内部为您处理。
我有这个适用于 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.dll
和 ssleay32.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 的 Destination
、Host
或 Port
属性。 TIdHTTP
将在内部为您处理。