代码之家  ›  专栏  ›  技术社区  ›  Tihauan

如何使用indy 10和openssl通过https下载文件?

  •  9
  • Tihauan  · 技术社区  · 15 年前

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

    • 我用来下载的tidthttp组件
    • 用于创建URL的tiduri组件
    • TidsslioHandlerSocketToPenssl组件,应提供安全连接。所需的dll在二进制文件夹中。

    该站点还需要身份验证,我在URL中包含了用户/通行证,如下面的示例所示。简而言之,这就是代码:

    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没有问题。你对我遗漏了什么或者我做错了什么有什么看法吗?

    3 回复  |  直到 15 年前
        1
  •  10
  •   Tihauan    15 年前

    我最终放弃了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;
    
        2
  •  1
  •   jasonpenny    15 年前

    我也看到过同样的事情。将tidtp.readTimeout设置为零可以为我解决问题。

    ...
    HTTP.IOHandler := IOHandler;
    HTTP.ReadTimeout := 0;
    
        3
  •  0
  •   macf00bar    15 年前

    除非正确安装了一些附加库,否则用于安全连接的所有与SSL相关的功能都将失败。

    1.) 下载库

    2.)解压两个DLL并将其复制到项目文件夹(或系统路径中的某个位置)。

    有了这一点,您的问题代码对我来说很好。

    --莱因哈德

    下载库

    2.)解压两个DLL并将其复制到项目文件夹(或系统路径中的某个位置)。

    有了这个问题,你的代码对我来说很好。

    ——莱因哈德

    推荐文章