| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- (*
- Brook for Free Pascal
- Copyright (C) 2014-2019 Silvio Clecio.
- See the file LICENSE.txt, included in this distribution,
- for details about the copyright.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *)
- { FCL HTTP client broker. }
- unit BrookFCLHttpClientBroker;
- {$mode objfpc}{$H+}
- interface
- uses
- BrookHttpClient, BrookConsts, FPHttpClient, Classes, SysUtils;
- type
- TBrookFPHttpClientDef = class(TBrookHttpDef)
- private
- FHttp: TFPHttpClient;
- FContents: TStrings;
- FDocument: TMemoryStream;
- FMethod: string;
- FUrl: string;
- class function InternalRequest(AHttp: TFPHttpClient; AResponse: TStream;
- const AMethod, AUrl: string): Boolean;
- protected
- function GetClient: TObject; override;
- function GetContents: TStrings; override;
- function GetCookies: TStrings; override;
- function GetDocument: TStream; override;
- function GetHeaders: TStrings; override;
- function GetContentType: string; override;
- procedure SetContentType(AValue: string); override;
- function GetStatusCode: Integer; override;
- function GetReasonPhrase: string; override;
- function GetMethod: string; override;
- function GetUrl: string; override;
- procedure SetMethod(AValue: string); override;
- procedure SetUrl(AValue: string); override;
- public
- constructor Create; override;
- destructor Destroy; override;
- class function GetLibrary: string; override;
- class function Get(const AUrl: string; AResponse: TStream): Boolean; override;
- class function Post(const AUrl: string; AResponse: TStream): Boolean; override;
- class function Put(const AUrl: string; AResponse: TStream): Boolean; override;
- class function Delete(const AUrl: string; AResponse: TStream): Boolean; override;
- class function Options(const AUrl: string; AResponse: TStream): Boolean; override;
- class function Head(const AUrl: string; AHeaders: TStrings): Boolean; override;
- class function PostForm(const AUrl, AFormData: string; AResponse: TStream): Boolean; override;
- class function PostForm(const AUrl: string; AFormData, AResponse: TStream): Boolean; override;
- class function PutForm(const AUrl, AFormData: string; AResponse: TStream): Boolean; override;
- class function PutForm(const AUrl: string; AFormData, AResponse: TStream): Boolean; override;
- class function PostFile(const AUrl, AFieldName, AFileName: string;
- AResponse: TStream): Boolean; override;
- class function PostFile(const AUrl, AFieldName, AFileName: string;
- AFile, AResponse: TStream): Boolean; override;
- procedure AddHeader(const AName, AValue: string); override;
- function Request: Boolean; override;
- end;
- implementation
- constructor TBrookFPHttpClientDef.Create;
- begin
- FHttp := TFPHttpClient.Create(nil);
- FContents := TStringList.Create;
- FDocument := TMemoryStream.Create;
- FHttp.AddHeader('User-Agent', 'Brook for Free Pascal and FCL-Web.');
- FMethod := 'GET';
- end;
- destructor TBrookFPHttpClientDef.Destroy;
- begin
- FContents.Free;
- FDocument.Free;
- FHttp.Free;
- inherited Destroy;
- end;
- function TBrookFPHttpClientDef.GetClient: TObject;
- begin
- Result := FHttp;
- end;
- function TBrookFPHttpClientDef.GetContents: TStrings;
- begin
- FDocument.Seek(0, 0);
- FContents.LoadFromStream(FDocument);
- Result := FContents;
- end;
- function TBrookFPHttpClientDef.GetCookies: TStrings;
- begin
- Result := FHttp.Cookies;
- end;
- function TBrookFPHttpClientDef.GetDocument: TStream;
- begin
- Result := FDocument;
- end;
- function TBrookFPHttpClientDef.GetHeaders: TStrings;
- begin
- Result := FHttp.ResponseHeaders;
- end;
- function TBrookFPHttpClientDef.GetContentType: string;
- begin
- Result := FHttp.GetHeader('Content-Type');
- end;
- procedure TBrookFPHttpClientDef.SetContentType(AValue: string);
- begin
- FHttp.AddHeader('Content-Type', AValue);
- end;
- function TBrookFPHttpClientDef.GetStatusCode: Integer;
- begin
- Result := FHttp.ResponseStatusCode;
- end;
- function TBrookFPHttpClientDef.GetReasonPhrase: string;
- begin
- Result := FHttp.ResponseStatusText;
- end;
- function TBrookFPHttpClientDef.GetMethod: string;
- begin
- Result := FMethod;
- end;
- function TBrookFPHttpClientDef.GetUrl: string;
- begin
- Result := FUrl;
- end;
- procedure TBrookFPHttpClientDef.SetMethod(AValue: string);
- begin
- FMethod := AValue;
- end;
- procedure TBrookFPHttpClientDef.SetUrl(AValue: string);
- begin
- FUrl := AValue;
- end;
- class function TBrookFPHttpClientDef.InternalRequest(AHttp: TFPHttpClient;
- AResponse: TStream; const AMethod, AUrl: string): Boolean;
- begin
- AHttp.RequestHeaders.Add('Connection: Close');
- if Assigned(AResponse) then
- begin
- AHttp.HttpMethod(AMethod, AUrl, AResponse, []);
- Result := AHttp.ResponseStatusCode = 200;
- end
- else
- begin
- AResponse := TMemoryStream.Create;
- try
- AHttp.HttpMethod(AMethod, AUrl, AResponse, []);
- Result := AHttp.ResponseStatusCode = 200;
- finally
- FreeAndNil(AResponse);
- end;
- end;
- end;
- class function TBrookFPHttpClientDef.GetLibrary: string;
- begin
- Result := 'FCLWeb';
- end;
- class function TBrookFPHttpClientDef.Get(const AUrl: string;
- AResponse: TStream): Boolean;
- var
- VHttp: TFPHttpClient;
- begin
- VHttp := TFPHttpClient.Create(nil);
- try
- Result := InternalRequest(VHttp, AResponse, 'GET', AUrl);
- finally
- VHttp.Free;
- end;
- end;
- class function TBrookFPHttpClientDef.Post(const AUrl: string;
- AResponse: TStream): Boolean;
- var
- VHttp: TFPHttpClient;
- begin
- VHttp := TFPHttpClient.Create(nil);
- try
- Result := InternalRequest(VHttp, AResponse, 'POST', AUrl);
- finally
- VHttp.Free;
- end;
- end;
- class function TBrookFPHttpClientDef.Put(const AUrl: string;
- AResponse: TStream): Boolean;
- var
- VHttp: TFPHttpClient;
- begin
- VHttp := TFPHttpClient.Create(nil);
- try
- Result := InternalRequest(VHttp, AResponse, 'PUT', AUrl);
- finally
- VHttp.Free;
- end;
- end;
- class function TBrookFPHttpClientDef.Delete(const AUrl: string;
- AResponse: TStream): Boolean;
- var
- VHttp: TFPHttpClient;
- begin
- VHttp := TFPHttpClient.Create(nil);
- try
- Result := InternalRequest(VHttp, AResponse, 'DELETE', AUrl);
- finally
- VHttp.Free;
- end;
- end;
- class function TBrookFPHttpClientDef.Options(const AUrl: string;
- AResponse: TStream): Boolean;
- var
- VHttp: TFPHttpClient;
- begin
- VHttp := TFPHttpClient.Create(nil);
- try
- Result := InternalRequest(VHttp, AResponse, 'OPTIONS', AUrl);
- finally
- VHttp.Free;
- end;
- end;
- class function TBrookFPHttpClientDef.Head(const AUrl: string;
- AHeaders: TStrings): Boolean;
- var
- VHttp: TFPHttpClient;
- begin
- VHttp := TFPHttpClient.Create(nil);
- try
- VHttp.RequestHeaders.Add('Connection: Close');
- VHttp.HttpMethod('HEAD', AUrl, nil, []);
- AHeaders.Assign(VHttp.ResponseHeaders);
- Result := VHttp.ResponseStatusCode = 200;
- finally
- VHttp.Free;
- end;
- end;
- class function TBrookFPHttpClientDef.PostForm(const AUrl: string; AFormData,
- AResponse: TStream): Boolean;
- var
- VHttp: TFPHttpClient;
- begin
- VHttp := TFPHttpClient.Create(nil);
- try
- VHttp.RequestBody := AFormData;
- VHttp.AddHeader('Content-Type', 'application/x-www-form-urlencoded');
- Result := InternalRequest(VHttp, AResponse, 'POST', AUrl);
- finally
- VHttp.Free;
- end;
- end;
- class function TBrookFPHttpClientDef.PostForm(const AUrl, AFormData: string;
- AResponse: TStream): Boolean;
- var
- VFormData: TStringStream;
- begin
- VFormData := TStringStream.Create(AFormData);
- try
- Result := PostForm(AUrl, VFormData, AResponse);
- finally
- VFormData.Free;
- VFormData := nil;
- end;
- end;
- class function TBrookFPHttpClientDef.PutForm(const AUrl: string; AFormData,
- AResponse: TStream): Boolean;
- var
- VHttp: TFPHttpClient;
- begin
- VHttp := TFPHttpClient.Create(nil);
- try
- VHttp.RequestBody := AFormData;
- VHttp.AddHeader('Content-Type', 'application/x-www-form-urlencoded');
- Result := InternalRequest(VHttp, AResponse, 'PUT', AUrl);
- finally
- VHttp.Free;
- end;
- end;
- class function TBrookFPHttpClientDef.PutForm(const AUrl, AFormData: string;
- AResponse: TStream): Boolean;
- var
- VFormData: TStringStream;
- begin
- VFormData := TStringStream.Create(AFormData);
- try
- Result := PutForm(AUrl, VFormData, AResponse);
- finally
- VFormData.Free;
- VFormData := nil;
- end;
- end;
- class function TBrookFPHttpClientDef.PostFile(const AUrl, AFieldName,
- AFileName: string; AFile, AResponse: TStream): Boolean;
- var
- S, VSep: string;
- VData: TMemoryStream;
- VHttp: TFPHttpClient;
- begin
- VData := TMemoryStream.Create;
- VHttp := TFPHttpClient.Create(nil);
- try
- VSep := Format('%.8x_multipart_boundary', [Random($FFFFFF)]);
- S := '--' + VSep + CRLF;
- S := S + Format('Content-Disposition: form-data; name="%s"; filename="%s"' +
- CRLF, [AFieldName, ExtractFileName(AFileName)]);
- S := S + 'Content-Type: application/octet-string' + CRLF + CRLF;
- VData.Write(Pointer(S)^, Length(S));
- VData.CopyFrom(AFile, 0);
- S := CRLF + '--' + VSep + '--' + CRLF;
- VData.Write(Pointer(S)^, Length(S));
- VHttp.AddHeader('Content-Type', 'multipart/form-data; boundary=' + VSep);
- VData.Seek(0, 0);
- VHttp.RequestBody := VData;
- Result := InternalRequest(VHttp, AResponse, 'POST', AUrl);
- finally
- VData.Free;
- VHttp.RequestBody := nil;
- VHttp.Free;
- end;
- end;
- class function TBrookFPHttpClientDef.PostFile(const AUrl, AFieldName,
- AFileName: string; AResponse: TStream): Boolean;
- var
- VFile: TFileStream;
- begin
- VFile := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
- try
- Result := PostFile(AUrl, AFieldName, AFileName, VFile, AResponse);
- finally
- VFile.Free;
- end;
- end;
- procedure TBrookFPHttpClientDef.AddHeader(const AName, AValue: string);
- begin
- FHttp.AddHeader(AName, AValue);
- end;
- function TBrookFPHttpClientDef.Request: Boolean;
- begin
- try
- if FHttp.ResponseHeaders.Count > 0 then
- FHttp.RequestHeaders.AddStrings(FHttp.ResponseHeaders);
- if FDocument.Size > 0 then
- begin
- FHttp.RequestBody := TMemoryStream.Create;
- FHttp.RequestBody.CopyFrom(FDocument, 0);
- FHttp.RequestBody.Seek(0, 0);
- FDocument.Clear;
- end;
- FHttp.RequestHeaders.Add('Connection: Close');
- FHttp.HttpMethod(FMethod, FUrl, FDocument, []);
- Result := FHttp.ResponseStatusCode = 200;
- finally
- FHttp.RequestBody.Free;
- FHttp.RequestBody := nil;
- end;
- end;
- initialization
- TBrookFPHttpClientDef.Register;
- end.
|