mORMot and Open Source friends
Check-in [f673bbed94]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:{1509} added SendTimeout,ReceiveTimeout,ConnectTimeout optional parameters to TSQLHttpClientGeneric.Create
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: f673bbed94dbfccd971735511ba79702d96c0e55
User & Date: ab 2015-06-19 13:24:45
Context
2015-06-19
17:10
{1510} added TSQLRestStorageInMemory.LoadFromResource method check-in: b00e9fe08f user: ab tags: trunk
13:24
{1509} added SendTimeout,ReceiveTimeout,ConnectTimeout optional parameters to TSQLHttpClientGeneric.Create check-in: f673bbed94 user: ab tags: trunk
13:23
{1508} fixed Delphi 5 compilation issue check-in: 007c7f8ca6 user: ab tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to SQLite3/mORMotHttpClient.pas.

186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202


203



204
205
206
207
208
209
210
...
318
319
320
321
322
323
324





325



326
327
328
329
330
331
332
...
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
...
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
...
529
530
531
532
533
534
535


536
537
538
539
540
541
542
...
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576




577
578
579
580
581
582
583
...
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
...
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817

818
819
820
821
822
823
824
...
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
    fSendTimeout, fReceiveTimeout, fConnectTimeout: DWORD;
    fExtendedOptions: THttpRequestExtendedOptions;
    procedure SetCompression(Value: TSQLHttpCompressions);
    procedure SetKeepAliveMS(Value: cardinal);
    constructor RegisteredClassCreateFrom(aModel: TSQLModel;
      aDefinition: TSynConnectionDefinition); override;
    /// process low-level HTTP/1.1 request
    // - call by URI() public method
    // - returns 200,202,204 if OK, http status error otherwise in result.Lo
    // - returns Server-InternalState in result.Hi
    function InternalRequest(const url, method: RawUTF8;
      var Header, Data, DataType: RawUTF8): Int64Rec; virtual; abstract;
    /// method calling the RESTful server fServer via HTTP/1.1
    // - calls the InternalRequest() protected method
    procedure InternalURI(var Call: TSQLRestURIParams); override;
  public
    /// connect to TSQLHttpServer on aServer:aPort


    constructor Create(const aServer, aPort: AnsiString; aModel: TSQLModel); reintroduce; overload; virtual;



    /// connect to TSQLHttpServer via 'address:port/root' URI format
    // - if port is not specified, aDefaultPort is used
    // - if root is not specified, aModel.Root is used
    constructor Create(const aServer: TSQLRestServerURIString; aModel: TSQLModel;
      aDefaultPort: integer); reintroduce; overload; 
    /// connnect to a LogView HTTP Server for remote logging
    // - will associate the EchoCustom callback of the log class to this server
................................................................................
    /// overridden protected method to handle HTTP connection
    function InternalCheckOpen: boolean; override;
    /// set the fWinAPI class
    // - the overridden implementation should set the expected fWinAPIClass
    procedure InternalSetClass; virtual; abstract;
  public
    /// connect to TSQLHttpServer on aServer:aPort with the default settings





    constructor Create(const aServer, aPort: AnsiString; aModel: TSQLModel); overload; override;



    /// connect to TSQLHttpServer on aServer:aPort
    // - optional aProxyName may contain the name of the proxy server to use,
    // and aProxyByPass an optional semicolon delimited list of host names or
    // IP addresses, or both, that should not be routed through the proxy
    // - you can customize the default client timeouts by setting appropriate
    // ConnectTimeout, SendTimeout and ReceiveTimeout parameters (in ms) - note
    // that after creation of this instance, the connection is tied to those
................................................................................
procedure TSQLHttpClientGeneric.SetKeepAliveMS(Value: cardinal);
begin
  fKeepAliveMS := Value;
  InternalClose; // force re-create connection at next request
end;

constructor TSQLHttpClientGeneric.Create(const aServer, aPort: AnsiString;
  aModel: TSQLModel);
begin
  inherited Create(aModel);
  fServer := aServer;
  fPort := aPort;
  fKeepAliveMS := 20000; // 20 seconds connection keep alive by default
  fCompression := [hcSynLZ];
  fConnectTimeout := HTTP_DEFAULT_CONNECTTIMEOUT;
  fSendTimeout := HTTP_DEFAULT_SENDTIMEOUT;
  fReceiveTimeout := HTTP_DEFAULT_RECEIVETIMEOUT;
end;

constructor TSQLHttpClientGeneric.CreateForRemoteLogging(const aServer: AnsiString;
  aLogClass: TSynLogClass; aPort: Integer; const aRoot: RawUTF8);
