Skip to content

Commit 17fc1d3

Browse files
committed
TIdSecSocket.Readable now checks for socket errors
1 parent 3ce6e09 commit 17fc1d3

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

src/IdSSLOpenSSL.pas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ function TIdSSLIOHandlerSocketOpenSSL.Readable(AMSec: Integer = IdTimeoutDefault
838838
Exit;
839839

840840
if not fPassThrough and (fSSLSocket <> nil) then
841-
Result := fSSLSocket.Readable;
841+
Result := fSSLSocket.Readable in [sslDataAvailable,sslUnRecoverableError,sslEOF];
842842
until Result;
843843
end;
844844

src/IdSSLOpenSSLSocket.pas

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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);
14451447
end;
14461448

1447-
function TIdSSLSocket.Readable: Boolean;
1449+
function TIdSSLSocket.Readable: TIdSSLReadStatus;
14481450
var buf : byte;
14491451
Lr: integer;
14501452
begin
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;
14591478
end;
14601479

14611480
procedure TIdSSLSocket.DoShutdown;

0 commit comments

Comments
 (0)