Delphi 如何使用Indy 10和OpenSSL通过HTTPS下载文件?
我有以下任务:使用HTTPS和身份验证下载文件。印第似乎是一条路要走,但由于某种原因,它到目前为止还不起作用。我已准备好以下各项:Delphi 如何使用Indy 10和OpenSSL通过HTTPS下载文件?,delphi,openssl,indy,delphi-2006,Delphi,Openssl,Indy,Delphi 2006,我有以下任务:使用HTTPS和身份验证下载文件。印第似乎是一条路要走,但由于某种原因,它到目前为止还不起作用。我已准备好以下各项: 一个我用来下载的TIdHTTP组件 用于创建URL的TIdURI组件 应提供安全连接的TIdSSLIOHandlerSocketOpenSSL组件。所需的DLL位于二进制文件夹中 该站点还需要身份验证,我在URL中包含了user/pass,如下例所示。简而言之,代码如下: URI := TIdURI.Create('https://test.example.co
- 一个我用来下载的TIdHTTP组件
- 用于创建URL的TIdURI组件
- 应提供安全连接的TIdSSLIOHandlerSocketOpenSSL组件。所需的DLL位于二进制文件夹中
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不会出现问题。有没有关于遗漏了什么或我做错了什么的想法?我最终放弃了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;
除非正确安装了一些附加库,否则用于安全连接的所有SSL相关函数都将失败 1.) 2.)解压这两个DLL并将其复制到项目文件夹(或系统路径中的某个位置) 有了这个问题,你的代码对我来说很好
--莱因哈德我也看到过同样的事情。将TIdHTTP.ReadTimeout设置为零可以解决我的问题
...
HTTP.IOHandler := IOHandler;
HTTP.ReadTimeout := 0;
谢谢你的回答。我把DLL放在适当的位置,看起来它们加载正确。读取超时似乎是由其他原因引起的。WinInet方法适用于同一台服务器。应用程序和服务器之间是否有防火墙/代理?“Browser works“并不意味着有直接的Internet连接。@mjustin如果我查看浏览器设置,没有定义代理。此外,WinInet方法在不设置任何代理的情况下工作的事实告诉我,这不是问题所在。在这种情况下不要使用TIdURI.Username/password属性。您必须改用TIdHTTP.Username/Password属性。ReadTimeout=0是默认超时值,它表示无限超时。是的,但是在附加IOHandler后在代码中设置它似乎可以阻止引发EIdReadTimeout异常。(至少在我的经验中,对于Delphi附带的Indy版本)关于上述代码,有一点需要注意:您应该始终使用INTERNET_FLAG_RELOAD参数强制从服务器而不是缓存下载。因此,我建议您将代码更改为:hull:=InternetOpenURL(hsSession,PChar(fullURL),无,0,互联网标志重新加载,0);将
Winapi.WinInet
添加到uses
。