[fpc-pascal] Improvement to TFPHTTPClient Class

African Wild Dog paintedlycaon at gmail.com
Tue Jul 19 04:14:26 CEST 2016


Hello,

The current version of the TFPHTTPClient (the one shipped with fpc 3.0) is
coupled to the fpc's sockets framework (fcl-net) so we can't utilize other
tcp connection framework (e.g Synapse) to perform HTTP requests using
TFPHTTPClient.

I have made an improvement to the TFPHTTPClient class (unit fphttpclient,
package fcl-web) which consists of decoupling the client from the socket
framework that is used to perform HTTP requests.

My solution is quite simple: i created a new class called
TTCPConnectionAdapter (as the name suggests, i used the Adapter pattern)
and changed the http client class to perform requests using a
TCPConnectionAdapter instance . The connection adapter is passed as a
parameter to the constructor of the TFPHTTPClient class (dependency
injection). So, the TFPHTTPClient is not tied to the a particular socket
framework anymore. If one wants to perform http requests using e.g Synapse,
just implement the appropriate TTCPConnectionAdapter descendant and inject
it into TFPHTTPClient.

The code below shows the TInetAdapter


======================================

{ TTCPConnectionAdapter }

TTCPConnectionAdapter = class(TStream)
  strict private
    FHost: String;
    FPort: Word;
    procedure ValidateConnection;
  strict protected
    procedure DoConnect(const AHost: String; const APort: Word); virtual;
abstract;
    function DoRead(var Buffer; Count: Longint): Longint; virtual; abstract;
    function DoWrite(const Buffer; Count: Longint): Longint; virtual;
abstract;
    function GetConnected: Boolean; virtual; abstract;
  public
    procedure Connect(const AHost: String; const APort: Word);
    procedure Disconnect; virtual; abstract;
    function Read(var Buffer; Count: Longint): Longint; override;
    function Seek(Offset: Longint; Origin: Word): Longint; override;
    function Write(const Buffer; Count: Longint): Longint; override;
    property Connected: Boolean read GetConnected;
    property Host: String read FHost;
    property Port: Word read FPort;
  end;

{ TInetConnectionAdapter }

  TInetConnectionAdapter = class(TTCPConnectionAdapter)
  strict private
    FSocket: TInetSocket;
    procedure FreeSocket;
  strict protected
    procedure DoConnect(const AHost: String; const APort: Word); override;
    function DoRead(var Buffer; Count: Longint): Longint; override;
    function DoWrite(const Buffer; Count: Longint): Longint; override;
    function GetConnected: Boolean; override;
  public
    destructor Destroy; override;
    procedure Disconnect; override;
  end;

  { TFPCustomHTTPClient }

  TFPCustomHTTPClient = Class(TComponent)
  private
    ......
    FTCPConnection: TTCPConnectionAdapter;
  public
    Constructor Create(const ATCPConnection: TTCPConnectionAdapter);
  end;

==============================================================

Best regards
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20160718/f6f214cd/attachment.html>


More information about the fpc-pascal mailing list