2

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.

Erick Moraes
  • 41
  • 1
  • 4

1 Answers1

5

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;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks for your reply. It turned out the problem was something with the OpenSSl dlls, after updating it it worked just fine. Oddly, and i'm not sure why, after updating the dlls, the SSL Handler is not loading the dll library on the first attempt, but if i try again, the second time onwards works completely normal, to work around that we simply called IdSSLOpenSSLHeaders.Load() on the application initialization. But nonetheless thanks for your side notes, it will be very useful on future implementations to maintain a cleaner code! – Erick Moraes Jun 14 '18 at 17:13
  • "*the SSL Handler is not loading the dll library on the first attempt, but if i try again, the second time onwards works completely normal*" - what does Indy's `WhichFailedToLoad()` function report when OpenSSL fails to load the first time? – Remy Lebeau Jun 14 '18 at 17:21