From fde13f5c0043517c2c96278c9dcd57505de4474d Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 21 Oct 2020 19:18:44 +1100 Subject: [PATCH 1/2] Fix issues with thread leakage --- Lib/Protocols/IdCustomHTTPServer.pas | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Lib/Protocols/IdCustomHTTPServer.pas b/Lib/Protocols/IdCustomHTTPServer.pas index 4374df181..5f54c9bc5 100644 --- a/Lib/Protocols/IdCustomHTTPServer.pas +++ b/Lib/Protocols/IdCustomHTTPServer.pas @@ -182,6 +182,7 @@ interface Id_TId_HTTPServer_ParseParams = True; Id_TId_HTTPServer_SessionState = False; Id_TId_HTTPSessionTimeOut = 0; + Id_TId_HTTPConnectionTimeOut = -1; Id_TId_HTTPAutoStartSession = False; Id_TId_HTTPMaximumHeaderLineCount = 1024; @@ -420,6 +421,7 @@ TIdCustomHTTPServer = class(TIdCustomTCPServer) FImplicitSessionList: Boolean; FSessionState: Boolean; FSessionTimeOut: Integer; + FConnectionTimeOut : Integer; // FOnCreatePostStream: TIdHTTPCreatePostStream; FOnDoneWithPostStream: TIdHTTPDoneWithPostStream; @@ -499,6 +501,7 @@ TIdCustomHTTPServer = class(TIdCustomTCPServer) property ServerSoftware: string read FServerSoftware write FServerSoftware; property SessionState: Boolean read FSessionState write SetSessionState default Id_TId_HTTPServer_SessionState; property SessionTimeOut: Integer read FSessionTimeOut write FSessionTimeOut default Id_TId_HTTPSessionTimeOut; + property ConnectionTimeOut : Integer read FConnectionTimeOut write FConnectionTimeOut default Id_TId_HTTPConnectionTimeOut; property SessionIDCookieName: string read FSessionIDCookieName write SetSessionIDCookieName stored IsSessionIDCookieNameStored; // property OnCommandError: TIdHTTPCommandError read FOnCommandError write FOnCommandError; @@ -660,9 +663,9 @@ function DecodeHTTPCommand(const ACmd: string): THTTPCommandType; procedure Run; override; end; // class -function InternalReadLn(AIOHandler: TIdIOHandler): String; +function InternalReadLn(AIOHandler: TIdIOHandler; ATimeout : Integer): String; begin - Result := AIOHandler.ReadLn; + Result := AIOHandler.ReadLn(LF, ATimeout); if AIOHandler.ReadLnTimedout then begin raise EIdReadTimeout.Create(RSReadTimeout); end; @@ -903,6 +906,7 @@ procedure TIdCustomHTTPServer.InitComponent; FKeepAlive := Id_TId_HTTPServer_KeepAlive; FMaximumHeaderLineCount := Id_TId_HTTPMaximumHeaderLineCount; FSessionIDCookieName := GSessionIDCookie; + FConnectionTimeOut := Id_TId_HTTPConnectionTimeOut; end; // under ARC, all weak references to a freed object get nil'ed automatically @@ -1210,7 +1214,7 @@ function TIdCustomHTTPServer.DoExecute(AContext:TIdContext): boolean; // not start at Position 0. LRequestInfo.PostStream.Position := 0; repeat - S := InternalReadLn(LIOHandler); + S := InternalReadLn(LIOHandler, FConnectionTimeout); I := IndyPos(';', S); {do not localize} if I > 0 then begin S := Copy(S, 1, I - 1); @@ -1220,10 +1224,10 @@ function TIdCustomHTTPServer.DoExecute(AContext:TIdContext): boolean; Break; end; LIOHandler.ReadStream(LRequestInfo.PostStream, Size); - InternalReadLn(LIOHandler); // CRLF at end of chunk data + InternalReadLn(LIOHandler, FConnectionTimeout); // CRLF at end of chunk data until False; // skip trailer headers - repeat until InternalReadLn(LIOHandler) = ''; + repeat until InternalReadLn(LIOHandler, FConnectionTimeout) = ''; // TODO: seek back to the original Position where CreatePostStream() // left it, not all the way back to Position 0. LRequestInfo.PostStream.Position := 0; @@ -1281,7 +1285,7 @@ function TIdCustomHTTPServer.DoExecute(AContext:TIdContext): boolean; try LConn := AContext.Connection; repeat - LInputLine := InternalReadLn(LConn.IOHandler); + LInputLine := InternalReadLn(LConn.IOHandler, FConnectionTimeout); i := RPos(' ', LInputLine, -1); {Do not Localize} if i = 0 then begin raise EIdHTTPErrorParsingCommand.Create(RSHTTPErrorParsingCommand); From 075554b3467c0f555daf3f34259584733502cf3b Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 22 Oct 2020 11:29:25 +1100 Subject: [PATCH 2/2] update IdHl7 so the thread uses TIdThread not TThread directly --- Lib/Protocols/IdHL7.pas | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/Protocols/IdHL7.pas b/Lib/Protocols/IdHL7.pas index 5e65cb07b..1b6508fd2 100644 --- a/Lib/Protocols/IdHL7.pas +++ b/Lib/Protocols/IdHL7.pas @@ -139,6 +139,7 @@ interface IdTCPClient, IdTCPConnection, IdTCPServer, + IdThread, SysUtils; const @@ -198,12 +199,12 @@ EHL7CommunicationError = class(EIdException) TIdHL7 = class; TIdHL7ConnCountEvent = procedure (ASender : TIdHL7; AConnCount : integer) of object; - TIdHL7ClientThread = class(TThread) + TIdHL7ClientThread = class(TIdThread) Protected FClient: TIdTCPClient; FCloseEvent: TIdLocalEvent; FOwner: TIdHL7; - procedure Execute; Override; + procedure Run; Override; procedure PollStack; Public constructor Create(aOwner: TIdHL7); @@ -1186,7 +1187,7 @@ procedure TIdHL7ClientThread.PollStack; until Terminated or not FClient.Connected; end; -procedure TIdHL7ClientThread.Execute; +procedure TIdHL7ClientThread.Run; var LRecTime: TDateTime; begin