- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用 SSL 时如何在 Indy 中设置 ConnectTimeout/ReadTimeout ?
MCVE:
program mcve;
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}SysUtils, IdHTTP, IdSSLOpenSSL, DateUtils;
var
HTTP : TIdHTTP;
SSL : TIdSSLIOHandlerSocketOpenSSL;
Started : TDateTime;
begin
HTTP := TIdHTTP.Create();
try
HTTP.ReadTimeout := 1000;
HTTP.ConnectTimeout := 2000;
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP);
SSL.ConnectTimeout := HTTP.ConnectTimeout;
SSL.ReadTimeout := HTTP.ReadTimeout;
SSL.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
HTTP.IOHandler := SSL;
Started := Now;
try
HTTP.Get(ParamStr(1));
except
On E: Exception do WriteLn(E.Message);
end;
Writeln(FormatDateTime('hh:nn:ss', SecondsBetween(Started, Now) / SecsPerDay));
finally
HTTP.Free;
end;
end.
当使用 http
时,ConnectTimeout/ReadTimeout 可以正常工作,只有在使用 https
时才可以解决此问题,如下所示:
:~$ ./mcve http://x.x.x.x
Read timed out.
00:00:01 <-- Correct.
<小时/>
:~$ ./mcve https://x.x.x.x
Socket Error # 0
00:03:38 <-- NOT Correct / More than SSL.ReadTimeout value.
从 OPM 版本 10.6.2.5494 安装 Lazarus 2.0.6 Indy。
注意:在 Windows 上使用 Delphi 和 Indy 10.6.2.5366 的相同代码,结果按预期工作
最佳答案
您无需手动设置ConnectTimeout
和ReadTimeout
在 IOHandler 本身上,仅在客户端组件上(在本例中为 TIdHTTP
)。 TIdTCPClient.Connect()
将为您将值分配给 IOHandler。
ConnectTimeout
在创建任何 SSL/TLS session 之前,底层套接字连接到服务器时适用,因此无论您是否使用 SSL/TLS,它的操作都是相同的。
ReadTimeout
当 Indy 尝试从 IOHandler 的内部连接读取字节时适用。当不使用 SSL/TLS 时,这意味着它直接进入套接字,因此当没有字节到达套接字时就会超时。但是当使用 SSL/TLS 时,Indy 使用 OpenSSL 的遗留 SSL_...()
API,而不是较新的 BIO_...()
API,这意味着 OpenSSL 正在代表 Indy 进行自己的套接字读取和缓冲,因此当 OpenSSL 不提供任何解密的应用程序字节时,Indy 会超时。
方式上的一个区别TIdSSLIOHandlerSocketOpenSSL
在 Windows 上运行与其他平台相比,仅在 Windows Vista+ 上运行,TIdSSLIOHandlerSocketOpenSSL
确实适用 ReadTimeout
到底层套接字的 SO_RCVTIMEO
和SO_SNDTIMEO
通过 IOHandler 的超时 Binding.SetSockOpt()
方法,作为 Windows 上 OpenSSL 错误的解决方法。对于其他平台,Indy 目前没有设置这两个套接字超时。
手动设置这些超时的好地方是 IOHandler 的 OnBeforeConnect
事件,该事件在套接字连接到服务器之后、创建任何 SSL/TLS session 之前触发。
关于delphi - 如何在 Indy SSL 中设置 ConnectTimeout/ReadTimeout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58779531/
我是一名优秀的程序员,十分优秀!