如何使用Indy 10和OpenSSL通过HTTPS下载文件?
我有以下任务:使用HTTPS和身份验证下载文件。 Indy似乎要走,但由于某种原因,它迄今为止并不奏效。我在地方执行以下操作:如何使用Indy 10和OpenSSL通过HTTPS下载文件?
- 我使用下载
- 用于创建URL
- 一个TIdSSLIOHandlerSocketOpenSSL组件,它应该提供安全连接TIdURI分量TIdHTTP组件。所需的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;
关于上面的代码的警告一句话:你应该总是使用INTERNET_FLAG_RELOAD参数来强制从服务器下载而不是缓存。所以我建议你将代码改为:hURL:= InternetOpenURL(hSession,PChar(fullURL) ,零,0,INTERNET_FLAG_RELOAD,0); – user2858981 2016-11-10 15:11:59
所有SSL安全连接相关的功能将失败。
2)解压缩和复制两个DLL文件到您的项目文件夹(或在您的系统的路径某处)
与从问题的代码工作正常,我。
--reinhard
谢谢你的回答。我有DLL的地方,似乎他们正确加载。读取超时似乎是由别的东西引起的。 WinInet方法适用于同一台服务器。 – Tihauan 2010-02-11 13:25:53
我见过同样的事情。将TIdHTTP.ReadTimeout设置为零可以为我解决问题。
...
HTTP.IOHandler := IOHandler;
HTTP.ReadTimeout := 0;
ReadTimeout = 0是默认超时值,它表示无限超时。 – 2010-02-12 10:15:47
是的,但在附加IOHandler后将其设置在代码中似乎阻止了引发EIdReadTimeout异常。 (至少在我的经验中,随着Delphi的Indy版本) – jasonpenny 2010-02-12 13:20:40
在应用程序和服务器之间是否存在防火墙/代理? '浏览器作品'并不意味着有直接的互联网连接。 – mjn 2010-02-11 14:16:43
@mjustin如果我查看浏览器设置,则没有定义代理。另外,WinInet方法在没有设置任何代理的情况下工作的事实告诉我,这不是问题。 – Tihauan 2010-02-12 08:31:24
在这种情况下,请勿使用TIdURI.Username/password属性。您必须改用TIdHTTP.Username/Password属性。 – 2010-02-12 10:17:38