BrookHTTPUploads.pas 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. (* _ _
  2. * | |__ _ __ ___ ___ | | __
  3. * | '_ \| '__/ _ \ / _ \| |/ /
  4. * | |_) | | | (_) | (_) | <
  5. * |_.__/|_| \___/ \___/|_|\_\
  6. *
  7. * Microframework which helps to develop web Pascal applications.
  8. *
  9. * Copyright (c) 2012-2021 Silvio Clecio <[email protected]>
  10. *
  11. * Brook framework is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation; either
  14. * version 2.1 of the License, or (at your option) any later version.
  15. *
  16. * Brook framework is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with Brook framework; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *)
  25. { Contains classes for upload handling. }
  26. unit BrookHTTPUploads;
  27. {$I BrookDefines.inc}
  28. interface
  29. uses
  30. SysUtils,
  31. Marshalling,
  32. libsagui,
  33. BrookUtility,
  34. BrookHandledClasses;
  35. type
  36. TBrookHTTPUploads = class;
  37. { Structured type which holds the upload properties and allows to save the
  38. uploaded file. }
  39. TBrookHTTPUpload = packed record
  40. private
  41. FHandle: Psg_httpupld;
  42. FStreamHandle: Pointer;
  43. FDirectory: string;
  44. FField: string;
  45. FName: string;
  46. FMime: string;
  47. FEncoding: string;
  48. FSize: UInt64;
  49. function GetHandle: Pointer;
  50. public
  51. { Creates an instance of @code(TBrookHTTPUpload).
  52. @param(AHandle[in] Upload handle.) }
  53. constructor Create(AHandle: Pointer);
  54. { Saves the uploaded file defining the destination path by upload name and
  55. directory.
  56. @param(AOverwritten[in] Overwrite upload file if it exists.)
  57. @param(AError[out] Variable reference to store string describing the error
  58. if save fails.)
  59. @returns(@True if the uploaded file is saved successfully.) }
  60. function Save(AOverwritten: Boolean; out AError: string): Boolean; overload;
  61. { Saves the uploaded file defining the destination path by upload name and
  62. directory.
  63. @param(AError[out] Variable reference to store string describing the error
  64. if save fails.)
  65. @returns(@True if the uploaded file is saved successfully.) }
  66. function Save(out AError: string): Boolean; overload;
  67. { Saves the uploaded file defining the destination path by upload name and
  68. directory.
  69. @param(AOverwritten[in] Overwrite upload file if it exists.) }
  70. procedure Save(AOverwritten: Boolean); overload;
  71. { Saves the uploaded file defining the destination path by upload name and
  72. directory. }
  73. procedure Save; overload;
  74. { Saves the uploaded file allowing to define the destination path.
  75. @param(APath[in] Absolute destination path.)
  76. @param(AOverwritten[in] Overwrite upload file if it exists.)
  77. @param(AError[out] Variable reference to store string describing the error
  78. if save fails.)
  79. @returns(@True if the uploaded file is saved successfully.) }
  80. function SaveAs(const APath: TFileName; AOverwritten: Boolean;
  81. out AError: string): Boolean; overload;
  82. { Saves the uploaded file allowing to define the destination path.
  83. @param(APath[in] Absolute destination path.)
  84. @param(AError[out] Variable reference to store string describing the error
  85. if save fails.)
  86. @returns(@True if the uploaded file is saved successfully.) }
  87. function SaveAs(const APath: TFileName; out AError: string): Boolean; overload;
  88. { Saves the uploaded file allowing to define the destination path.
  89. @param(APath[in] Absolute destination path.)
  90. @param(AOverwritten[in] Overwrite upload file if it exists.) }
  91. procedure SaveAs(const APath: TFileName; AOverwritten: Boolean); overload;
  92. { Saves the uploaded file allowing to define the destination path.
  93. @param(APath[in] Absolute destination path.) }
  94. procedure SaveAs(const APath: TFileName); overload;
  95. { Handle of an upload. }
  96. property Handle: Pointer read GetHandle;
  97. { Stream handle of the upload. }
  98. property StreamHandle: Pointer read FStreamHandle;
  99. { Directory of the uploaded file. }
  100. property Directory: string read FDirectory;
  101. { Field name of the upload. }
  102. property Field: string read FField;
  103. { Name of the uploaded file. }
  104. property Name: string read FName;
  105. { MIME (content-type) of the upload. }
  106. property Mime: string read FMime;
  107. { Encoding (transfer-encoding) of the upload. }
  108. property Encoding: string read FEncoding;
  109. { Size of the upload. }
  110. property Size: UInt64 read FSize;
  111. end;
  112. { Enumerator used to iterate the map @code(TBrookHTTPUpload). }
  113. TBrookHTTPUploadsEnumerator = class
  114. private
  115. FUploads: TBrookHTTPUploads;
  116. FCurr: TBrookHTTPUpload;
  117. FBOF: Boolean;
  118. public
  119. { Creates an instance of @code(TBrookHTTPUploadsEnumerator).
  120. @param(AUploads[in] Uploads list.) }
  121. constructor Create(AUploads: TBrookHTTPUploads);
  122. { Gets the current upload.
  123. @returns(Current upload.) }
  124. function GetCurrent: TBrookHTTPUpload;
  125. { Moves to the next upload.
  126. @returns(@True when move next reaches the EOF.) }
  127. function MoveNext: Boolean;
  128. { Same to @code(GetCurrent). }
  129. property Current: TBrookHTTPUpload read GetCurrent;
  130. end;
  131. { Uploads list which contains all uploaded files and form fields. }
  132. TBrookHTTPUploads = class(TBrookHandledPersistent)
  133. private
  134. FHandle: Psg_httpupld;
  135. FCurrent: Psg_httpupld;
  136. function GetCount: Integer;
  137. function GetCurrent: Pointer;
  138. protected
  139. function GetHandle: Pointer; override;
  140. function IsEOF: Boolean; virtual;
  141. property Current: Pointer read GetCurrent;
  142. public
  143. { Creates an instance of @code(TBrookHTTPUploads).
  144. @param(AHandle[in] Uploads handle.) }
  145. constructor Create(AHandle: Pointer); virtual;
  146. { Gets an instance of @code(TBrookHTTPUploadsEnumerator). }
  147. function GetEnumerator: TBrookHTTPUploadsEnumerator;
  148. { Retrieves the first upload in the list.
  149. @param(AUpload[out] First upload returned.)
  150. @returns(@True when upload is found, @False otherwise.) }
  151. function First: TBrookHTTPUpload; virtual;
  152. { Retrieves the next upload in the list.
  153. @param(AUpload[out] Next upload returned.) }
  154. function Next: TBrookHTTPUpload; virtual;
  155. { Indicates the end of list. }
  156. property EOF: Boolean read IsEOF; //FI:C110
  157. { Counts the total uploads present in the list. }
  158. property Count: Integer read GetCount;
  159. end;
  160. implementation
  161. { TBrookHTTPUploadsEnumerator }
  162. constructor TBrookHTTPUploadsEnumerator.Create(AUploads: TBrookHTTPUploads);
  163. begin
  164. inherited Create;
  165. FUploads := AUploads;
  166. FCurr := FUploads.First;
  167. FBOF := True;
  168. end;
  169. function TBrookHTTPUploadsEnumerator.GetCurrent: TBrookHTTPUpload;
  170. begin
  171. Result := FCurr;
  172. end;
  173. function TBrookHTTPUploadsEnumerator.MoveNext: Boolean;
  174. begin
  175. if FBOF then
  176. FBOF := False
  177. else
  178. FCurr := FUploads.Next;
  179. Result := not FUploads.EOF;
  180. end;
  181. { TBrookHTTPUpload }
  182. constructor TBrookHTTPUpload.Create(AHandle: Pointer);
  183. begin
  184. FHandle := AHandle;
  185. SgLib.Check;
  186. FStreamHandle := sg_httpupld_handle(FHandle);
  187. FDirectory := TMarshal.ToString(sg_httpupld_dir(FHandle));
  188. FField := TMarshal.ToString(sg_httpupld_field(FHandle));
  189. FName := TMarshal.ToString(sg_httpupld_name(FHandle));
  190. FMime := TMarshal.ToString(sg_httpupld_mime(FHandle));
  191. FEncoding := TMarshal.ToString(sg_httpupld_encoding(FHandle));
  192. FSize := sg_httpupld_size(FHandle);
  193. end;
  194. function TBrookHTTPUpload.Save(AOverwritten: Boolean;
  195. out AError: string): Boolean;
  196. var
  197. R: cint;
  198. begin
  199. SgLib.Check;
  200. R := sg_httpupld_save(FHandle, AOverwritten);
  201. Result := R = 0;
  202. if not Result then
  203. AError := Sagui.StrError(R);
  204. end;
  205. function TBrookHTTPUpload.Save(out AError: string): Boolean;
  206. begin
  207. Result := Save(True, AError);
  208. end;
  209. procedure TBrookHTTPUpload.Save(AOverwritten: Boolean);
  210. begin
  211. SgLib.Check;
  212. SgLib.CheckLastError(sg_httpupld_save(FHandle, AOverwritten));
  213. end;
  214. procedure TBrookHTTPUpload.Save;
  215. begin
  216. Save(True);
  217. end;
  218. function TBrookHTTPUpload.SaveAs(const APath: TFileName; AOverwritten: Boolean;
  219. out AError: string): Boolean;
  220. var
  221. R: cint;
  222. M: TMarshaller;
  223. begin
  224. SgLib.Check;
  225. R := sg_httpupld_save_as(FHandle, M.ToCString(APath), AOverwritten);
  226. Result := R = 0;
  227. if not Result then
  228. AError := Sagui.StrError(R);
  229. end;
  230. function TBrookHTTPUpload.SaveAs(const APath: TFileName;
  231. out AError: string): Boolean;
  232. begin
  233. Result := SaveAs(APath, True, AError);
  234. end;
  235. procedure TBrookHTTPUpload.SaveAs(const APath: TFileName; AOverwritten: Boolean);
  236. var
  237. M: TMarshaller;
  238. begin
  239. SgLib.Check;
  240. SgLib.CheckLastError(sg_httpupld_save_as(FHandle, M.ToCString(APath),
  241. AOverwritten));
  242. end;
  243. procedure TBrookHTTPUpload.SaveAs(const APath: TFileName);
  244. begin
  245. SaveAs(APath, True);
  246. end;
  247. function TBrookHTTPUpload.GetHandle: Pointer;
  248. begin
  249. Result := FHandle;
  250. end;
  251. { TBrookHTTPUploads }
  252. constructor TBrookHTTPUploads.Create(AHandle: Pointer);
  253. begin
  254. inherited Create;
  255. FHandle := AHandle;
  256. end;
  257. function TBrookHTTPUploads.GetHandle: Pointer;
  258. begin
  259. Result := FHandle;
  260. end;
  261. function TBrookHTTPUploads.IsEOF: Boolean;
  262. begin
  263. Result := not Assigned(FCurrent);
  264. end;
  265. function TBrookHTTPUploads.GetEnumerator: TBrookHTTPUploadsEnumerator;
  266. begin
  267. Result := TBrookHTTPUploadsEnumerator.Create(Self);
  268. end;
  269. function TBrookHTTPUploads.First: TBrookHTTPUpload;
  270. begin
  271. FCurrent := FHandle;
  272. Result := TBrookHTTPUpload.Create(FCurrent);
  273. end;
  274. function TBrookHTTPUploads.Next: TBrookHTTPUpload;
  275. begin
  276. SgLib.Check;
  277. SgLib.CheckLastError(sg_httpuplds_next(@FCurrent));
  278. if not Assigned(FCurrent) then
  279. Exit(Default(TBrookHTTPUpload));
  280. Result := TBrookHTTPUpload.Create(FCurrent);
  281. end;
  282. function TBrookHTTPUploads.GetCount: Integer;
  283. begin
  284. SgLib.Check;
  285. Result := sg_httpuplds_count(FHandle);
  286. end;
  287. function TBrookHTTPUploads.GetCurrent: Pointer;
  288. begin
  289. Result := FCurrent;
  290. end;
  291. end.