[fpc-pascal] Improvement to TFPHTTPClient Class
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 ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Improvement to TFPHTTPClient Class
Hello, This will not be applied, for 2 reasons: 1. The whole point of TFPHTTPClient is exactly to couple it to sockets framework (fcl-net). If you want to use synapse, use httpsend. lnet has a similar component for the http protocol. 2. I favour the opposite approach. Abstract out the underlying HTTP implementation at a higher level. For this I have introduced FPWebclient, which has 2 implementations: TFPHTTPClient and Synapse. The new google-api and OData apis use FPWebclient. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Hello, I suggest that you change the TFPGMap in fgl.
Hello, You could always send a patch with a TFPGHashedMap or TFPGRedBlackMap implementation. thanks, -- Felipe Monteiro de Carvalho ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Improvement to TFPHTTPClient Class
2016-07-19 4:52 GMT-03:00 Michael Van Canneyt : > > 1. The whole point of TFPHTTPClient is exactly to couple it to sockets >framework (fcl-net). >If you want to use synapse, use httpsend. lnet has a similar component >for the http protocol. > > I dont want to use synapse. I am developing bindings for a c library. The library offers TCP connection functionality but does not provide any support for http. I need to use that library due to some particularities of my project. I do not understand the need for such coupling between http client and fcl-net. It is like coupling SQLDb with a specific RDBMS. > 2. I favour the opposite approach. Abstract out the underlying HTTP > implementation >at a higher level. > Why should we duplicate the code? Why should we implement the same functionality in several diferent places? > >For this I have introduced FPWebclient, which has 2 implementations: >TFPHTTPClient and Synapse. > > Through TAbstractWebClient you are introducing another level of complexity to do the same task: perform http requests. TAbstractWebClient is actually an adapter to diferent http implementations. TAbstractWebClient is an interesting class. However, It is a poor solution, IMHO. Best regards ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Improvement to TFPHTTPClient Class
On Tue, 19 Jul 2016, African Wild Dog wrote: 2016-07-19 4:52 GMT-03:00 Michael Van Canneyt : 1. The whole point of TFPHTTPClient is exactly to couple it to sockets framework (fcl-net). If you want to use synapse, use httpsend. lnet has a similar component for the http protocol. I dont want to use synapse. I am developing bindings for a c library. The library offers TCP connection functionality but does not provide any support for http. I need to use that library due to some particularities of my project. I do not understand the need for such coupling between http client and fcl-net. It is like coupling SQLDb with a specific RDBMS. The comparison is at fault, but I will not press the point. 2. I favour the opposite approach. Abstract out the underlying HTTP implementation at a higher level. Why should we duplicate the code? Why should we implement the same functionality in several diferent places? Because all Pascal TCP toolkits out there offer a HTTP Client. (lnet, indy, synapse). By doing this, I leave the choice up to the user which one to use for various APIs that are built ON TOP of HTTP. Your use case is simply one I didn't foresee, Because I assume that any decent TCP toolkit offers a HTTP client. However, now that I understand what you actually need, we can consider this use-case. I will accept the patch, on the condition that you provide a binding for a C TCP/IP library too. If your c library is open source, then we can use that. if not, then I'd ask you to provide an libevent implementation. It has no point abstracting out something if we have only 1 implementation. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal