If I send a basic email via TidSMTP (ignore the try/finally blocks, this is just an example):
var
SMTP : TidSMTP;
MSG : TidMessage;
LHandler : TIdSSLIOHandlerSocketOpenSSL;
begin
SMTP := TIdSMTP.Create(nil);
Msg := TIdMessage.Create(nil);
LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
Msg.Body.Text := 'Test Simple Email';
Msg.Subject := 'Test Simple Email Subject';
Msg.From.Address := '[email protected]';
MSG.ContentType := 'text/html';
Msg.Priority := mpHighest;
SMTP.Host := 'smtp.server.com';
SMTP.Username := '[email protected]';
SMTP.Port := 587;
SMTP.Password := 'testPassword';
SMTP.IOHandler := LHandler;
try
with Msg.Recipients.Add do
begin
Address := '[email protected]'
end;
try
SMTP.Connect;
SMTP.Send(Msg);
SMTP.Disconnect;
finally
Screen.Cursor := crDefault;
end;
finally
LHandler.Free;
Msg.Free;
SMTP.Free;
end;
And then call a DLL which makes an HTTPS request via TidHTTP:
var
myHTTP : TIdHTTP;
LHandler: TIdSSLIOHandlerSocketOpenSSL;
FJSON : String;
GetStr : String;
begin
GetStr := URLEncode('6421 E ROAD, GREELEY,CO,80634');
GetStr := 'https://maps.googleapis.com/maps/api/geocode/json?address=' + GetStr + '&key=' + 'someGoogleAPIKey';
myHTTP := TIdHTTP.Create(nil);
try
LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
LHandler.SSLOptions.SSLVersions := [sslvTLSv1_2];
myHTTP.IOHandler := LHandler;
try
FJSON := myHTTP.Get(GetStr);
except
on E: Exception do
begin
raise
end;
end;
showmessage(FJSON);
finally
LHandler.Free;
end;
finally
myHTTP.Free;
end;
And then try the email a second time, I'm receiving the error "Error creating SSL context", specifically "error:140A90F1:SSL routines: SSL_CTX_new: unable to load ssl2 md5 routines"
If I change this slightly by feeding in the TidSMTP component into the TidSSLIOHandlerSocketOpenSSL Create method:
LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(SMTP);
...
//SMTP.IOHandler := lHandler;
Then it works. But I can't use that. This is a completely stripped down version of the problem. In reality I'm using ReportBuilder (digital-metaphors) to send the email, and they don't allow one to send in the TidSMTP during the TidSSLIOHandlerSocketOpenSSL Create method.
This error does not happen when the HTTPS request is made within the same program as the SMTP request. Only when crossing into a DLL. This error does not happen if I do the HTTPS/DLL first and then SMTP. There is something happening during the first SMTP call that sets it up for the error down the road.
Should I take this over to Digital-Metaphors, or is there something going on during the HTTPS/DLL call that I could be doing better?
Ownerto a component does not solve your issue. That is strictly for memory management only, which is not your issue. You have multiple modules using OpenSSL, and one module is likely unloading OpenSSL from memory while the other module is still using it. OpenSSL doesn't work very well in DLLs when it comes to dynamic (un)loading, and Indy does use OpenSSL dynamically. One thing you could try is having your main app have Indy load OpenSSL at startup before it is actually needed, thus keeping OpenSSL alive for the life of the app, rather than (un)load it on an as-needed basis - Remy LebeauLoadOpenSSLLibrary()function in theIdSSLOpenSSLunit. - Remy LebeauTidSSLIOHandlerSocketOpenSSLcallsLoadOpenSSLLibrary()internally for you (in theTIdSSLContextconstructor). But if it works for you, so be it. I can't comment on why the other approach did not work for you, and I have no way to reproduce/debug it myself right now. - Remy Lebeau