View Issue Details

IDProjectCategoryView StatusLast Update
0033745FPCFCLpublic2018-06-09 22:28
ReporterDimitrios Chr. IoannidisAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version3.0.4Product Build 
Target Version3.2.0Fixed in Version3.1.1 
Summary0033745: TInetSocket connect timeout.
DescriptionHere is a patch which ia adds support for timeout during connection.

Implemented with setting the socket non-blocking before connect and detecting if the socket is writable after the connect call. If the socket is not writable then a ESocketError seConnectTimeout is raised. Added a ConnectTimeout property to TSocketStream.

Tested in Windows 10, Debian 9 both x86_64.

Additional InformationAttached also is a patch for TFPHTTPClient for using the ConnectTimeout property and a test project.
TagsNo tags attached.
Fixed in Revision39199
FPCOldBugId
FPCTarget
Attached Files
  • ssockets-16052018.diff (6,480 bytes)
    Index: ssockets.pp
    ===================================================================
    --- ssockets.pp	(revision 38998)
    +++ ssockets.pp	(working copy)
    @@ -29,6 +29,7 @@
         seBindFailed,
         seListenFailed,
         seConnectFailed,
    +    seConnectTimeOut,
         seAcceptFailed,
         seAcceptWouldBlock,
         seIOTimeOut);
    @@ -82,8 +83,10 @@
         FWriteFlags: Integer;
         FHandler : TSocketHandler;
         FIOTimeout : Integer;
    +    FConnectTimeout : Integer;
         function GetLastError: Integer;
         Procedure GetSockOptions;
    +    procedure SetConnectTimeout(AValue: Integer);
         Procedure SetSocketOptions(Value : TSocketOptions);
         function GetLocalAddress: TSockAddr;
         function GetRemoteAddress: TSockAddr;
    @@ -102,6 +105,7 @@
         Property ReadFlags : Integer Read FReadFlags Write FReadFlags;
         Property WriteFlags : Integer Read FWriteFlags Write FWriteFlags;
         Property IOTimeout : Integer read FIOTimeout Write SetIOTimeout;
    +    Property ConnectTimeout : Integer read FConnectTimeout Write SetConnectTimeout;
       end;
     
       TConnectEvent = Procedure (Sender : TObject; Data : TSocketStream) Of Object;
    @@ -219,6 +223,8 @@
       Private
         FHost : String;
         FPort : Word;
    +    function SetSocketBlockingMode(ASocket: cint; ABlockMode: DWord; AFDSPtr: Pointer): Integer;
    +    function CheckSocketConnectTimeout(ASocket: cint; AFDSPtr: Pointer; ATimeVPtr: Pointer): Integer;
       Protected
       Public
         Constructor Create(const AHost: String; APort: Word; AHandler : TSocketHandler = Nil); Overload;
    @@ -250,10 +256,13 @@
     {$ifdef windows}
       winsock2, windows,
     {$endif}
    -  resolve;
    +  resolve,
    +  math;
     
     Const
       SocketWouldBlock = -2;
    +  SocketBlockingMode = 0;
    +  SocketNonBlockingMode = 1;
     
     { ---------------------------------------------------------------------
       ESocketError
    @@ -269,7 +278,8 @@
       strSocketAcceptWouldBlock = 'Accept would block on socket: %d';
       strSocketIOTimeOut = 'Failed to set IO Timeout to %d';
       strErrNoStream = 'Socket stream not assigned';
    -  
    +  strSocketConnectTimeOut = 'Connection to %s timed out.';
    +
     { TSocketHandler }
     
     Procedure TSocketHandler.SetSocket(const AStream: TSocketStream);
    @@ -374,6 +384,7 @@
         seAcceptFailed     : s := strSocketAcceptFailed;
         seAcceptWouldBLock : S := strSocketAcceptWouldBlock;
         seIOTimeout        : S := strSocketIOTimeOut;
    +    seConnectTimeOut    : s := strSocketConnectTimeout;
       end;
       s := Format(s, MsgArgs);
       inherited Create(s);
    @@ -427,6 +438,12 @@
       {$endif}
     end;
     
    +procedure TSocketStream.SetConnectTimeout(AValue: Integer);
    +begin
    +  if FConnectTimeout = AValue then Exit;
    +  FConnectTimeout := AValue;
    +end;
    +
     function TSocketStream.GetLastError: Integer;
     begin
       Result:=FHandler.LastError;
    @@ -945,7 +962,6 @@
       ---------------------------------------------------------------------}
     
     Constructor TInetSocket.Create(const AHost: String; APort: Word;AHandler : TSocketHandler = Nil);
    -
     Var
       S : Longint;
     
    @@ -958,12 +974,98 @@
         Connect;
     end;
     
    -Procedure TInetSocket.Connect;
    +function TInetSocket.SetSocketBlockingMode(ASocket: cint; ABlockMode: DWord; AFDSPtr: Pointer): Integer;
    +{$if defined(unix) or defined(windows)}
    +var
    +  locFDS: PFDSet;
    +{$endif}
    +{$ifdef unix}
    +  flags: Integer;
    +{$endif}
    +begin
    +  {$if defined(unix) or defined(windows)}
    +  locFDS := PFDSet(AFDSPtr);
    +  {$endif}
    +  if AblockMode = SocketNonBlockingMode then
    +   begin
    +  {$ifdef unix}
    +      locFDS^ := Default(TFDSet);
    +      fpFD_Zero(locFDS^);
    +      fpFD_Set(ASocket, locFDS^);
    +  {$else}
    +  {$ifdef windows}
    +      locFDS^ := Default(TFDSet);
    +      FD_Zero(locFDS^);
    +      FD_Set(ASocket, locFDS^);
    +  {$endif}
    +  {$endif}
    +   end;
    +  {$ifdef unix}
    +   flags := FpFcntl(ASocket, F_GetFl, 0);
    +   if AblockMode = SocketNonBlockingMode then
    +    result := FpFcntl(ASocket, F_SetFl, flags or O_NONBLOCK)
    +   else
    +    result := FpFcntl(ASocket, F_SetFl, flags and (not O_NONBLOCK));
    +  {$endif}
    +  {$ifdef windows}
    +   result := ioctlsocket(ASocket,FIONBIO,@ABlockMode);
    +  {$endif}
    +end;
     
    +function TInetSocket.CheckSocketConnectTimeout(ASocket: cint; AFDSPtr: Pointer; ATimeVPtr: Pointer): Integer;
    +{$if defined(unix) or defined(windows)}
    +var
    +  Err: LongInt = 1;
    +  ErrLen: LongInt;
    +  locTimeVal: PTimeVal;
    +  locFDS: PFDSet;
    +{$endif}
    +begin
    +  locTimeVal := PTimeVal(ATimeVPtr);
    +  locFDS := PFDSet(AFDSPtr);
    +  {$if defined(unix) or defined(windows)}
    +      locTimeVal^.tv_usec := 0;
    +      locTimeVal^.tv_sec := FConnectTimeout div 1000;
    +  {$endif}
    +  {$ifdef unix}
    +    Result := fpSelect(ASocket + 1, nil, locFDS, nil, locTimeVal); // 0 -> TimeOut
    +    if Result > 0 then
    +     begin
    +       ErrLen := SizeOf(Err);
    +       if fpFD_ISSET(ASocket, locFDS^) = 1 then
    +       begin
    +         fpgetsockopt(ASocket, SOL_SOCKET, SO_ERROR, @Err, @ErrLen);
    +         if Err <> 0 then // 0 -> connected
    +           Result := Err;
    +       end;
    +     end;
    +  {$else}
    +  {$ifdef windows}
    +    Result := select(ASocket + 1, nil, locFDS, nil, locTimeVal); // 0 -> TimeOut
    +    if Result > 0 then
    +     begin
    +       ErrLen := SizeOf(Err);
    +       if FD_ISSET(ASocket, locFDS^) then
    +       begin
    +         fpgetsockopt(ASocket, SOL_SOCKET, SO_ERROR, @Err, @ErrLen);
    +         if Err <> 0 then // 0 -> connected
    +           Result := Err;
    +       end;
    +     end;
    +  {$endif}
    +  {$endif}
    +end;
    +
    +procedure TInetSocket.Connect;
    +
     Var
       A : THostAddr;
       addr: TInetSockAddr;
       Res : Integer;
    +  {$if defined(unix) or defined(windows)}
    +  FDS: TFDSet;
    +  TimeV: TTimeVal;
    +  {$endif}
     
     begin
       A := StrToHostAddr(FHost);
    @@ -979,19 +1081,24 @@
       addr.sin_family := AF_INET;
       addr.sin_port := ShortHostToNet(FPort);
       addr.sin_addr.s_addr := HostToNet(a.s_addr);
    +  SetSocketBlockingMode(Handle, SocketNonBlockingMode, @FDS) ;
       {$ifdef unix}
       Res:=ESysEINTR;
         While (Res=ESysEINTR) do
       {$endif}
           Res:=fpConnect(Handle, @addr, sizeof(addr));
    +      Res:=CheckSocketConnectTimeout(Handle, @FDS, @TimeV);
    +      SetSocketBlockingMode(Handle, SocketBlockingMode, @FDS);
       If Not (Res<0) then
         if not FHandler.Connect then
           begin
    -      Res:=-1;
    +      if Res<>0 then Res:=-1;
           CloseSocket(Handle);
           end;
       If (Res<0) then
         Raise ESocketError.Create(seConnectFailed, [Format('%s:%d',[FHost, FPort])]);
    +  If (Res=0) then
    +    Raise ESocketError.Create(seConnectTimeOut, [Format('%s:%d',[FHost, FPort])]);
     end;
     
     { ---------------------------------------------------------------------
    
    ssockets-16052018.diff (6,480 bytes)
  • fphttpclient-16052018.diff (2,715 bytes)
    Index: fphttpclient.pp
    ===================================================================
    --- fphttpclient.pp	(revision 38998)
    +++ fphttpclient.pp	(working copy)
    @@ -80,6 +80,7 @@
         FOnRedirect: TRedirectEvent;
         FPassword: String;
         FIOTimeout: Integer;
    +    FConnectTimeout: Integer;
         FSentCookies,
         FCookies: TStrings;
         FHTTPVersion: String;
    @@ -100,6 +101,7 @@
         function GetCookies: TStrings;
         function GetProxy: TProxyData;
         Procedure ResetResponse;
    +    procedure SetConnectTimeout(AValue: Integer);
         Procedure SetCookies(const AValue: TStrings);
         procedure SetHTTPVersion(const AValue: String);
         procedure SetKeepConnection(AValue: Boolean);
    @@ -273,6 +275,7 @@
       Protected
         // Timeouts
         Property IOTimeout : Integer read FIOTimeout write SetIOTimeout;
    +    Property ConnectTimeout : Integer read FConnectTimeout write SetConnectTimeout;
         // Before request properties.
         // Additional headers for request. Host; and Authentication are automatically added.
         Property RequestHeaders : TStrings Read FRequestHeaders Write SetRequestHeaders;
    @@ -332,6 +335,7 @@
         Property KeepConnection;
         Property Connected;
         Property IOTimeout;
    +    Property ConnectTimeout;
         Property RequestHeaders;
         Property RequestBody;
         Property ResponseHeaders;
    @@ -502,6 +506,12 @@
         FSocket.IOTimeout:=AValue;
     end;
     
    +procedure TFPCustomHTTPClient.SetConnectTimeout(AValue: Integer);
    +begin
    +  if FConnectTimeout = AValue then Exit;
    +  FConnectTimeout := AValue;
    +end;
    +
     function TFPCustomHTTPClient.IsConnected: Boolean;
     begin
       Result := Assigned(FSocket);
    @@ -605,6 +615,8 @@
       try
         if FIOTimeout<>0 then
           FSocket.IOTimeout:=FIOTimeout;
    +    if FConnectTimeout<>0 then
    +      FSocket.ConnectTimeout:=FConnectTimeout;
         FSocket.Connect;
       except
         FreeAndNil(FSocket);
    @@ -1199,7 +1211,6 @@
       const AMethod: string; AStream: TStream;
       const AAllowedResponseCodes: array of Integer;
       AHeadersOnly, AIsHttps: Boolean);
    -
     Var
       CHost: string;
       CPort: Word;
    @@ -1220,7 +1231,6 @@
       const AMethod: string; AStream: TStream;
       const AAllowedResponseCodes: array of Integer;
       AHeadersOnly, AIsHttps: Boolean);
    -
     Var
       T: Boolean;
       CHost: string;
    @@ -1276,6 +1286,7 @@
       inherited Create(AOwner);
       // Infinite timeout on most platforms
       FIOTimeout:=0;
    +  FConnectTimeout:=3000;
       FRequestHeaders:=TStringList.Create;
       FRequestHeaders.NameValueSeparator:=':';
       FResponseHeaders:=TStringList.Create;
    @@ -1361,7 +1372,6 @@
       FBuffer:='';
     end;
     
    -
     procedure TFPCustomHTTPClient.HTTPMethod(const AMethod, AURL: String;
       Stream: TStream; const AllowedResponseCodes: array of Integer);
     
    
  • ConnectTimeoutTest.pas (311 bytes)
    program ConnectTimeoutTest;
    uses
      fphttpclient;
    var
      cli: TFPHTTPClient;
    begin
      cli := TFPHTTPClient.Create(nil);
      cli.ConnectTimeout := 1000; // Such short value most probably will timeout .....
      try
        writeln(cli.Get('http://wiki.freepascal.org/'));
      finally
        cli.Free;
      end;
    end.
    
    

