i have built a RemObjectsSDK client server sample with Delphi, Indy and SSL
Pull requests and suggestions for better architectur are welcome.
Currently i have a problem, when i close the ssl client in Delphi. Is this a matter of the Indy-Component?
Erste Gelegenheit für Exception bei $00689366. Exception-Klasse $C0000005 mit Meldung
’access violation at 0x00689366: read of address 0x0000000c’.
Prozess SimpleSSLClientTCPDelphiIndy.exe (4584)
what links here: unit IdSSLOpenSSL.pas
3606 if (LParentIO <> nil) and (LParentIO.fSSLSocket <> nil) and
3607 -> (LParentIO.fSSLSocket <> Self) then
3608 begin
3609 SSL_copy_session_id(fSSL, LParentIO.fSSLSocket.fSSL);
3610 end;
from the first sight, this is problem in Indy library.
I see several workarounds:
rollback to stable version of indy,
update openssl libraries to latest version (at least OpenSSL 1.0.2g)
replace Indy components with synapse ones (TROIpHTTPServer + TROSynapseHTTPChannel) or with WinInet ones (TROWinHttpServer + TROWinInetHTTPChannel). WinInet version doesn’t use openssl libraries at all.
works my github sample with a stable indy version for you?
Do perform ROChannel socket I/O operations during setting ROChannel.Active := false;? Because the SSL IOHandler apparently receive data after a disconnect. The member fSSLSocket is there allready nil.
I think, the problem in Indy itself - it shouldn’t raise any AV …
after successful request, client-side waits for any data via TIdTCPConnection.IOHandler.ReadFromSource(false,24000,false) in background thread.
that should mean that no exceptions should be raised at all:
when channel is deactivated, it calls TIdTCPConnection.Disconnect that destroys TIdSSLSocket in TIdSSLIOHandlerSocketOpenSSL.Close (main thread).
TIdIOHandler.ReadFromSource in loop tries to read data and in next attempt calls TIdSSLSocket.Recv. TIdSSLSocket object is already destroyed and it causes AV.
I think, Indy should check disconnect state in TIdIOHandler.ReadFromSource and don’t try to read data for such cases.
from log:
Debug Output: 20:06:50.187:0:___ before TryReadByte Process SimpleSSLClientTCPDelphiIndy.exe (11948)
Debug Output: 20:06:52.319:0:Disconnect Process SimpleSSLClientTCPDelphiIndy.exe (11948)
First chance exception at $774CC54F. Exception class EAccessViolation with message 'Access violation at address 006A5382 in module 'SimpleSSLClientTCPDelphiIndy.exe'. Read of address 0000000C'. Process SimpleSSLClientTCPDelphiIndy.exe (11948)
i.e. it calls TIdIOHandler.ReadFromSource, 2 seconds later it calls TIdTCPConnection.Disconnect and later AV is fired
I can suggest to update IdSSLOpenSSL.pas (Indy sources) as:
function TIdSSLIOHandlerSocketOpenSSL.RecvEnc(var VBuffer: TIdBytes): Integer;
begin
if fSSLSocket = nil then Exit(-1); //added
Result := fSSLSocket.Recv(VBuffer)
end;
function TIdSSLIOHandlerSocketOpenSSL.CheckForError(ALastResult: Integer): Integer;
..
begin
if PassThrough then begin
Result := inherited CheckForError(ALastResult);
end else begin
if fSSLSocket = nil then Exit(ALastResult); // added
after these changes, your testcase works as expected