unit Sparkle.Http.Client;

interface

uses
  Sparkle.Http.Engine;

type
  THttpRequest = Sparkle.Http.Engine.THttpRequest;
  THttpResponse = Sparkle.Http.Engine.THttpResponse;

  THttpRequestProc = reference to procedure(ARequest: THttpRequest);
  THttpResponseProc = reference to procedure(ARequest: THttpRequest; var AResponse: THttpResponse);

  THttpClient = class
  strict private
    FEngine: THttpEngine;
    FInProcEngine: THttpEngine;
    FOnSendingRequest: THttpRequestProc;
    FOnResponseReceived: THttpResponseProc;
    procedure DoResponseReceived(Request: THttpRequest; var Response: THttpResponse); virtual;
  public
    property Engine: THttpEngine read FEngine;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    function CreateRequest: THttpRequest;
    function Send(Request: THttpRequest): THttpResponse;
    function Get(const AUri: string): THttpResponse;
    property OnSendingRequest: THttpRequestProc read FOnSendingRequest write FOnSendingRequest;
    property OnResponseReceived: THttpResponseProc read FOnResponseReceived write FOnResponseReceived;
  end;

implementation

uses
  Sparkle.Http.InProcEngine;

{ THttpClient }

constructor THttpClient.Create;
begin
  FEngine := THttpEngine.CreateDefault;
  FInProcEngine := TInProcHttpEngine.Create;
end;

function THttpClient.CreateRequest: THttpRequest;
begin
  Result := FEngine.CreateRequest;
end;

destructor THttpClient.Destroy;
begin
  FEngine.Free;
  FInProcEngine.Free;
  inherited;
end;

procedure THttpClient.DoResponseReceived(Request: THttpRequest;
  var Response: THttpResponse);
begin
  try
    FOnResponseReceived(Request, Response);
  except
    Response.Free;
    raise;
  end;
end;

function THttpClient.Get(const AUri: string): THttpResponse;
var
  Req: THttpRequest;
begin
  Req := CreateRequest;
  try
    Req.Uri := AUri;
    Req.Method := 'GET';
    Result := Send(Req);
  finally
    Req.Free;
  end;
end;

function THttpClient.Send(Request: THttpRequest): THttpResponse;
begin
  if Assigned(FOnSendingRequest) then
    FOnSendingRequest(Request);
  if Request.AsUri.Scheme = 'local' then
    Result := FInProcEngine.Send(Request)
  else
    Result := FEngine.Send(Request);
  if Assigned(FOnResponseReceived) then
    DoResponseReceived(Request, Result);
end;

end.