Activities

Dimitrios Chr. Ioannidis

2018-05-16 17:12

reporter  

ssockets-16052018.diff (6,480 bytes)
Index: ssockets.pp
===================================================================
--- ssockets.pp	(revision 38998)
+++ ssockets.pp	(working copy)
@@ -29,6 +29,7 @@
     seBindFailed,
     seListenFailed,
     seConnectFailed,
+    seConnectTimeOut,
     seAcceptFailed,
     seAcceptWouldBlock,
     seIOTimeOut);
@@ -82,8 +83,10 @@
     FWriteFlags: Integer;
     FHandler : TSocketHandler;
     FIOTimeout : Integer;
+    FConnectTimeout : Integer;
     function GetLastError: Integer;
     Procedure GetSockOptions;
+    procedure SetConnectTimeout(AValue: Integer);
     Procedure SetSocketOptions(Value : TSocketOptions);
     function GetLocalAddress: TSockAddr;
     function GetRemoteAddress: TSockAddr;
@@ -102,6 +105,7 @@
     Property ReadFlags : Integer Read FReadFlags Write FReadFlags;
     Property WriteFlags : Integer Read FWriteFlags Write FWriteFlags;
     Property IOTimeout : Integer read FIOTimeout Write SetIOTimeout;
+    Property ConnectTimeout : Integer read FConnectTimeout Write SetConnectTimeout;
   end;
 
   TConnectEvent = Procedure (Sender : TObject; Data : TSocketStream) Of Object;
