Quick.HttpClient.pas 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. { ***************************************************************************
  2. Copyright (c) 2016-2018 Kike Pérez
  3. Unit : Quick.HttpClient
  4. Description : Json Http Client
  5. Author : Kike Pérez
  6. Version : 1.1
  7. Created : 22/05/2018
  8. Modified : 27/05/2018
  9. This file is part of QuickLib: https://github.com/exilon/QuickLib
  10. ***************************************************************************
  11. Licensed under the Apache License, Version 2.0 (the "License");
  12. you may not use this file except in compliance with the License.
  13. You may obtain a copy of the License at
  14. http://www.apache.org/licenses/LICENSE-2.0
  15. Unless required by applicable law or agreed to in writing, software
  16. distributed under the License is distributed on an "AS IS" BASIS,
  17. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. See the License for the specific language governing permissions and
  19. limitations under the License.
  20. *************************************************************************** }
  21. unit Quick.HttpClient;
  22. {$i QuickLib.inc}
  23. interface
  24. uses
  25. Classes,
  26. SysUtils,
  27. {$IFDEF DELPHIXE8_UP}
  28. System.Net.HttpClient,
  29. System.Net.URLClient,
  30. System.NetConsts,
  31. System.JSON;
  32. {$ELSE}
  33. IdHTTP,
  34. IdException,
  35. {$IFDEF FPC}
  36. fpjson;
  37. {$ELSE}
  38. Data.DBXJSON;
  39. {$ENDIF}
  40. {$ENDIF}
  41. type
  42. IHttpRequestResponse = interface
  43. ['{64DC58F7-B551-4619-85E9-D13E781529CD}']
  44. function StatusCode : Integer;
  45. function StatusText : string;
  46. function Response : TJSONObject;
  47. end;
  48. THttpRequestResponse = class(TInterfacedObject,IHttpRequestResponse)
  49. private
  50. fStatusCode : Integer;
  51. fStatusText : string;
  52. fResponse : TJSONObject;
  53. public
  54. {$IFDEF DELPHIXE8_UP}
  55. constructor Create(aResponse : IHTTPResponse; const aContent : string);
  56. {$ELSE}
  57. constructor Create(aResponse : TIdHTTPResponse; const aContent : string);
  58. {$ENDIF}
  59. destructor Destroy; override;
  60. function StatusCode : Integer;
  61. function StatusText : string;
  62. function Response : TJSONObject;
  63. end;
  64. TJsonHttpClient = class
  65. private
  66. {$IFDEF DELPHIXE8_UP}
  67. fHTTPClient : System.Net.HttpClient.THTTPClient;
  68. {$ELSE}
  69. fHTTPClient : TIdHTTP;
  70. {$ENDIF}
  71. fUserAgent : string;
  72. fContentType : string;
  73. fResponseTimeout : Integer;
  74. fConnectionTimeout : Integer;
  75. fHandleRedirects : Boolean;
  76. procedure SetContentType(const aValue: string);
  77. procedure SetUserAgent(const aValue: string);
  78. procedure SetResponseTimeout(const aValue: Integer);
  79. procedure SetConnectionTimeout(const aValue: Integer);
  80. procedure SetHandleRedirects(const aValue: Boolean);
  81. public
  82. constructor Create;
  83. destructor Destroy; override;
  84. property UserAgent : string read fUserAgent write SetUserAgent;
  85. property ContentType : string read fContentType write SetContentType;
  86. property ResponseTimeout : Integer read fResponseTimeout write SetResponseTimeout;
  87. property ConnectionTimeout : Integer read fConnectionTimeout write SetConnectionTimeout;
  88. property HandleRedirects : Boolean read fHandleRedirects write SetHandleRedirects;
  89. function Get(const aURL : string) : IHttpRequestResponse;
  90. function Post(const aURL, aInContent : string) : IHttpRequestResponse; overload;
  91. function Post(const aURL : string; aJsonContent : TJsonObject) : IHttpRequestResponse; overload;
  92. function Put(const aURL, aInContent : string) : IHttpRequestResponse;
  93. end;
  94. implementation
  95. const
  96. DEF_USER_AGENT = 'XLHttpClient';
  97. constructor TJsonHttpClient.Create;
  98. begin
  99. {$IFDEF DELPHIXE8_UP}
  100. fHTTPClient := THTTPClient.Create;
  101. fHTTPClient.ContentType := 'application/json';
  102. fHTTPClient.UserAgent := DEF_USER_AGENT;
  103. {$ELSE}
  104. fHTTPClient := TIdHTTP.Create(nil);
  105. fHTTPClient.Request.ContentType := 'application/json';
  106. fHTTPClient.Request.UserAgent := DEF_USER_AGENT;
  107. {$ENDIF}
  108. end;
  109. destructor TJsonHttpClient.Destroy;
  110. begin
  111. fHTTPClient.Free;
  112. inherited;
  113. end;
  114. function TJsonHttpClient.Get(const aURL : string) : IHttpRequestResponse;
  115. var
  116. {$IFDEF DELPHIXE8_UP}
  117. resp : IHTTPResponse;
  118. {$ELSE}
  119. resp : TIdHTTPResponse;
  120. {$ENDIF}
  121. bodycontent : TStringStream;
  122. responsecontent : TStringStream;
  123. begin
  124. bodycontent := TStringStream.Create;
  125. try
  126. responsecontent := TStringStream.Create;
  127. try
  128. {$IFDEF DELPHIXE8_UP}
  129. resp := fHTTPClient.Get(aURL,responsecontent,nil);
  130. {$ELSE}
  131. {$IFDEF FPC}
  132. fHTTPClient.Get(aURL,responsecontent);
  133. {$ELSE}
  134. fHTTPClient.Get(aURL,responsecontent,nil);
  135. {$ENDIF}
  136. resp := fHTTPClient.Response;
  137. {$ENDIF}
  138. Result := THttpRequestResponse.Create(resp,responsecontent.DataString);
  139. finally
  140. responsecontent.Free;
  141. end;
  142. finally
  143. bodycontent.Free;
  144. end;
  145. end;
  146. function TJsonHttpClient.Post(const aURL, aInContent : string) : IHttpRequestResponse;
  147. var
  148. {$IFDEF DELPHIXE8_UP}
  149. resp : IHTTPResponse;
  150. {$ELSE}
  151. resp : TIdHTTPResponse;
  152. {$ENDIF}
  153. responsecontent : TStringStream;
  154. postcontent : TStringStream;
  155. begin
  156. postcontent := TStringStream.Create(Utf8Encode(aInContent));
  157. try
  158. //postcontent.WriteString(aInContent);
  159. responsecontent := TStringStream.Create;
  160. try
  161. {$IFDEF DELPHIXE8_UP}
  162. resp := fHTTPClient.Post(aURL,postcontent,responsecontent);
  163. {$ELSE}
  164. {$IFDEF FPC}
  165. try
  166. fHTTPClient.Post(aURL,postcontent,responsecontent);
  167. fHTTPClient.Disconnect(False);
  168. except
  169. on E : Exception do
  170. begin
  171. if e.ClassType <> EIdConnClosedGracefully then raise e;
  172. end;
  173. end;
  174. {$ELSE}
  175. fHTTPClient.Post(aURL,postcontent,responsecontent);
  176. {$ENDIF}
  177. resp := fHTTPClient.Response;
  178. {$ENDIF}
  179. Result := THttpRequestResponse.Create(resp,responsecontent.DataString);
  180. finally
  181. responsecontent.Free;
  182. end;
  183. finally
  184. postcontent.Free;
  185. end;
  186. end;
  187. function TJsonHttpClient.Post(const aURL : string; aJsonContent : TJsonObject) : IHttpRequestResponse;
  188. begin
  189. {$IFDEF DELPHIXE8_UP}
  190. Result := Self.Post(aURL,aJsonContent.ToJSON);
  191. {$ELSE}
  192. {$IFDEF FPC}
  193. Result := Self.Post(aURL,aJsonContent.AsJson);
  194. {$ELSE}
  195. Result := Self.Post(aURL,aJsonContent.ToString);
  196. {$ENDIF}
  197. {$ENDIF}
  198. end;
  199. function TJsonHttpClient.Put(const aURL, aInContent : string) : IHttpRequestResponse;
  200. var
  201. {$IFDEF DELPHIXE8_UP}
  202. resp : IHTTPResponse;
  203. {$ELSE}
  204. resp : TIdHTTPResponse;
  205. {$ENDIF}
  206. responsecontent : TStringStream;
  207. postcontent : TStringStream;
  208. begin
  209. postcontent := TStringStream.Create(Utf8Encode(aInContent));
  210. try
  211. //postcontent.WriteString(aInContent);
  212. responsecontent := TStringStream.Create;
  213. try
  214. {$IFDEF DELPHIXE8_UP}
  215. resp := fHTTPClient.Put(aURL,postcontent,responsecontent);
  216. {$ELSE}
  217. {$IFDEF FPC}
  218. try
  219. fHTTPClient.Put(aURL,postcontent,responsecontent);
  220. fHTTPClient.Disconnect(False);
  221. except
  222. on E : Exception do
  223. begin
  224. if e.ClassType <> EIdConnClosedGracefully then raise e;
  225. end;
  226. end;
  227. {$ELSE}
  228. fHTTPClient.Post(aURL,postcontent,responsecontent);
  229. {$ENDIF}
  230. resp := fHTTPClient.Response;
  231. {$ENDIF}
  232. Result := THttpRequestResponse.Create(resp,responsecontent.DataString);
  233. finally
  234. responsecontent.Free;
  235. end;
  236. finally
  237. postcontent.Free;
  238. end;
  239. end;
  240. procedure TJsonHttpClient.SetConnectionTimeout(const aValue: Integer);
  241. begin
  242. fConnectionTimeout := aValue;
  243. {$IFDEF DELPHIXE8_UP}
  244. fHTTPClient.ConnectionTimeout := aValue;
  245. {$ELSE}
  246. fHTTPClient.ConnectTimeout := aValue;
  247. {$ENDIF}
  248. end;
  249. procedure TJsonHttpClient.SetContentType(const aValue: string);
  250. begin
  251. fContentType := aValue;
  252. {$IFDEF DELPHIXE8_UP}
  253. fHTTPClient.ContentType := aValue;
  254. {$ELSE}
  255. fHTTPClient.Request.ContentType := aValue;
  256. {$ENDIF}
  257. end;
  258. procedure TJsonHttpClient.SetHandleRedirects(const aValue: Boolean);
  259. begin
  260. fHandleRedirects := aValue;
  261. {$IFDEF DELPHIXE8_UP}
  262. fHTTPClient.HandleRedirects := aValue;
  263. {$ELSE}
  264. fHTTPClient.HandleRedirects := aValue;
  265. {$ENDIF}
  266. end;
  267. procedure TJsonHttpClient.SetResponseTimeout(const aValue: Integer);
  268. begin
  269. fResponseTimeout := aValue;
  270. {$IFDEF DELPHIXE8_UP}
  271. fHTTPClient.ResponseTimeout := aValue;
  272. {$ELSE}
  273. fHTTPClient.ReadTimeout := aValue;
  274. {$ENDIF}
  275. end;
  276. procedure TJsonHttpClient.SetUserAgent(const aValue: string);
  277. begin
  278. fUserAgent := aValue;
  279. {$IFDEF DELPHIXE8_UP}
  280. fHTTPClient.UserAgent := aValue;
  281. {$ELSE}
  282. fHTTPClient.Request.UserAgent := aValue;
  283. {$ENDIF}
  284. end;
  285. { THttpRequestResponse }
  286. {$IFDEF DELPHIXE8_UP}
  287. constructor THttpRequestResponse.Create(aResponse: IHTTPResponse; const aContent : string);
  288. begin
  289. fStatusCode := aResponse.StatusCode;
  290. fStatusText := aResponse.StatusText;
  291. if aContent <> '' then fResponse := TJSONObject.ParseJSONValue(aContent) as TJSONObject;
  292. //if response is not json, get as json result
  293. if fResponse = nil then
  294. begin
  295. fResponse := TJSONObject.Create;
  296. fResponse.AddPair('Result',aContent);
  297. end;
  298. end;
  299. {$ELSE}
  300. constructor THttpRequestResponse.Create(aResponse : TIdHTTPResponse; const aContent : string);
  301. begin
  302. fStatusCode := aResponse.ResponseCode;
  303. fStatusText := aResponse.ResponseText;
  304. if (aContent.Contains('{')) and (aContent.Contains('}')) then fResponse := GetJSON(aContent) as TJsonObject;
  305. //if response is not json, get as json result
  306. if fResponse = nil then
  307. begin
  308. fResponse := TJSONObject.Create;
  309. fResponse.Add('Result',aContent);
  310. end;
  311. end;
  312. {$ENDIF}
  313. destructor THttpRequestResponse.Destroy;
  314. begin
  315. if Assigned(fResponse) then fResponse.Free;
  316. inherited;
  317. end;
  318. function THttpRequestResponse.Response: TJSONObject;
  319. begin
  320. Result := fResponse;
  321. end;
  322. function THttpRequestResponse.StatusCode: Integer;
  323. begin
  324. Result := fStatusCode;
  325. end;
  326. function THttpRequestResponse.StatusText: string;
  327. begin
  328. Result := fStatusText;
  329. end;
  330. end.