12-17-2018, 05:49 PM
For context, I'm trying to create a simple abstraction over TIdHTP. So far I have something along these lines:
The issue is that not all requests and responses will be text based. I'd like to keep the interface as uniform as possible. Although filling the Body of a THTTPRequest with TBytes converted by StringOf did not result in any instantly noticeable problem, it does worry me that unwanted conversions may happen that corrupt the data. Conversely, I'm not sure if BytesOf on the Body of a THTTPResponse will give me the binary response (in case of files) exactly as it was sent. I could switch to always using TBytes for both, but then I lose all encoding/decoding intelligence that Indy has.
What is the cleanest solution (i.e. smallest number of fields/types) that will work?
Code:
type
THTTPRequest = record
Method: (
hmGET
hmPOST,
hmPUT
);
URL: string;
ContentType: string;
Body: string;
end;
THTTPResponse = record
StatusCode: SmallInt;
Body: string;
end;
THTTPClient = class
public
function Perform(const ARequest: THTTPRequest): THTTPResponse; virtual; abstract;
end;
TIndyHTTPClient = class(THTTPClient)
public
function Perform(const ARequest: THTTPRequest): THTTPResponse; override;
end;
function TIndyHTTPClient.Perform(const ARequest: THTTPRequest): THTTPResponse;
var
LClient: TIdHTTP;
LRequestBodyStream: TStringStream;
begin
Result := Default(THTTPResponse);
LRequestBodyStream := TStringStream.Create(ARequest.Body);
try
LClient := TIdHTTP.Create(nil);
try
LClient.HandleRedirects := True;
LClient.HTTPOptions := LClient.HTTPOptions + [hoNoProtocolErrorException];
LClient.Request.ContentType := ARequest.ContentType;
case ARequest.Method of
hmGET:
Result.Body := LClient.Get(ARequest.URL);
hmPUT:
Result.Body := LClient.Put(ARequest.URL, LRequestBodyStream);
hmPOST:
Result.Body := LClient.Post(ARequest.URL, LRequestBodyStream);
end;
Result.StatusCode := LClient.ResponseCode;
finally
LClient.Free;
end;
finally
LRequestBodyStream.Free;
end;
end;
The issue is that not all requests and responses will be text based. I'd like to keep the interface as uniform as possible. Although filling the Body of a THTTPRequest with TBytes converted by StringOf did not result in any instantly noticeable problem, it does worry me that unwanted conversions may happen that corrupt the data. Conversely, I'm not sure if BytesOf on the Body of a THTTPResponse will give me the binary response (in case of files) exactly as it was sent. I could switch to always using TBytes for both, but then I lose all encoding/decoding intelligence that Indy has.
What is the cleanest solution (i.e. smallest number of fields/types) that will work?