【问题标题】:Error connecting with SSL using IdHttp Indy使用 IdHttp Indy 连接 SSL 时出错
【发布时间】:2018-11-24 03:37:05
【问题描述】:

我在使用 Indy (Delphi) 的 IdHttp 中遇到问题。

我尝试使用 IdHttp 在 Web 服务 SOAP 中发布 XML,但不起作用。返回“与 SSL 连接时出错。”在来自 indy 的 IdSSLOpenSSL.Connect@1437 中。

我的代码很简单:

procedure TForm1.Button1Click(Sender: TObject);
var
  vRequest : TStringStream;
  s : String;
begin
  vRequest  := TStringStream.Create((Memo1.Lines.Text));
  try
    IdHTTP1.Host                       := edHost.Text;
    IdHTTP1.Request.ContentLength      := length(Memo1.Lines.Text);
    IdHTTP1.Request.ContentType        := edContentType.Text;
    IdHTTP1.Request.CustomHeaders.Text := 'SOAPAction: "removed for safe"'#13#10;
    IdHTTP1.request.CacheControl       := 'no-cache';
    IdHTTP1.Request.AcceptEncoding     := edAccept.Text;
    IdHTTP1.HTTPOptions                := [hoKeepOrigProtocol];
    IdHTTP1.ProtocolVersion            := pv1_1;

    Memo2.Clear;
    try
      s := IdHTTP1.post(Edit1.Text, vRequest);
      Memo2.Lines.Text := s;
    except
      on e: EIdHTTPProtocolException do begin
        Label1.Caption     := e.Message;
        MEMO2.LINES.TEXT   := e.Message;
      end;
      on e:Exception do begin
        Label1.Caption     := e.Message;
        MEMO2.LINES.TEXT   := e.Message;
      end;
    end;

    requestHeaders.Lines.Text  := IdHTTP1.Request.RawHeaders.Text;
    responseHeaders.Lines.Text := IdHTTP1.Response.RawHeaders.Text;
  finally
    vRequest.Free;
  end;
end;

在 exe 文件夹中包含 libeay32.dll 和 ssleay32.dll。有什么建议吗?

我用的是delphi 5,但是在delphi 7中也是同样的问题。

【问题讨论】:

    标签: delphi ssl indy delphi-5 idhttp


    【解决方案1】:

    默认情况下,TIdSSLIOHandlerSockOpenSSLSSLVersions 属性设置为仅启用 TLS 1.0 1。但许多网站开始逐步淘汰 TLS 1.0,只接受 TLS 1.1+。因此,请尝试在 SSLVersions 属性中启用 TLS 1.1 和 TLS 1.2,看看是否有帮助。

    1:Indy 的问题跟踪器中有一个open ticket,默认情况下也启用 TLS 1.1 和 TLS 1.2。


    附带说明,您应该对代码进行一些进一步的调整:

    • 不要为TIdHTTPHostContentLength 属性分配任何值。它们由TIdHTTP 自动填充。

    • 1234563 .你真的不应该给AcceptEncoding 分配任何东西,除非你准备好处理自定义编码。 Compressor 句柄 deflate/gzipTIdHTTP 将相应地更新 AcceptEncoding,如果 Compressor 已分配并准备好使用。
    • 使用CustomHeaders.Values 属性来设置单个标题,而不是CustomHeaders.Text 属性。

    • 您不需要显式捕获EIdHTTPProtocolException,因为该异常处理程序没有做任何额外的事情,而更通用的Exception 处理程序没有做。

    • RawHeaders 属性是TStringList 的后代,因此使用Lines.Assign(RawHeaders) 而不是Lines.Text := RawHeaders.Text 更有效。

    试试这个:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      vRequest : TStringStream;
      s : String;
    begin
      IdHTTP1.Request.ContentType := edContentType.Text;
      IdHTTP1.Request.CustomHeaders.Values['SOAPAction'] := 'removed for safe';
      IdHTTP1.Request.CacheControl := 'no-cache';
      IdHTTP1.HTTPOptions := [hoKeepOrigProtocol];
      IdHTTP1.ProtocolVersion := pv1_1;
    
      Memo2.Clear;
      try
        vRequest := TStringStream.Create(Memo1.Lines.Text);
        try
          s := IdHTTP1.Post(Edit1.Text, vRequest);
        finally
          vRequest.Free;
        end;
        Memo2.Lines.Text := s;
      except
        on e: Exception do begin
          Label1.Caption := e.Message;
          Memo2.Lines.Text := e.Message;
        end;
      end;
    
      RequestHeaders.Lines.Assign(IdHTTP1.Request.RawHeaders);
      ResponseHeaders.Lines.Assign(IdHTTP1.Response.RawHeaders);
    end;
    

    【讨论】:

    • 感谢您的回复。原来问题出在 OpenSSl dll 上,更新后它工作得很好。奇怪的是,我不知道为什么,在更新 dll 之后,SSL 处理程序在第一次尝试时没有加载 dll 库,但是如果我再试一次,第二次以后工作完全正常,解决我们简单调用的问题应用程序初始化时的 IdSSLOpenSSLHeaders.Load()。但尽管如此,还是感谢您的旁注,这对未来的实现保持更简洁的代码非常有用!
    • "SSL 处理程序在第一次尝试时没有加载 dll 库,但如果我再试一次,第二次以后工作完全正常" - Indy 的 @987654350 是什么意思@函数报告OpenSSL第一次加载失败?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    相关资源
    最近更新 更多