Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何使用Indy 10和OpenSSL通过HTTPS下载文件?_Delphi_Openssl_Indy_Delphi 2006 - Fatal编程技术网

Delphi 如何使用Indy 10和OpenSSL通过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

我有以下任务:使用HTTPS和身份验证下载文件。印第似乎是一条路要走,但由于某种原因,它到目前为止还不起作用。我已准备好以下各项:

  • 一个我用来下载的TIdHTTP组件
  • 用于创建URL的TIdURI组件
  • 应提供安全连接的TIdSSLIOHandlerSocketOpenSSL组件。所需的DLL位于二进制文件夹中
该站点还需要身份验证,我在URL中包含了user/pass,如下例所示。简而言之,代码如下:

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