Skip to content

Commit 76286e0

Browse files
Added timeout support
bumped dspec version
1 parent b7d9340 commit 76286e0

6 files changed

Lines changed: 326 additions & 179 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ __history
3737
/Tests/Win64
3838
/Tests/OSX32
3939
/Tests/__history
40+
*.delphilsp.json

Source/VSoft.HttpClient.WinHttpClient.pas

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ THttpClient = class(THttpClientBase, IHttpClient, IHttpClientInternal)
4242
FData : Pointer;
4343
FDataLength : DWORD;
4444

45+
4546
protected
4647
procedure OnHTTPCallback(hInternet: HINTERNET; dwInternetStatus: DWORD; lpvStatusInformation: Pointer; dwStatusInformationLength: DWORD);
4748
function OnHeadersAvailable(hRequest: HINTERNET; dwInternetStatus: DWORD; lpvStatusInformation: Pointer; dwStatusInformationLength: DWORD) : DWORD;
@@ -78,6 +79,16 @@ THttpClient = class(THttpClientBase, IHttpClient, IHttpClientInternal)
7879
function GetUseHttp2 : boolean;
7980
procedure SetUseHttp2(const value : boolean);
8081

82+
function GetConnectionTimeout : integer;
83+
procedure SetConnectionTimeout(const value : integer);
84+
85+
function GetSendTimeout : integer;
86+
procedure SetSendTimeout(const value : integer);
87+
88+
function GetResponseTimeout : integer;
89+
procedure SetResponseTimeout(const value : integer);
90+
91+
8192

8293
function CreateRequest(const resource : string) : TRequest;overload;
8394
function CreateRequest(const uri : IUri) : TRequest;overload;
@@ -248,6 +259,11 @@ function THttpClient.GetBaseUri: string;
248259
end;
249260

250261

262+
function THttpClient.GetConnectionTimeout: integer;
263+
begin
264+
result := FConnectionTimeout;
265+
end;
266+
251267
function THttpClient.GetPassword: string;
252268
begin
253269
result := FPassword;
@@ -282,6 +298,16 @@ function THttpClient.GetResourceFromRequest(const request: TRequest): string;
282298
end;
283299
end;
284300

