【发布时间】:2018-12-06 12:54:35
【问题描述】:
我正在使用 TIDHTTP 从非 https url 下载 zip 文件,如下面的代码:
IdHTTPProgress.DownloadFile('http://www.myurl.com/myfile.zip','c:\myfile.zip');
尽管如此,我还是遇到了“无法加载 SSL 库”异常。发生异常,但之后无论如何都会进行下载。
我怎样才能避免这个异常?
谢谢
【问题讨论】:
我正在使用 TIDHTTP 从非 https url 下载 zip 文件,如下面的代码:
IdHTTPProgress.DownloadFile('http://www.myurl.com/myfile.zip','c:\myfile.zip');
尽管如此,我还是遇到了“无法加载 SSL 库”异常。发生异常,但之后无论如何都会进行下载。
我怎样才能避免这个异常?
谢谢
【问题讨论】:
发生异常的唯一方式是:
您已将TIdSSLIOHandlerSocketOpenSSL 组件分配给TIdHTTP.IOHandler 属性。
即使您发出 HTTP 请求,它也会尝试初始化 OpenSSL,因为任何 HTTP 请求都可能重定向到 HTTPS,因此 Indy 在建立 TCP 连接时会准备 OpenSSL,以防万一。
您尚未在您的应用中部署 OpenSSL DLL(libeay32.dll 和 ssleay32.dll,或您的目标平台的等效) - 或者 - 您部署了 错误 版本的 DLL与您的 Indy 版本不兼容。
如果您要使用TIdSSLIOHandlerSocketOpenSSL,则需要正确的 DLL。 Indy 目前最高支持 OpenSSL 1.0.2,但不支持 OpenSSL 1.1.0 或更高版本(但 - 即on the TODO list)。
当 Indy 引发“无法加载 SSL 库”异常时,您可以在 IdSSLOpenSSLHeaders 单元中调用 Indy 的 WhichFailedToLoad() 函数,以确定失败是因为 DLL 未能加载到内存中,还是因为DLL 缺少 Indy 所需的导出。
IdSSLOpenSSL 单元中还有一个OpenSSLVersion() 函数,用于报告已将哪个版本的 OpenSSL 加载到内存中。
在您的情况下,不会发生从 HTTP 到 HTTPS 的重定向,但内部仍然会发生错误,TIdHTTP 将其吞下,因为未使用 HTTPS。您的代码在运行时不会看到异常。但是你的调试器会。
【讨论】:
TIdSSLIOHandlerSocketOpenSSL 引发了异常。如果您将IOHandler 保留为零,TIdHTTP 在内部创建一个默认值,TIdIOHandlerStack 或TIdSSLIOHandlerSocketOpenSSL,基于第一个请求是 HTTP 还是 HTTPS(但前提是 IdSSLOpenSSL 在您的 uses 中条款)。设置后,IOHandler 不会自动更改。除非事先设置了 TIdSSLIOHandlerSocketOpenSSL,否则您无法请求 HTTP url 并收到 SSL 加载错误。
TIdSSLIOHandlerSocketOpenSSL,并且发生了从 HTTP 到 HTTPS 的重定向,您将得到不同的异常(“IOHandler 无效”)。但是是的,如果异常被TIdHTTP 吞噬并且没有到达您的代码,那么您可以忽略它。并且可选地告诉调试器也忽略它。如果您根本不想使用 HTTPS,则不应在项目中引用 IdSSLOpenSSL 单元。