var aModel: TSQLModel;
begin
  if not Assigned(aLogClass) then
................................................................................
    exit;
  inherited DefinitionTo(Definition); // save Kind + User/Password
  if fHttps then
    Definition.ServerName := 'https://';
  Definition.ServerName := FormatUTF8('%%:%',[Definition.ServerName,fServer,fPort]);
  Definition.DatabaseName := UrlEncode([
   'IgnoreSSLCertificateErrors',ord(fExtendedOptions.IgnoreSSLCertificateErrors),
   'SendTimeout',fSendTimeout,'ReceiveTimeout',fReceiveTimeout,
   'ProxyName',fProxyName,'ProxyByPass',fProxyByPass]);
  Definition.DatabaseName := copy(Definition.DatabaseName,2,MaxInt); // trim leading '?'
end;

constructor TSQLHttpClientGeneric.RegisteredClassCreateFrom(aModel: TSQLModel;
  aDefinition: TSynConnectionDefinition);
var URI: TURI;
................................................................................
    tmp: RawUTF8;
begin
  URI.From(aDefinition.ServerName);
  Create(URI.Server,URI.Port,aModel);
  fHttps := URI.Https;
  P := Pointer(aDefinition.DataBaseName);
  while P<>nil do begin


    if UrlDecodeCardinal(P,'SENDTIMEOUT',V) then
      fSendTimeout := V else
    if UrlDecodeCardinal(P,'RECEIVETIMEOUT',V) then
      fReceiveTimeout := V else
    if UrlDecodeValue(P,'PROXYNAME',tmp) then
      fProxyName := CurrentAnsiConvert.UTF8ToAnsi(tmp) else
    if UrlDecodeValue(P,'PROXYBYPASS',tmp) then
................................................................................


{ TSQLHttpClientWinSock }

function TSQLHttpClientWinSock.InternalCheckOpen: boolean;
begin
  if fSocket<>nil then begin
    result := true;
    exit;
  end;
  EnterCriticalSection(fMutex);
  try
    try
      if fSocketClass=nil then
        fSocketClass := THttpClientSocket;
      fSocket := fSocketClass.Open(fServer,fPort,cslTCP,fConnectTimeout);




      {$ifdef USETCPPREFIX}
      fSocket.TCPPrefix := 'magic';
      {$endif}
      // note that first registered algo will be the prefered one
      if hcSynShaAes in Compression then
        // global SHA-256 / AES-256-CTR encryption + SynLZ compression
        fSocket.RegisterCompress(CompressShaAes,0); // CompressMinSize=0
................................................................................


{ TSQLHttpClientWebsockets }

function TSQLHttpClientWebsockets.InternalCheckOpen: boolean;
begin
  if fSocket<>nil then begin
    result := true;
    exit;
  end;
  if fSocketClass=nil then
    fSocketClass := THttpClientWebSockets;
  result := inherited InternalCheckOpen;
  if result then
    with fWebSocketParams do
................................................................................
  fProxyByPass := aProxyByPass;
  fSendTimeout := SendTimeout;
  fReceiveTimeout := ReceiveTimeout;
  fConnectTimeout := ConnectTimeout;
end;

constructor TSQLHttpClientRequest.Create(const aServer,
  aPort: AnsiString; aModel: TSQLModel);
begin
  Create(aServer,aPort,aModel,false); // will use default settings
end;

function TSQLHttpClientRequest.InternalCheckOpen: boolean;
begin
  result := false;
  if fRequest=nil then
  try

    EnterCriticalSection(fMutex);
    try
      InternalSetClass;
      if fRequestClass=nil then
        raise ECommunicationException.CreateUTF8('fRequestClass=nil for %',[self]);
      fRequest := fRequestClass.Create(fServer,fPort,fHttps,
        fProxyName,fProxyByPass,fConnectTimeout,fSendTimeout,fReceiveTimeout);
................................................................................
    except
      on Exception do
        FreeAndNil(fRequest);
    end;
  finally
    LeaveCriticalSection(fMutex);
  end else
    result := true;
end;

procedure TSQLHttpClientRequest.InternalClose;
begin
  FreeAndNil(fRequest);
end;







|









>
>
|
>
>
>







 







>
>
>
>
>
|
>
>
>







 







|






|
|
|







 







|







 







>
>







 







|








>
>
>
>







 







|







 







|

|




<


>







 







|







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
...
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
...
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
...
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
...
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
...
820
821
822
823
824
825
826
827
828
829
830
831
832
833

