@@ -69,6 +69,8 @@ TIdSSLByteArray = record
6969 Data: PByte;
7070 end ;
7171
72+ TIdSSLReadStatus = (sslDataAvailable, sslNoData, sslEOF, sslUnrecoverableError);
73+
7274 TIdSSLSocket = class ;
7375
7476 // TIdSSLIOHandlerSocketOpenSSL and TIdServerIOHandlerSSLOpenSSL have some common
@@ -191,7 +193,7 @@ TIdSSLSocket = class(TObject)
191193 function GetSessionIDAsString :String;
192194 procedure SetCipherList (CipherList: String);
193195 function GetCallbackHelper : IIdSSLOpenSSLCallbackHelper;
194- function Readable : Boolean ;
196+ function Readable : TIdSSLReadStatus ;
195197 procedure DoShutdown ;
196198 function GetSSL : PSSL;
197199 function GetSSLError (retCode: Integer): Integer;
@@ -1444,18 +1446,35 @@ function TIdSSLSocket.GetCallbackHelper: IIdSSLOpenSSLCallbackHelper;
14441446 fParent.GetInterface(IIdSSLOpenSSLCallbackHelper,Result);
14451447end ;
14461448
1447- function TIdSSLSocket.Readable : Boolean ;
1449+ function TIdSSLSocket.Readable : TIdSSLReadStatus ;
14481450var buf : byte;
14491451 Lr: integer;
14501452begin
1453+ Result := sslNoData;
14511454 { Confirm that there is application data to be read.}
14521455 Lr := SSL_peek(fSSL, @buf, 1 );
1453- { Return true if application data pending, or if it looks like we have disconnected}
1454- Result := (Lr > 0 );
1455- if not Result and
1456- (SSL_get_error(fSSL,Lr) = SSL_ERROR_ZERO_RETURN) and
1457- (SSL_get_shutdown(fSSL) = SSL_RECEIVED_SHUTDOWN) then
1458- Result := true;
1456+ { Return sslDataAvailable if application data pending, or if it looks like we have disconnected,
1457+ sslUnrecoverableError if error state indicates thus,
1458+ sslEOF if the connection has been shutdown, or
1459+ sslNoData otherwise => try again later}
1460+ if Lr > 0 then
1461+ Result := sslDataAvailable
1462+ else
1463+ begin
1464+ case SSL_get_error(fSSL,Lr) of
1465+ SSL_ERROR_SSL, SSL_ERROR_SYSCALL:
1466+ if SSL_get_shutdown(fSSL) = SSL_RECEIVED_SHUTDOWN then
1467+ Result := sslEOF
1468+ else
1469+ Result := sslUnrecoverableError;
1470+
1471+ SSL_ERROR_ZERO_RETURN:
1472+ if SSL_get_shutdown(fSSL) = SSL_RECEIVED_SHUTDOWN then
1473+ Result := sslEOF;
1474+
1475+ { anything else return the function default - sslNoData (yet)}
1476+ end ;
1477+ end ;
14591478end ;
14601479
14611480procedure TIdSSLSocket.DoShutdown ;
0 commit comments