1
votes

I'm using Delphi 7 with Indy 10.6.2.5459 to make a POST request to a server from time to time:

sParams := '?ultimaAlteracao='+FormatDateTime('YYYY-MM-DD',now())+'T00:00:00.000';
FidHTTP := TIdHTTP.Create;
try
  FidHTTP.Request.Clear;
  FidHTTP.Request.Accept           := 'application/json;charset=UTF-8';
  FidHTTP.Request.CharSet          := 'UTF-8';
  FidHTTP.Response.ContentType     := 'application/json;charset=UTF-8';
  FidHTTP.Response.ContentEncoding := 'UTF-8';
  FidHTTP.Request.CustomHeaders.AddValue('Authorization','Basic '+EncodeBase64('xx:xx@123456'));

  JsonStream := TStringStream.Create('');
  JsonStream.Position := 0;
  try
    FidHTTP.Get('https://'+server+'/LinxImportacaoArquivo/GetSelecaoDadosMDMNCM'+sParams, JsonStream);
    DataString := JsonStream.DataString;
  finally
    FreeAndNil(JsonStream);
  end;
finally
  FreeAndNil(FidHTTP);
end;

After sometime, it begins to fail and returns:

Error creating SSL context. error:140A90F1:SSL routines:SSL_CTX_new:unable to load ssl2 md5 routines

If I restart the application, it works for sometime again. I found some people who had the same issue: here and here

From what I learned, it can be some other process which uses Indy to make a request that is interfering, and I quote

It appears to be an issue with some type of static member initialization inside the openssl library. I have 2 libraries, both of them use the openssl library, let's call them A and B. When the application starts up both A & B are able to successfully create a security context. Later, when library B tries to create another security context it fails. Both library A and B are module plugins to our application so they both will load but if one is not needed it is unloaded.

Indeed, my application has a lot of others process executing, making http requests, through indy10 or WinInet.

So, my question is: Is there some procedure I can call on Indy10 to make it initialize something that had it freed on opensll library?

1
On a side note, you should not by using the TIdHTTP.Request.CustomHeaders property to send Basic authentication credentials manually. Set TIdHTTP.Request.BasicAuthentication=true and use the TIdHTTP.Request.Username and TIdHTTP.Request.Password properties instead. And UTF-8 is not a valid ContentEncoding. And when receiving string responses, you should use the overload of TIdHTTP.Get() that returns a string rather than the overload that fills a TStream, let TIdHTTP handle the response's charset for you: DataString := FidHTTP.Get(url);Remy Lebeau

1 Answers

1
votes

I found out that at unit IdSSLOpenSSL there's a procedure named UnLoadOpenSSLLibrary. If I always call that procedure before my code, the error does not occurr.