834
835
836
837
838
839
840
841
842
843
...
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
    fSendTimeout, fReceiveTimeout, fConnectTimeout: DWORD;
    fExtendedOptions: THttpRequestExtendedOptions;
    procedure SetCompression(Value: TSQLHttpCompressions);
    procedure SetKeepAliveMS(Value: cardinal);
    constructor RegisteredClassCreateFrom(aModel: TSQLModel;
      aDefinition: TSynConnectionDefinition); override;
    /// process low-level HTTP/1.1 request
    // - called by InternalURI(), therefore by URI() public method
    // - returns 200,202,204 if OK, http status error otherwise in result.Lo
    // - returns Server-InternalState in result.Hi
    function InternalRequest(const url, method: RawUTF8;
      var Header, Data, DataType: RawUTF8): Int64Rec; virtual; abstract;
    /// method calling the RESTful server fServer via HTTP/1.1
    // - calls the InternalRequest() protected method
    procedure InternalURI(var Call: TSQLRestURIParams); override;
  public
    /// connect to TSQLHttpServer on aServer:aPort
    // - you can customize the default client timeouts by setting appropriate
    // ConnectTimeout, SendTimeout and ReceiveTimeout parameters (in ms)
    constructor Create(const aServer, aPort: AnsiString; aModel: TSQLModel;
      SendTimeout: DWORD=HTTP_DEFAULT_SENDTIMEOUT;
      ReceiveTimeout: DWORD=HTTP_DEFAULT_RECEIVETIMEOUT;
      ConnectTimeout: DWORD=HTTP_DEFAULT_CONNECTTIMEOUT); reintroduce; overload; virtual;
    /// connect to TSQLHttpServer via 'address:port/root' URI format
    // - if port is not specified, aDefaultPort is used
    // - if root is not specified, aModel.Root is used
    constructor Create(const aServer: TSQLRestServerURIString; aModel: TSQLModel;
      aDefaultPort: integer); reintroduce; overload; 
    /// connnect to a LogView HTTP Server for remote logging
    // - will associate the EchoCustom callback of the log class to this server
................................................................................
    /// overridden protected method to handle HTTP connection
    function InternalCheckOpen: boolean; override;
    /// set the fWinAPI class
    // - the overridden implementation should set the expected fWinAPIClass
    procedure InternalSetClass; virtual; abstract;
  public
    /// connect to TSQLHttpServer on aServer:aPort with the default settings
    // - you can customize the default client timeouts by setting appropriate
    // ConnectTimeout, SendTimeout and ReceiveTimeout parameters (in ms) - note
    // that after creation of this instance, the connection is tied to those
    // initial parameters, so we won't publish any properties to change those
    // initial values once created
    constructor Create(const aServer, aPort: AnsiString; aModel: TSQLModel;
      SendTimeout: DWORD=HTTP_DEFAULT_SENDTIMEOUT;
      ReceiveTimeout: DWORD=HTTP_DEFAULT_RECEIVETIMEOUT;
      ConnectTimeout: DWORD=HTTP_DEFAULT_CONNECTTIMEOUT); overload; override;
    /// connect to TSQLHttpServer on aServer:aPort
    // - optional aProxyName may contain the name of the proxy server to use,
    // and aProxyByPass an optional semicolon delimited list of host names or
    // IP addresses, or both, that should not be routed through the proxy
    // - you can customize the default client timeouts by setting appropriate
    // ConnectTimeout, SendTimeout and ReceiveTimeout parameters (in ms) - note
    // that after creation of this instance, the connection is tied to those
................................................................................
procedure TSQLHttpClientGeneric.SetKeepAliveMS(Value: cardinal);
begin
  fKeepAliveMS := Value;
  InternalClose; // force re-create connection at next request
end;

constructor TSQLHttpClientGeneric.Create(const aServer, aPort: AnsiString;
  aModel: TSQLModel; SendTimeout,ReceiveTimeout,ConnectTimeout: DWORD);
begin
  inherited Create(aModel);
  fServer := aServer;
  fPort := aPort;
  fKeepAliveMS := 20000; // 20 seconds connection keep alive by default
  fCompression := [hcSynLZ];
  fConnectTimeout := ConnectTimeout;
  fSendTimeout := SendTimeout;
  fReceiveTimeout := ReceiveTimeout;
end;

constructor TSQLHttpClientGeneric.CreateForRemoteLogging(const aServer: AnsiString;
  aLogClass: TSynLogClass; aPort: Integer; const aRoot: RawUTF8);
var aModel: TSQLModel;
begin
  if not Assigned(aLogClass) then
