Search code examples
delphisslindydelphi-5idhttp

Error connecting with SSL using IdHttp Indy


I have a problem in IdHttp using Indy (Delphi).

I try to using IdHttp to post XML in web service SOAP, but dont work. Return "Error connecting with SSL." in IdSSLOpenSSL.Connect@1437 from indy.

My code is simple:

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;

In exe folder contain libeay32.dll and ssleay32.dll. Any sugestion?

I Used delphi 5, but in delphi 7 is the same problem.


Solution

  • By default, the SSLVersions property of TIdSSLIOHandlerSockOpenSSL is set to enable only TLS 1.0 1. But many websites are starting to phase out TLS 1.0 and only accept TLS 1.1+. So try enabling TLS 1.1 and TLS 1.2 in the SSLVersions property and see if it helps.

    1: there is an open ticket in Indy's issue tracker to also enable TLS 1.1 and TLS 1.2 by default.


    On a side note, there are some further tweaks you should make to your code:

    • do not assign any values to TIdHTTP's Host or ContentLength properties. They are populated automatically by TIdHTTP.

    • if you set the AcceptEncoding property manually, make sure NOT to include deflate or gzip unless you have a Compressor assigned to TIdHTTP, otherwise it will fail to decode a compressed response. You really should not assign anything to AcceptEncoding unless you are prepared to handle custom encodings. The Compressor handles deflate/gzip and TIdHTTP will update AcceptEncoding accordingly if a Compressor is assigned and ready for use.

    • use the CustomHeaders.Values property to set individual headers, not the CustomHeaders.Text property.

    • you do not need to catch EIdHTTPProtocolException explicitly, since that exception handler is not doing anything extra that the more generic Exception handler is not doing.

    • the RawHeaders property is a TStringList descendant, so it is more efficient to use Lines.Assign(RawHeaders) instead of Lines.Text := RawHeaders.Text.

    Try this:

    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;