@@ -219,6 +223,8 @@
   Private
     FHost : String;
     FPort : Word;
+    function SetSocketBlockingMode(ASocket: cint; ABlockMode: DWord; AFDSPtr: Pointer): Integer;
+    function CheckSocketConnectTimeout(ASocket: cint; AFDSPtr: Pointer; ATimeVPtr: Pointer): Integer;
   Protected
   Public
     Constructor Create(const AHost: String; APort: Word; AHandler : TSocketHandler = Nil); Overload;
@@ -250,10 +256,13 @@
 {$ifdef windows}
   winsock2, windows,
 {$endif}
-  resolve;
+  resolve,
+  math;
 
 Const
   SocketWouldBlock = -2;
+  SocketBlockingMode = 0;
+  SocketNonBlockingMode = 1;
 
 { ---------------------------------------------------------------------
   ESocketError
@@ -269,7 +278,8 @@
   strSocketAcceptWouldBlock = 'Accept would block on socket: %d';
   strSocketIOTimeOut = 'Failed to set IO Timeout to %d';
   strErrNoStream = 'Socket stream not assigned';
-  
+  strSocketConnectTimeOut = 'Connection to %s timed out.';
+
 { TSocketHandler }
 
 Procedure TSocketHandler.SetSocket(const AStream: TSocketStream);
@@ -374,6 +384,7 @@
     seAcceptFailed     : s := strSocketAcceptFailed;
     seAcceptWouldBLock : S := strSocketAcceptWouldBlock;
     seIOTimeout        : S := strSocketIOTimeOut;
+    seConnectTimeOut    : s := strSocketConnectTimeout;
   end;
   s := Format(s, MsgArgs);
   inherited Create(s);
@@ -427,6 +438,12 @@
   {$endif}
 end;
 
+procedure TSocketStream.SetConnectTimeout(AValue: Integer);
+begin
+  if FConnectTimeout = AValue then Exit;
+  FConnectTimeout := AValue;
+end;
+
 function TSocketStream.GetLastError: Integer;
 begin
   Result:=FHandler.LastError;
@@ -945,7 +962,6 @@
   ---------------------------------------------------------------------}
 
 Constructor TInetSocket.Create(const AHost: String; APort: Word;AHandler : TSocketHandler = Nil);