................................................................................
    exit;
  inherited DefinitionTo(Definition); // save Kind + User/Password
  if fHttps then
    Definition.ServerName := 'https://';
  Definition.ServerName := FormatUTF8('%%:%',[Definition.ServerName,fServer,fPort]);
  Definition.DatabaseName := UrlEncode([
   'IgnoreSSLCertificateErrors',ord(fExtendedOptions.IgnoreSSLCertificateErrors),
   'ConnectTimeout',fConnectTimeout,'SendTimeout',fSendTimeout,'ReceiveTimeout',fReceiveTimeout,
   'ProxyName',fProxyName,'ProxyByPass',fProxyByPass]);
  Definition.DatabaseName := copy(Definition.DatabaseName,2,MaxInt); // trim leading '?'
end;

constructor TSQLHttpClientGeneric.RegisteredClassCreateFrom(aModel: TSQLModel;
  aDefinition: TSynConnectionDefinition);
var URI: TURI;
................................................................................
    tmp: RawUTF8;
begin
  URI.From(aDefinition.ServerName);
  Create(URI.Server,URI.Port,aModel);
  fHttps := URI.Https;
  P := Pointer(aDefinition.DataBaseName);
  while P<>nil do begin
    if UrlDecodeCardinal(P,'CONNECTTIMEOUT',V) then
      fConnectTimeout := V else
    if UrlDecodeCardinal(P,'SENDTIMEOUT',V) then
      fSendTimeout := V else
    if UrlDecodeCardinal(P,'RECEIVETIMEOUT',V) then
      fReceiveTimeout := V else
    if UrlDecodeValue(P,'PROXYNAME',tmp) then
      fProxyName := CurrentAnsiConvert.UTF8ToAnsi(tmp) else
    if UrlDecodeValue(P,'PROXYBYPASS',tmp) then
................................................................................


{ TSQLHttpClientWinSock }

function TSQLHttpClientWinSock.InternalCheckOpen: boolean;
begin
  if fSocket<>nil then begin
    result := true; // already connected
    exit;
  end;
  EnterCriticalSection(fMutex);
  try
    try
      if fSocketClass=nil then
        fSocketClass := THttpClientSocket;
      fSocket := fSocketClass.Open(fServer,fPort,cslTCP,fConnectTimeout);
      if fSendTimeout>0 then
        fSocket.SendTimeout := fSendTimeout;
      if fReceiveTimeout>0 then
        fSocket.ReceiveTimeout := fReceiveTimeout;
      {$ifdef USETCPPREFIX}
      fSocket.TCPPrefix := 'magic';
      {$endif}
      // note that first registered algo will be the prefered one
      if hcSynShaAes in Compression then
        // global SHA-256 / AES-256-CTR encryption + SynLZ compression
        fSocket.RegisterCompress(CompressShaAes,0); // CompressMinSize=0
................................................................................


{ TSQLHttpClientWebsockets }

function TSQLHttpClientWebsockets.InternalCheckOpen: boolean;
begin
  if fSocket<>nil then begin
    result := true; // already connected
    exit;
  end;
  if fSocketClass=nil then
    fSocketClass := THttpClientWebSockets;
  result := inherited InternalCheckOpen;
  if result then
    with fWebSocketParams do
................................................................................
  fProxyByPass := aProxyByPass;
  fSendTimeout := SendTimeout;
  fReceiveTimeout := ReceiveTimeout;
  fConnectTimeout := ConnectTimeout;
end;

constructor TSQLHttpClientRequest.Create(const aServer,
  aPort: AnsiString; aModel: TSQLModel; SendTimeout,ReceiveTimeout,ConnectTimeout: DWORD);
begin
  Create(aServer,aPort,aModel,false,'','',SendTimeout,ReceiveTimeout,ConnectTimeout);
end;

function TSQLHttpClientRequest.InternalCheckOpen: boolean;
begin

  if fRequest=nil then
  try
    result := false;
    EnterCriticalSection(fMutex);
    try
      InternalSetClass;
      if fRequestClass=nil then
        raise ECommunicationException.CreateUTF8('fRequestClass=nil for %',[self]);
      fRequest := fRequestClass.Create(fServer,fPort,fHttps,
        fProxyName,fProxyByPass,fConnectTimeout,fSendTimeout,fReceiveTimeout);
................................................................................
    except
      on Exception do
        FreeAndNil(fRequest);
    end;
  finally
    LeaveCriticalSection(fMutex);
  end else
    result := true; // already connected
end;

procedure TSQLHttpClientRequest.InternalClose;
begin
  FreeAndNil(fRequest);
end;

Changes to SynopseCommit.inc.

1
'1.18.1508'
|
1
'1.18.1509'