|
@@ -17,7 +17,7 @@ unit fphttpclient;
|
|
|
{ ---------------------------------------------------------------------
|
|
|
Todo:
|
|
|
* Proxy support ?
|
|
|
- * Easy calls for DELETE/etc.
|
|
|
+ * Https support.
|
|
|
---------------------------------------------------------------------}
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
|
@@ -106,6 +106,41 @@ Type
|
|
|
Class procedure SimplePost(const URL: string; Response : TStrings);
|
|
|
Class procedure SimplePost(const URL: string; const LocalFileName: String);
|
|
|
Class function SimplePost(const URL: string) : String;
|
|
|
+ // Simple Put
|
|
|
+ // Put URL, and Requestbody. Return response in Stream, File, TstringList or String;
|
|
|
+ procedure Put(const URL: string; const Response: TStream);
|
|
|
+ procedure Put(const URL: string; Response : TStrings);
|
|
|
+ procedure Put(const URL: string; const LocalFileName: String);
|
|
|
+ function Put(const URL: string) : String;
|
|
|
+ // Simple class methods.
|
|
|
+ Class procedure SimplePut(const URL: string; const Response: TStream);
|
|
|
+ Class procedure SimplePut(const URL: string; Response : TStrings);
|
|
|
+ Class procedure SimplePut(const URL: string; const LocalFileName: String);
|
|
|
+ Class function SimplePut(const URL: string) : String;
|
|
|
+ // Simple Delete
|
|
|
+ // Delete URL, and Requestbody. Return response in Stream, File, TstringList or String;
|
|
|
+ procedure Delete(const URL: string; const Response: TStream);
|
|
|
+ procedure Delete(const URL: string; Response : TStrings);
|
|
|
+ procedure Delete(const URL: string; const LocalFileName: String);
|
|
|
+ function Delete(const URL: string) : String;
|
|
|
+ // Simple class methods.
|
|
|
+ Class procedure SimpleDelete(const URL: string; const Response: TStream);
|
|
|
+ Class procedure SimpleDelete(const URL: string; Response : TStrings);
|
|
|
+ Class procedure SimpleDelete(const URL: string; const LocalFileName: String);
|
|
|
+ Class function SimpleDelete(const URL: string) : String;
|
|
|
+ // Simple Options
|
|
|
+ // Options from URL, and Requestbody. Return response in Stream, File, TstringList or String;
|
|
|
+ procedure Options(const URL: string; const Response: TStream);
|
|
|
+ procedure Options(const URL: string; Response : TStrings);
|
|
|
+ procedure Options(const URL: string; const LocalFileName: String);
|
|
|
+ function Options(const URL: string) : String;
|
|
|
+ // Simple class methods.
|
|
|
+ Class procedure SimpleOptions(const URL: string; const Response: TStream);
|
|
|
+ Class procedure SimpleOptions(const URL: string; Response : TStrings);
|
|
|
+ Class procedure SimpleOptions(const URL: string; const LocalFileName: String);
|
|
|
+ Class function SimpleOptions(const URL: string) : String;
|
|
|
+ // Get HEAD
|
|
|
+ Class Procedure Head(AURL : String; Headers: TStrings);
|
|
|
// Post Form data (www-urlencoded).
|
|
|
// Formdata in string (urlencoded) or TStrings (plain text) format.
|
|
|
// Form data will be inserted in the requestbody.
|
|
@@ -127,8 +162,6 @@ Type
|
|
|
Procedure FileFormPost(const AURL, AFieldName, AFileName: string; const Response: TStream);
|
|
|
// Simple form of Posting a file
|
|
|
Class Procedure SimpleFileFormPost(const AURL, AFieldName, AFileName: string; const Response: TStream);
|
|
|
- // Get HEAD
|
|
|
- Class Procedure HEAD(AURL : String; Headers: TStrings);
|
|
|
Protected
|
|
|
// Before request properties.
|
|
|
// Additional headers for request. Host; and Authentication are automatically added.
|
|
@@ -300,7 +333,7 @@ begin
|
|
|
I:=Pos(':',Result);
|
|
|
if (I=0) then
|
|
|
I:=Length(Result);
|
|
|
- Delete(Result,1,I);
|
|
|
+ System.Delete(Result,1,I);
|
|
|
end;
|
|
|
|
|
|
Function TFPCustomHTTPClient.GetServerURL(URI : TURI) : String;
|
|
@@ -355,8 +388,8 @@ begin
|
|
|
If (URI.Port<>0) then
|
|
|
S:=S+':'+IntToStr(URI.Port);
|
|
|
S:=S+CRLF;
|
|
|
- If Assigned(RequestBody) and (IndexOfHeader('Content-length')=-1) then
|
|
|
- AddHeader('Content-length',IntToStr(RequestBody.Size));
|
|
|
+ If Assigned(RequestBody) and (IndexOfHeader('Content-Length')=-1) then
|
|
|
+ AddHeader('Content-Length',IntToStr(RequestBody.Size));
|
|
|
For I:=0 to FRequestHeaders.Count-1 do
|
|
|
begin
|
|
|
l:=FRequestHeaders[i];
|
|
@@ -416,7 +449,7 @@ begin
|
|
|
Result:=Result+#13
|
|
|
else
|
|
|
begin
|
|
|
- Delete(FBuffer,1,1);
|
|
|
+ System.Delete(FBuffer,1,1);
|
|
|
Done:=True;
|
|
|
end;
|
|
|
end;
|
|
@@ -436,7 +469,7 @@ begin
|
|
|
else
|
|
|
begin
|
|
|
Result:=Result+Copy(FBuffer,1,P-1);
|
|
|
- Delete(FBuffer,1,P+1);
|
|
|
+ System.Delete(FBuffer,1,P+1);
|
|
|
Done:=True;
|
|
|
end;
|
|
|
end;
|
|
@@ -471,7 +504,7 @@ begin
|
|
|
S:=Uppercase(GetNextWord(AStatusLine));
|
|
|
If (Copy(S,1,5)<>'HTTP/') then
|
|
|
Raise EHTTPClient.CreateFmt(SErrInvalidProtocolVersion,[S]);
|
|
|
- Delete(S,1,5);
|
|
|
+ System.Delete(S,1,5);
|
|
|
FServerHTTPVersion:=S;
|
|
|
S:=GetNextWord(AStatusLine);
|
|
|
Result:=StrToIntDef(S,-1);
|
|
@@ -492,14 +525,14 @@ Function TFPCustomHTTPClient.ReadResponseHeaders : Integer;
|
|
|
If Assigned(FCookies) then
|
|
|
FCookies.Clear;
|
|
|
P:=Pos(':',S);
|
|
|
- Delete(S,1,P);
|
|
|
+ System.Delete(S,1,P);
|
|
|
Repeat
|
|
|
P:=Pos(';',S);
|
|
|
If (P=0) then
|
|
|
P:=Length(S)+1;
|
|
|
C:=Trim(Copy(S,1,P-1));
|
|
|
Cookies.Add(C);
|
|
|
- Delete(S,1,P);
|
|
|
+ System.Delete(S,1,P);
|
|
|
Until (S='');
|
|
|
end;
|
|
|
|
|
@@ -557,7 +590,7 @@ begin
|
|
|
S:=Trim(LowerCase(FResponseHeaders[i]));
|
|
|
If (Copy(S,1,Length(Cl))=Cl) then
|
|
|
begin
|
|
|
- Delete(S,1,Length(CL));
|
|
|
+ System.Delete(S,1,Length(CL));
|
|
|
Result:=StrToIntDef(Trim(S),-1);
|
|
|
end;
|
|
|
Inc(I);
|
|
@@ -580,7 +613,7 @@ begin
|
|
|
S:=Trim(LowerCase(FResponseHeaders[i]));
|
|
|
If (Copy(S,1,Length(Cl))=Cl) then
|
|
|
begin
|
|
|
- Delete(S,1,Length(CL));
|
|
|
+ System.Delete(S,1,Length(CL));
|
|
|
Result:=Trim(S);
|
|
|
exit;
|
|
|
end;
|
|
@@ -980,7 +1013,284 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+procedure TFPCustomHTTPClient.Put(const URL: string; const Response: TStream);
|
|
|
+begin
|
|
|
+ DoMethod('PUT',URL,Response,[]);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFPCustomHTTPClient.Put(const URL: string; Response: TStrings);
|
|
|
+begin
|
|
|
+ Response.Text:=Put(URL);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFPCustomHTTPClient.Put(const URL: string;
|
|
|
+ const LocalFileName: String);
|
|
|
+
|
|
|
+Var
|
|
|
+ F : TFileStream;
|
|
|
+
|
|
|
+begin
|
|
|
+ F:=TFileStream.Create(LocalFileName,fmCreate);
|
|
|
+ try
|
|
|
+ Put(URL,F);
|
|
|
+ finally
|
|
|
+ F.Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TFPCustomHTTPClient.Put(const URL: string): String;
|
|
|
+Var
|
|
|
+ SS : TStringStream;
|
|
|
+begin
|
|
|
+ SS:=TStringStream.Create('');
|
|
|
+ try
|
|
|
+ Put(URL,SS);
|
|
|
+ Result:=SS.Datastring;
|
|
|
+ finally
|
|
|
+ SS.Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class procedure TFPCustomHTTPClient.SimplePut(const URL: string;
|
|
|
+ const Response: TStream);
|
|
|
+
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Put(URL,Response);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class procedure TFPCustomHTTPClient.SimplePut(const URL: string;
|
|
|
+ Response: TStrings);
|
|
|
+
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Put(URL,Response);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class procedure TFPCustomHTTPClient.SimplePut(const URL: string;
|
|
|
+ const LocalFileName: String);
|
|
|
+
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Put(URL,LocalFileName);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class function TFPCustomHTTPClient.SimplePut(const URL: string): String;
|
|
|
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Result:=Put(URL);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFPCustomHTTPClient.Delete(const URL: string; const Response: TStream);
|
|
|
+begin
|
|
|
+ DoMethod('DELETE',URL,Response,[]);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFPCustomHTTPClient.Delete(const URL: string; Response: TStrings);
|
|
|
+begin
|
|
|
+ Response.Text:=Delete(URL);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFPCustomHTTPClient.Delete(const URL: string;
|
|
|
+ const LocalFileName: String);
|
|
|
+
|
|
|
+Var
|
|
|
+ F : TFileStream;
|
|
|
+
|
|
|
+begin
|
|
|
+ F:=TFileStream.Create(LocalFileName,fmCreate);
|
|
|
+ try
|
|
|
+ Delete(URL,F);
|
|
|
+ finally
|
|
|
+ F.Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TFPCustomHTTPClient.Delete(const URL: string): String;
|
|
|
+Var
|
|
|
+ SS : TStringStream;
|
|
|
+begin
|
|
|
+ SS:=TStringStream.Create('');
|
|
|
+ try
|
|
|
+ Delete(URL,SS);
|
|
|
+ Result:=SS.Datastring;
|
|
|
+ finally
|
|
|
+ SS.Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class procedure TFPCustomHTTPClient.SimpleDelete(const URL: string;
|
|
|
+ const Response: TStream);
|
|
|
+
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Delete(URL,Response);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class procedure TFPCustomHTTPClient.SimpleDelete(const URL: string;
|
|
|
+ Response: TStrings);
|
|
|
+
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Delete(URL,Response);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class procedure TFPCustomHTTPClient.SimpleDelete(const URL: string;
|
|
|
+ const LocalFileName: String);
|
|
|
+
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Delete(URL,LocalFileName);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class function TFPCustomHTTPClient.SimpleDelete(const URL: string): String;
|
|
|
+
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Result:=Delete(URL);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFPCustomHTTPClient.Options(const URL: string; const Response: TStream);
|
|
|
+begin
|
|
|
+ DoMethod('OPTIONS',URL,Response,[]);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFPCustomHTTPClient.Options(const URL: string; Response: TStrings);
|
|
|
+begin
|
|
|
+ Response.Text:=Options(URL);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFPCustomHTTPClient.Options(const URL: string;
|
|
|
+ const LocalFileName: String);
|
|
|
+
|
|
|
+Var
|
|
|
+ F : TFileStream;
|
|
|
+
|
|
|
+begin
|
|
|
+ F:=TFileStream.Create(LocalFileName,fmCreate);
|
|
|
+ try
|
|
|
+ Options(URL,F);
|
|
|
+ finally
|
|
|
+ F.Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TFPCustomHTTPClient.Options(const URL: string): String;
|
|
|
+Var
|
|
|
+ SS : TStringStream;
|
|
|
+begin
|
|
|
+ SS:=TStringStream.Create('');
|
|
|
+ try
|
|
|
+ Options(URL,SS);
|
|
|
+ Result:=SS.Datastring;
|
|
|
+ finally
|
|
|
+ SS.Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class procedure TFPCustomHTTPClient.SimpleOptions(const URL: string;
|
|
|
+ const Response: TStream);
|
|
|
+
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Options(URL,Response);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class procedure TFPCustomHTTPClient.SimpleOptions(const URL: string;
|
|
|
+ Response: TStrings);
|
|
|
+
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Options(URL,Response);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class procedure TFPCustomHTTPClient.SimpleOptions(const URL: string;
|
|
|
+ const LocalFileName: String);
|
|
|
+
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Options(URL,LocalFileName);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Class function TFPCustomHTTPClient.SimpleOptions(const URL: string): String;
|
|
|
+
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ Result:=Options(URL);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+class procedure TFPCustomHTTPClient.Head(AURL : String; Headers: TStrings);
|
|
|
+begin
|
|
|
+ With Self.Create(nil) do
|
|
|
+ try
|
|
|
+ RequestHeaders.Add('Connection: Close');
|
|
|
+ HTTPMethod('HEAD', AURL, Nil, [200]);
|
|
|
+ Headers.Assign(ResponseHeaders);
|
|
|
+ Finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+end;
|
|
|
|
|
|
procedure TFPCustomHTTPClient.FormPost(const URL, FormData: string;
|
|
|
const Response: TStream);
|
|
@@ -1054,7 +1364,6 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
Class Procedure TFPCustomHTTPClient.SimpleFormPost(const URL, FormData: string; const Response: TStream);
|
|
|
|
|
|
begin
|
|
@@ -1138,10 +1447,10 @@ Var
|
|
|
F : TFileStream;
|
|
|
begin
|
|
|
Sep:=Format('%.8x_multipart_boundary',[Random($ffffff)]);
|
|
|
- AddHeader('Content-type','multipart/form-data; boundary='+Sep);
|
|
|
+ AddHeader('Content-Type','multipart/form-data; boundary='+Sep);
|
|
|
S:='--'+Sep+CRLF;
|
|
|
- s:=s+Format('content-disposition: form-data; name="%s"; filename="%s"'+CRLF,[AFieldName,AFileName]);
|
|
|
- s:=s+'Content-Type: Application/octet-string'+CRLF+CRLF;
|
|
|
+ s:=s+Format('Content-Disposition: form-data; name="%s"; filename="%s"'+CRLF,[AFieldName,AFileName]);
|
|
|
+ s:=s+'Content-Type: application/octet-string'+CRLF+CRLF;
|
|
|
SS:=TStringStream.Create(s);
|
|
|
try
|
|
|
SS.Seek(0,soFromEnd);
|
|
@@ -1175,18 +1484,5 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-class procedure TFPCustomHTTPClient.HEAD(AURL : String; Headers: TStrings);
|
|
|
-begin
|
|
|
- With Self.Create(nil) do
|
|
|
- try
|
|
|
- RequestHeaders.Add('Connection: Close');
|
|
|
- HTTPMethod('HEAD', AURL, Nil, [200]);
|
|
|
- Headers.Assign(ResponseHeaders);
|
|
|
- Finally
|
|
|
- Free;
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
end.
|
|
|
|