-
 Var
   S : Longint;
 
@@ -958,12 +974,98 @@
     Connect;
 end;
 
-Procedure TInetSocket.Connect;
+function TInetSocket.SetSocketBlockingMode(ASocket: cint; ABlockMode: DWord; AFDSPtr: Pointer): Integer;
+{$if defined(unix) or defined(windows)}
+var
+  locFDS: PFDSet;
+{$endif}
+{$ifdef unix}
+  flags: Integer;
+{$endif}
+begin
+  {$if defined(unix) or defined(windows)}
+  locFDS := PFDSet(AFDSPtr);
+  {$endif}
+  if AblockMode = SocketNonBlockingMode then
+   begin
+  {$ifdef unix}
+      locFDS^ := Default(TFDSet);
+      fpFD_Zero(locFDS^);
+      fpFD_Set(ASocket, locFDS^);
+  {$else}
+  {$ifdef windows}
+      locFDS^ := Default(TFDSet);
+      FD_Zero(locFDS^);
+      FD_Set(ASocket, locFDS^);
+  {$endif}
+  {$endif}
+   end;
+  {$ifdef unix}
+   flags := FpFcntl(ASocket, F_GetFl, 0);
+   if AblockMode = SocketNonBlockingMode then
+    result := FpFcntl(ASocket, F_SetFl, flags or O_NONBLOCK)
+   else
+    result := FpFcntl(ASocket, F_SetFl, flags and (not O_NONBLOCK));
+  {$endif}
+  {$ifdef windows}
+   result := ioctlsocket(ASocket,FIONBIO,@ABlockMode);
+  {$endif}
+end;
 