301+
function THttpClient.GetResponseTimeout: integer;
302+
begin
303+
result := FResponseTimeout;
304+
end;
305+
306+
function THttpClient.GetSendTimeout: integer;
307+
begin
308+
result := FSendTimeout;
309+
end;
310+
285311
function THttpClient.GetUri: IUri;
286312
begin
287313
result := FUri;
@@ -694,6 +720,13 @@ function THttpClient.Send(const request: TRequest; const cancellationToken: ICan
694720
FClientError := GetLastError;
695721
raise EHttpClientException.Create(ClientErrorToString(FClientError), FClientError);
696722
end;
723+
724+
if WinHttpSetTimeouts(hRequest, request.ConnectionTimeout, request.ConnectionTimeout, request.SendTimeout, request.ResponseTimeout) = False then
725+
raise EHttpClientException.Create(SysErrorMessage(GetLastError), GetLastError);
726+
727+
728+
//set timeouts on the request.
729+
697730
try
698731
pCallback := WinHttpSetStatusCallback(hRequest, _HTTPCallback, WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS + WINHTTP_CALLBACK_FLAG_REDIRECT, 0);
699732

@@ -799,11 +832,26 @@ procedure THttpClient.SetBaseUri(const value: string);
799832
FUri.BaseUriString := value;
800833
end;
801834

835+
procedure THttpClient.SetConnectionTimeout(const value: integer);
836+
begin
837+
FConnectionTimeout := value;
838+
end;
839+
802840
procedure THttpClient.SetPassword(const value: string);
803841
begin
804842
FPassword := value;
805843
end;
806844

845+
procedure THttpClient.SetResponseTimeout(const value: integer);
846+
begin
847+
FResponseTimeout := value;
848+
end;
849+
850+
procedure THttpClient.SetSendTimeout(const value: integer);
851+
begin
852+
FSendTimeout := value;
853+
end;
854+
807855
procedure THttpClient.SetUseHttp2(const value: boolean);
808856
begin
809857
FUseHttp2 := value;

Source/VSoft.HttpClient.pas

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,15 @@ TRequest = class;
7373
end;
7474

7575
THttpClientBase = class(TInterfacedObject)
76+
protected
77+
FConnectionTimeout: Integer;
78+
FSendTimeout: Integer;
79+
FResponseTimeout: Integer;
7680
public
7781
procedure ReleaseRequest(const request : TRequest);virtual;abstract;
82+
property ConnectionTimeout: Integer read FConnectionTimeout write FConnectionTimeout;
83+
property SendTimeout: Integer read FSendTimeout write FSendTimeout;
84+
property ResponseTimeout: Integer read FResponseTimeout write FResponseTimeout;
7885
end;
7986

8087

@@ -97,6 +104,10 @@ TRequest = class
97104
FProxyUserName : string;
98105
FProxyPassword : string;
99106

107+
FConnectionTimeout: Integer;
108+
FSendTimeout: Integer;
109+
FResponseTimeout: Integer;
110+
100111
FURI : IUri;
101112
protected
102113
function GetHeaders : TStrings;
@@ -203,6 +214,11 @@ TRequest = class
203214
property Passsword : string read FPassword write FPassword;
204215
property ProxyUserName : string read FProxyUserName write FProxyUserName;
205216
property ProxyPassword : string read FProxyPassword write FProxyPassword;
217+
218+
property ConnectionTimeout: Integer read FConnectionTimeout write FConnectionTimeout;
219+
property SendTimeout: Integer read FSendTimeout write FSendTimeout;
220+
property ResponseTimeout: Integer read FResponseTimeout write FResponseTimeout;
221+
206222
end;
207223

208224

@@ -233,6 +249,15 @@ TRequest = class
233249
function GetPassword : string;
234250
procedure SetPassword(const value : string);
235251

252+
function GetConnectionTimeout : integer;
253+
procedure SetConnectionTimeout(const value : integer);
254+
255+
function GetSendTimeout : integer;
256+
procedure SetSendTimeout(const value : integer);
257+
258+
function GetResponseTimeout : integer;
259+
procedure SetResponseTimeout(const value : integer);
260+
236261
function CreateRequest(const resource : string) : TRequest;overload;
237262
function CreateRequest(const uri : IUri) : TRequest;overload;
238263

@@ -246,13 +271,31 @@ TRequest = class
246271
property UserName : string read GetUserName write SetUserName;
247272
property Password : string read GetPassword write SetPassword;
248273

274+
property ConnectionTimeout: Integer read GetConnectionTimeout write SetConnectionTimeout;
275+
property SendTimeout: Integer read GetSendTimeout write SetSendTimeout;
276+
property ResponseTimeout: Integer read GetResponseTimeout write SetResponseTimeout;
277+
278+
249279
property UseHttp2 : boolean read GetUseHttp2 write SetUseHttp2;
280+
281+
250282
end;
251283

252284
THttpClientFactory = class
253-
class function CreateClient(const uri: string): IHttpClient;overload;
254-
class function CreateClient(const uri: IUri): IHttpClient;overload;
285+
private
286+
class
287+
var
288+
FDefaultConnectionTimeout: Integer;
289+
FDefaultSendTimeout: Integer;
290+
FDefaultResponseTimeout: Integer;
291+
class constructor Create;
292+
public
293+
class function CreateClient(const uri: string): IHttpClient;overload;
294+
class function CreateClient(const uri: IUri): IHttpClient;overload;
255295

296+
class property DefaultConnectionTimeout: Integer read FDefaultConnectionTimeout write FDefaultConnectionTimeout;
297+
class property DefaultSendTimeout: Integer read FDefaultSendTimeout write FDefaultSendTimeout;
298+
class property DefaultResponseTimeout: Integer read FDefaultResponseTimeout write FDefaultResponseTimeout;
256299
end;
257300

258301
EHttpClientException = class(Exception)
@@ -402,6 +445,9 @@ constructor TRequest.Create(const client: THttpClientBase; const uri: IUri);
402445
for queryParam in uri.QueryParams do
403446
WithParameter(queryParam.Name, queryParam.Value);
404447
end;
448+
FConnectionTimeout := client.ConnectionTimeout;
449+
FSendTimeout := client.SendTimeout;
450+
FResponseTimeout := client.ResponseTimeout;
405451
end;
406452

407453
function CombineUriParts(const a, b : string) : string;
@@ -596,6 +642,7 @@ function TRequest.GetCharSet: string;
596642
result := '';
597643
end;
598644

645+
599646
function TRequest.GetContentLength: Int64;
600647
var
601648
stream : TStream;
@@ -627,6 +674,7 @@ function TRequest.GetResource: string;
627674
result := FURI.AbsolutePath;
628675
end;
629676

677+
630678
function TRequest.GetUrlSegments: TStrings;
631679
begin
632680
result := FUrlSegments;
@@ -776,6 +824,7 @@ procedure TRequest.SetAcceptLanguage(const value: string);
776824
FHeaders.Values[cAcceptLanguageHeader] := value;
777825
end;
778826

827+
779828
procedure TRequest.SetContentType(const value: string);
780829
begin
781830
FHeaders.Values[cContentTypeHeader] := value;
@@ -787,6 +836,7 @@ procedure TRequest.SetResource(const value: string);
787836
end;
788837

789838

839+
790840
function TRequest.WillFollowRedirects: TRequest;
791841
begin
792842
FFollowRedirects := true;
@@ -907,13 +957,23 @@ class function THttpClientFactory.CreateClient(const uri : string): IHttpClient;
907957
begin
908958
if not TUriFactory.TryParseWithError(uri, true, theUri, error) then
909959
raise EArgumentOutOfRangeException.Create('Invalid Uri : ' + error );
960+
result := THttpClientFactory.CreateClient(theUri);
961+
end;
910962

911-
result := THttpClient.Create(theUri);
963+
class constructor THttpClientFactory.Create;
964+
begin
965+
//1min defaults
966+
FDefaultConnectionTimeout := 60000;
967+
FDefaultSendTimeout := 60000;
968+
FDefaultResponseTimeout := 60000;
912969
end;
913970

914971
class function THttpClientFactory.CreateClient(const uri: IUri): IHttpClient;
915972
begin
916973
result := THttpClient.Create(uri);
974+
result.ConnectionTimeout := FDefaultConnectionTimeout;
975+
result.SendTimeout := FDefaultSendTimeout;
976+
result.ResponseTimeout := FDefaultResponseTimeout;
917977
end;
918978

919979
{ EHttpClientException }

0 commit comments

Comments
 (0)