You are not logged in.
Pages: 1
Hi AB
as you know i write Crossplatform Client with FireMonkey.
No i switched the Server to secSSL.
For this i testet my 3 kinds of Clients:
Windows
Here i had to copy / install libeay32.dll, libssl32.dll and ssleay32.dll from OpenSSL (1.0.1) in my Path - Works fine.
IOS
Exception: in idHTTP.pas at TIdCustomHTTP.CheckAndConnect the IOHandler is nil
i googled and found this: http://www.monien.net/delphi-xe5-ssl-ht … estclient/
I added
{$if defined(IOS)}
IdSSLOpenSSLHeaders_Static,
{$endif}
to my code.
Than i downloaded Libcrypto.a and libssl.a which i added to the Project.
But the IOHandler is still nil....
I checked the Program with the Debugger but can not find the place.
I set the 5th parameter of TSQLRestClientHTTP.Create in GetClient to True (aHTTPS) and in TIndyHttpConnectionClass.Create the
fConnection.IOHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(nil) is set.
so it is very serious for me. (May be a Ref Count Problem ?!)
Android
Same Exception at same place as IOS.
Last edited by itSDS (2015-01-29 19:35:15)
Rad Studio 12.1 Santorini
Offline
Hi AB,
i think i have fixed the Problem. The Reason is in the RefCount - Management of Delphi (XE7) - could not say exactly but it works
type
TIndyHttpConnectionClass = class(TAbstractHttpConnection)
protected
fConnection: TIdHTTP; // itSDS
fIOHandler : TIdSSLIOHandlerSocketOpenSSL;
public
constructor Create(const aParameters: TSQLRestConnectionParams); override;
procedure URI(var Call: TSQLRestURIParams; const InDataType: string;
KeepAlive: integer); override;
destructor Destroy; override;
end;
{ TIndyHttpConnectionClass }
constructor TIndyHttpConnectionClass.Create(
const aParameters: TSQLRestConnectionParams);
begin
inherited;
fConnection := TIdHTTP.Create(nil);
fConnection.HTTPOptions := fConnection.HTTPOptions+[hoKeepOrigProtocol];
fConnection.ConnectTimeout := fParameters.ConnectionTimeOut;
if fParameters.Https then begin
fIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); // itSDS
fConnection.IOHandler:= fIOHandler; // itSDS
end;
if fParameters.ProxyName<>'' then
fConnection.ProxyParams.ProxyServer := fParameters.ProxyName;
end;
destructor TIndyHttpConnectionClass.Destroy;
begin
fConnection.Free;
fIOHandler.Free; // itSDS
inherited;
end;
in your Version the destructor of TIdSSLIOHandlerSocketOpenSSL is called in the end of TIndyHttpConnectionClass.Create. The Reason may be the Implementation of fConnection.IOHandler (fConnection.SetIOHandler)
As Workaround i added 1 extra Member fIOHandler in your TIndyHttpConnectionClass - Class.
Now SSL works on Windows, IOS, Android with FireMonkey
pls add my Modification to mORMot.
Rad Studio 12.1 Santorini
Offline
Hi AB i made a Ticket at Embarcadero
https://quality.embarcadero.com/browse/RSP-9994
may be they will find the Error.
I think the Problem is in TidTCPConnection and Delphi, there are lots of comments from the Developers concerning Problems.
At SetIOhander for example something about ARC.
At first i think my workround should fix the problem.
Last edited by itSDS (2015-01-30 10:39:15)
Rad Studio 12.1 Santorini
Offline
Now SSL works on Windows, IOS, Android with FireMonkey
pls add my Modification to mORMot.
This is just GREAT news!
Using a dedicated member at owner class is probably the best workaround we could find.
I suppose the error is in TIdHTTP.IOHandler property definition, which should store the IOHandler class as true reference, not as weak reference.
Another clear example of the breaking changes introduced by the NextGen ARC model, even in officially supported libraries.
Forcing to change the memory model was an awful decision from Embarcadero. At least, the ARC model should have been made optional, to leverage code compatibility.
I've committed your patch.
See http://synopse.info/fossil/info/0934096da2
Thanks a lot Stefan for your very valuable input!
Offline
tyvm
here is a little correction for SynCrossPlatformSpecific
// {$ifdef IOS}
// {$ifdef CPUARM}
// IdSSLOpenSSLHeaders_Static,
// {$endif}
// {$endif}
{$if defined(IOS) and defined(CPUARM)}
IdSSLOpenSSLHeaders_Static, // libcrypto.a und libssl.a sind im Ordner Framework\_main
{$else}
IdSSLOpenSSLHeaders,
{$endif}
the IdSSLOpenSSLHeaders is needed for IdOpenSSLSetLibPath('/usr/lib/'); // for OSX and iOS x86
Rad Studio 12.1 Santorini
Offline
Indeed.
Should be fixed by http://synopse.info/fossil/info/664d7e6d29
Offline
Hi Arnaud i got an answer on my Ticket
This is not an Indy bug. It is an ARC mis-management problem in the user code shown in this ticket.
The TIdTCPConnection.IOHandler and TIdTCPConnection.Socket properties are implemented as [weak] references, as they reference an external component whose lifetime is not dependent on TIdHTTP's lifetime. The user code shown is creating a temp IOHandler object with no Owner assigned to it, and its ARC reference count is not being incremented by TIdHTTP, so it falls to 0 when the user's code exits, thus freeing the IOHandler and nilling TIdHTTP's references to it. An Owner needs to be assigned so the IOHandler's ARC reference count is incremented, keeping it alive.
Connection.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(Connection);
Or:
Connection.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(Self);
Either way, the user's code is also assigning the TIdHTTP object to a local variable, not to a class member. Its ARC reference count is going to fall to 0 when the variable goes out of scope, freeing the TIdHTTP object.
Rad Studio 12.1 Santorini
Offline
This was at least a lack of documentation from the Indy part, I guess.
But what matter is that your workaround was just correct.
The fIOHandler: TIdSSLIOHandlerSocketOpenSSL property will take care of the ARC reference count as expected.
Nice!
Offline
I tested it with the following:
fConnection.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(fConnection);
and removed my fIOHandler Stuff - it works. So i don't have to care about the extra Variable
Rad Studio 12.1 Santorini
Offline
Pages: 1