+function TInetSocket.CheckSocketConnectTimeout(ASocket: cint; AFDSPtr: Pointer; ATimeVPtr: Pointer): Integer;
+{$if defined(unix) or defined(windows)}
+var
+  Err: LongInt = 1;
+  ErrLen: LongInt;
+  locTimeVal: PTimeVal;
+  locFDS: PFDSet;
+{$endif}
+begin
+  locTimeVal := PTimeVal(ATimeVPtr);
+  locFDS := PFDSet(AFDSPtr);
+  {$if defined(unix) or defined(windows)}
+      locTimeVal^.tv_usec := 0;
+      locTimeVal^.tv_sec := FConnectTimeout div 1000;
+  {$endif}
+  {$ifdef unix}
+    Result := fpSelect(ASocket + 1, nil, locFDS, nil, locTimeVal); // 0 -> TimeOut
+    if Result > 0 then
+     begin
+       ErrLen := SizeOf(Err);
+       if fpFD_ISSET(ASocket, locFDS^) = 1 then
+       begin
+         fpgetsockopt(ASocket, SOL_SOCKET, SO_ERROR, @Err, @ErrLen);
+         if Err <> 0 then // 0 -> connected
+           Result := Err;
+       end;
+     end;
+  {$else}
+  {$ifdef windows}
+    Result := select(ASocket + 1, nil, locFDS, nil, locTimeVal); // 0 -> TimeOut
+    if Result > 0 then
+     begin
+       ErrLen := SizeOf(Err);
+       if FD_ISSET(ASocket, locFDS^) then
+       begin
+         fpgetsockopt(ASocket, SOL_SOCKET, SO_ERROR, @Err, @ErrLen);
+         if Err <> 0 then // 0 -> connected
+           Result := Err;
+       end;
+     end;
+  {$endif}
+  {$endif}
+end;
+
+procedure TInetSocket.Connect;
+
 Var
   A : THostAddr;
   addr: TInetSockAddr;
   Res : Integer;
+  {$if defined(unix) or defined(windows)}
+  FDS: TFDSet;
+  TimeV: TTimeVal;
+  {$endif}
 
 begin
   A := StrToHostAddr(FHost);
