Bruce Long
Bruce Long

Reputation: 733

TIdHttp.Post response time too long

I am using Delphi XE6.

I have read all of the following:

Slow responses to TIdHTTP POSTs

Delphi: Why does IdHTTP.ConnectTimeout make requests slower?

Delphi TIdHTTP POST is very slow vs GET

And I know that relevent timing and performance factors include : 1. HTTPOptions 2. TIdHttp.Request options - content type, encoding, and especially connection timeout settings. 3. iCsslIOHandler.SSLOptions.Method should select the correct SSL version for authentication

But my TIdHttp.Post from Delphi Xe6 is still much slower than it should be, by a factor of 10x.

You can assume the posts are working - they are. No exception gets thrown, although there is no content in the log file I write out either.

Is it likely that using REST calls would make this faster, since http is not supposed to be RPC?

Does anyone have any tips or insights given the code below (iC prefixed variables are class scope, except for Mutexes which are not owned by the thread):

procedure TVinterClientCall<T , I>.InitialiseHttpClient;
var
  vKey           : String;
  vPair          : TPair<String , String>;
  vDebugString   : string;
  vSocketHandler : TIdSSLIOHandlerSocketOpenSSL;
  vParamValue    : String;
begin
  // Setup the Http Client
  iChttpClient := TIdHttp.Create;
  // System.RegisterExpectedMemoryLeak(iChttpClient);

  with iChttpClient do
  begin
    HandleRedirects := True;
    // Here we set the API and protocol content type
    Request.ContentType := iCContentType;
    Request.Accept      := iCContentType;


    ConnectTimeout     := 0;
    HTTPOptions        := [hoForceEncodeParams , hoKeepOrigProtocol];
    Request.Connection := 'keep-alive';

    // Logically, this should be redundant. There is no reason why this property should revert due to response
    // data or conditions. However, this is to be certain.
    if hoWaitForUnexpectedData in HTTPOptions then
    begin
      HTTPOptions := HTTPOptions - [hoWaitForUnexpectedData];
    end;

    //This just gets some header values from the interface, no problem...
    for vKey in iCCustomHeaderParams.Keys do
    begin
      // vParamValue is an out parameter
      iCCustomHeaderParams.TryGetValue(vKey , vParamValue);
      Request.CustomHeaders.AddValue(vKey , vParamValue);

    end;
  end;

  iCsslIOHandler                   := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  iCsslIOHandler.SSLOptions.Method := sslvSSLv3; //**Is this right?**

  iChttpClient.IOHandler := iCsslIOHandler;

end;

// This is the currently used method.
procedure TVinterClientCall<T , I>.ExecuteCallMemStream;
const
  CRLF = #13#10;
var
  vStream                  : TMemoryStream;
  vParams                  : TMemoryStream;
  vResponse                : TMemoryStream;
  vRequestString           : string;
  vHeaderString            : string;
  vRequestStringStream     : TStringStream;
  vDisplayStreamDataString : String;
  vResponseData            : TStringStream;               // TidStream is Version 10.1.x. TMemoryStream may be better...
  vTimeStamps              : array [0 .. 1] of TDateTime; // Array of real;
  v64TimeStamps            : array [0 .. 1] of DWORD;     // int64;
  vDuration                : TDateTime;
  v64Duration              : DWORD;
  vHour                    : word;
  vMin                     : word;
  vSec                     : word;
  vMsec                    : word;
  vTimingLog               : TextFile;
  vBeforePostNow           : int64; // cardinal;
  vAfterPostNow            : int64; // cardinal;

  vPostTimes : TStringList;


begin

  vStream              := TMemoryStream.Create;
  vParams              := TMemoryStream.Create;
  iCResponse           := TMemoryStream.Create;
  vRequestStringStream := TStringStream.Create;
  vResponseData        := TStringStream.Create;
  vPostTimes           := TStringList.Create;

  InitialiseHttpClient();

  iCURL := iCEndPoint;


    try

      vRequestString := '{' + ProtocolParamsString + ',' + Method + ',' + DataParamString + '}';
      StringReplace(vRequestString , #13#10 , '' , [rfReplaceAll]);


      vRequestStringStream.WriteString(vRequestString);
      vDisplayStreamDataString := vRequestStringStream.DataString;

      iCRequestData := vDisplayStreamDataString;
      vParams.Write(vRequestString[1] , Length(vRequestString));

      with iChttpClient do
      begin
        try

          iCMxUtility.Acquire;
          v64TimeStamps[0] := timeGetTime(); // Now64();

          // vResponseData  := TStringStream.Create(Post(iCURL , vRequestStringStream));
          Post(iCURL , vRequestStringStream , vResponseData);

          v64TimeStamps[1] := timeGetTime(); // Now64();
          // vTimeStamps[1] := Now;
          iCMxUtility.Release;
          v64Duration := v64TimeStamps[1] - v64TimeStamps[0];
          // vDuration      := vTimeStamps[1] - vTimeStamps[0];

          // DecodeTime(vDuration , vHour , vMin , vSec , vMsec);

        except
          on E : Exception do
          begin
            iCMxUtility.Acquire;
            showmessage('Error encountered during POST: ' + E.Message);
            iCMxUtility.Release;
          end;

        end;
      end;

    finally


      iCMxLogFiles.Acquire;
      // Try to open the Test.txt file for writing to
      vPostTimes.SaveToFile('.\PostTimes_'+ StringReplace(TimeToStr(Now), ':', '', [rfReplaceAll]));

      iCMxLogFiles.Release;

      // Local variable scope Cleanup.
      FreeAndNil(vStream);
      FreeAndNil(vParams);
      FreeAndNil(iCResponse);
      FreeAndNil(vRequestStringStream);
      FreeAndNil(vResponseData);
      FreeAndNil(vPostTimes);

      ReleaseHttpClient;

    end;


end;

Upvotes: 0

Views: 1158

Answers (0)

Related Questions