@@ -979,19 +1081,24 @@
   addr.sin_family := AF_INET;
   addr.sin_port := ShortHostToNet(FPort);
   addr.sin_addr.s_addr := HostToNet(a.s_addr);
+  SetSocketBlockingMode(Handle, SocketNonBlockingMode, @FDS) ;
   {$ifdef unix}
   Res:=ESysEINTR;
     While (Res=ESysEINTR) do
   {$endif}
       Res:=fpConnect(Handle, @addr, sizeof(addr));
+      Res:=CheckSocketConnectTimeout(Handle, @FDS, @TimeV);
+      SetSocketBlockingMode(Handle, SocketBlockingMode, @FDS);
   If Not (Res<0) then
     if not FHandler.Connect then
       begin
-      Res:=-1;
+      if Res<>0 then Res:=-1;
       CloseSocket(Handle);
       end;
   If (Res<0) then
     Raise ESocketError.Create(seConnectFailed, [Format('%s:%d',[FHost, FPort])]);
+  If (Res=0) then
+    Raise ESocketError.Create(seConnectTimeOut, [Format('%s:%d',[FHost, FPort])]);
 end;
 
 { ---------------------------------------------------------------------
ssockets-16052018.diff (6,480 bytes)

Dimitrios Chr. Ioannidis

2018-05-16 17:12

reporter  

fphttpclient-16052018.diff (2,715 bytes)
Index: fphttpclient.pp
===================================================================
--- fphttpclient.pp	(revision 38998)
+++ fphttpclient.pp	(working copy)
@@ -80,6 +80,7 @@
     FOnRedirect: TRedirectEvent;
     FPassword: String;
     FIOTimeout: Integer;
+    FConnectTimeout: Integer;
     FSentCookies,
     FCookies: TStrings;
     FHTTPVersion: String;
@@ -100,6 +101,7 @@
     function GetCookies: TStrings;
     function GetProxy: TProxyData;
     Procedure ResetResponse;
+    procedure SetConnectTimeout(AValue: Integer);
     Procedure SetCookies(const AValue: TStrings);
     procedure SetHTTPVersion(const AValue: String);
     procedure SetKeepConnection(AValue: Boolean);
@@ -273,6 +275,7 @@
   Protected
     // Timeouts
     Property IOTimeout : Integer read FIOTimeout write SetIOTimeout;
+    Property ConnectTimeout : Integer read FConnectTimeout write SetConnectTimeout;
     // Before request properties.
     // Additional headers for request. Host; and Authentication are automatically added.
     Property RequestHeaders : TStrings Read FRequestHeaders Write SetRequestHeaders;
@@ -332,6 +335,7 @@
     Property KeepConnection;
     Property Connected;
     Property IOTimeout;
+    Property ConnectTimeout;
     Property RequestHeaders;
     Property RequestBody;
     Property ResponseHeaders;
@@ -502,6 +506,12 @@
     FSocket.IOTimeout:=AValue;
 end;
 
+procedure TFPCustomHTTPClient.SetConnectTimeout(AValue: Integer);
+begin
+  if FConnectTimeout = AValue then Exit;
+  FConnectTimeout := AValue;
+end;
+
 function TFPCustomHTTPClient.IsConnected: Boolean;
 begin
   Result := Assigned(FSocket);
@@ -605,6 +615,8 @@
   try
     if FIOTimeout<>0 then
       FSocket.IOTimeout:=FIOTimeout;
+    if FConnectTimeout<>0 then
+      FSocket.ConnectTimeout:=FConnectTimeout;
     FSocket.Connect;
   except
     FreeAndNil(FSocket);
@@ -1199,7 +1211,6 @@
   const AMethod: string; AStream: TStream;
   const AAllowedResponseCodes: array of Integer;
   AHeadersOnly, AIsHttps: Boolean);
-
 Var
   CHost: string;
   CPort: Word;
@@ -1220,7 +1231,6 @@
   const AMethod: string; AStream: TStream;
   const AAllowedResponseCodes: array of Integer;
   AHeadersOnly, AIsHttps: Boolean);
-
 Var
   T: Boolean;
   CHost: string;
@@ -1276,6 +1286,7 @@
   inherited Create(AOwner);
   // Infinite timeout on most platforms
   FIOTimeout:=0;
+  FConnectTimeout:=3000;
   FRequestHeaders:=TStringList.Create;
   FRequestHeaders.NameValueSeparator:=':';
   FResponseHeaders:=TStringList.Create;
@@ -1361,7 +1372,6 @@
   FBuffer:='';
 end;
 
-
 procedure TFPCustomHTTPClient.HTTPMethod(const AMethod, AURL: String;
   Stream: TStream; const AllowedResponseCodes: array of Integer);
 

Dimitrios Chr. Ioannidis

2018-05-16 17:15

reporter  

ConnectTimeoutTest.pas (311 bytes)
program ConnectTimeoutTest;
uses
  fphttpclient;
var
  cli: TFPHTTPClient;
begin
  cli := TFPHTTPClient.Create(nil);
  cli.ConnectTimeout := 1000; // Such short value most probably will timeout .....
  try
    writeln(cli.Get('http://wiki.freepascal.org/'));
  finally
    cli.Free;
  end;
end.

Dimitrios Chr. Ioannidis

2018-05-16 17:27

reporter   ~0108345

Last edited: 2018-06-09 22:01

View 2 revisions

Forgot to mention that the patches are against today's ( 16052018 ) fpc trunk.

Also there is a leftover in uses including the unit math in ssockets unit. I can upload a new patch which will fix it if you want.

Michael Van Canneyt

2018-06-09 14:26

administrator   ~0108780

Fixed, many tthanks for the patch.

I have changed the mechanism so that if the connection timeout is zero, a blocking version is used.

Dimitrios Chr. Ioannidis

2018-06-09 21:58

reporter   ~0108799

Last edited: 2018-06-09 22:00

View 2 revisions

I think that you missed to remove the math unit from the ssockets patch 0033745:0108345.

Could you please remove it from the uses clause ?

Michael Van Canneyt

2018-06-09 22:17

administrator   ~0108800

Removed, rev 39205. Thanks for pointing it out.

Dimitrios Chr. Ioannidis

2018-06-09 22:28

reporter   ~0108802

Thank you very much.

Issue History

Date Modified Username Field Change
2018-05-16 17:12 Dimitrios Chr. Ioannidis New Issue
2018-05-16 17:12 Dimitrios Chr. Ioannidis File Added: ssockets-16052018.diff
2018-05-16 17:12 Dimitrios Chr. Ioannidis File Added: fphttpclient-16052018.diff
2018-05-16 17:15 Dimitrios Chr. Ioannidis File Added: ConnectTimeoutTest.pas
2018-05-16 17:27 Dimitrios Chr. Ioannidis Note Added: 0108345
2018-05-16 23:39 Michael Van Canneyt Assigned To => Michael Van Canneyt
2018-05-16 23:39 Michael Van Canneyt Status new => assigned
2018-06-09 14:26 Michael Van Canneyt Fixed in Revision => 39199
2018-06-09 14:26 Michael Van Canneyt Note Added: 0108780
2018-06-09 14:26 Michael Van Canneyt Status assigned => resolved
2018-06-09 14:26 Michael Van Canneyt Fixed in Version => 3.1.1
2018-06-09 14:26 Michael Van Canneyt Resolution open => fixed
2018-06-09 14:26 Michael Van Canneyt Target Version => 3.2.0
2018-06-09 21:58 Dimitrios Chr. Ioannidis Note Added: 0108799
2018-06-09 21:58 Dimitrios Chr. Ioannidis Status resolved => feedback
2018-06-09 21:58 Dimitrios Chr. Ioannidis Resolution fixed => reopened
2018-06-09 22:00 Dimitrios Chr. Ioannidis Note Edited: 0108799 View Revisions
2018-06-09 22:01 Dimitrios Chr. Ioannidis Note Edited: 0108345 View Revisions
2018-06-09 22:17 Michael Van Canneyt Note Added: 0108800
2018-06-09 22:17 Michael Van Canneyt Status feedback => resolved
2018-06-09 22:17 Michael Van Canneyt Resolution reopened => fixed
2018-06-09 22:28 Dimitrios Chr. Ioannidis Note Added: 0108802
2018-06-09 22:28 Dimitrios Chr. Ioannidis Status resolved => closed