webmodule.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. unit webmodule;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. SysUtils, Classes, httpdefs, fpHTTP, fpWeb;
  6. type
  7. { TFPWebModule1 }
  8. TFPWebModule1 = class(TFPWebModule)
  9. procedure DataModuleAfterResponse(Sender: TObject; AResponse: TResponse);
  10. procedure DataModuleCreate(Sender: TObject);
  11. procedure listfilesRequest(Sender: TObject; ARequest: TRequest;
  12. AResponse: TResponse; var Handled: Boolean);
  13. private
  14. { private declarations }
  15. UploadDir:String;
  16. FileDB:String;
  17. MaxSize:Integer;
  18. procedure DeleteTheFile(const FN:String);
  19. procedure HandleUploadedFiles;
  20. procedure listfilesReplaceTag(Sender: TObject; const TagString:String;
  21. TagParams: TStringList; Out ReplaceText: String);
  22. public
  23. { public declarations }
  24. end;
  25. var
  26. FPWebModule1: TFPWebModule1;
  27. implementation
  28. {$R *.lfm}
  29. { TFPWebModule1 }
  30. //In real applications, CopyFile should be used from unit FileUtil of the LCL
  31. function CopyTheFile(const SrcFilename, DestFilename: String): Boolean;
  32. var SrcFS, DestFS: TFileStream;
  33. begin
  34. Result := False;
  35. SrcFS := TFileStream.Create(SrcFilename, fmOpenRead or fmShareDenyWrite);
  36. try
  37. DestFS := TFileStream.Create(DestFilename, fmCreate);
  38. try
  39. DestFS.CopyFrom(SrcFS, SrcFS.Size);
  40. finally
  41. DestFS.Free;
  42. end;
  43. finally
  44. SrcFS.Free;
  45. end;
  46. Result := True;
  47. end;
  48. procedure TFPWebModule1.DataModuleAfterResponse(Sender: TObject;
  49. AResponse: TResponse);
  50. begin
  51. //reset global variables for apache modules for the next incoming request
  52. //
  53. end;
  54. procedure TFPWebModule1.DataModuleCreate(Sender: TObject);
  55. begin
  56. UploadDir := 'upfiles/';
  57. FileDB := 'filelist.txt';
  58. MaxSize := 2;//MB
  59. end;
  60. procedure TFPWebModule1.DeleteTheFile(const FN:String);
  61. var
  62. FDB: TStringList;
  63. s:String;
  64. begin
  65. FDB := TStringList.Create;
  66. if FileExists(FileDB) then
  67. FDB.LoadFromFile(FileDB);
  68. s := FDB.Values[FN];
  69. if s <> '' then
  70. begin
  71. FDB.Delete(FDB.IndexOfName(FN));
  72. FDB.SaveToFile(FileDB);
  73. FDB.Free;
  74. end else begin
  75. FDB.Free;
  76. Request.QueryFields.Add('_MSG=NOTFOUND');//NOTFOUND message will be displayed on the response page
  77. Exit;
  78. end;
  79. //delete the file
  80. s := UploadDir + FN;
  81. if FileExists(s) then
  82. DeleteFile(s);
  83. end;
  84. procedure TFPWebModule1.HandleUploadedFiles;
  85. var
  86. i:Integer;
  87. all_ok:Boolean;
  88. FDB: TStringList;
  89. Uploader, FN:String;
  90. begin
  91. if Request.Files.Count <= 0 then Exit;
  92. //process the uploaded files if there was any
  93. all_ok := true;
  94. for i := 0 to Request.Files.Count - 1 do
  95. begin//check sizes
  96. if Request.Files[i].Size > (MaxSize * 1024 * 1024) then
  97. begin//exceeds size limit
  98. all_ok := false;
  99. Request.QueryFields.Add('_MSG=TOOBIG');//TOOBIG message will be displayed on the response page
  100. break;
  101. end;
  102. end;
  103. if all_ok then //copy the file(s) to the upload directory (the temporary files will be deleted automatically after the request is handled)
  104. begin
  105. Uploader := Request.ContentFields.Values['UPLOADERPERSON'];
  106. if Uploader = '' then
  107. Uploader := '-';
  108. FDB := TStringList.Create;
  109. if FileExists(FileDB) then
  110. FDB.LoadFromFile(FileDB);
  111. for i := 0 to Request.Files.Count - 1 do
  112. begin
  113. FN := Request.Files[i].FileName;
  114. if (FN <> '')and(Request.Files[i].Size > 0) then
  115. begin
  116. CopyTheFile(Request.Files[i].LocalFileName, UploadDir + FN);//copy (or overwrite) the file to the upload dir
  117. if FDB.Values[FN] <> '' then
  118. FDB.Values[FN] := Uploader //overwrite the previous uploader
  119. else
  120. FDB.Add(FN + '=' + Uploader); //store the file and the uploader into the file database
  121. end;
  122. end;
  123. FDB.SaveToFile(FileDB);
  124. FDB.Free;
  125. end;
  126. end;
  127. procedure TFPWebModule1.listfilesRequest(Sender: TObject; ARequest: TRequest;
  128. AResponse: TResponse; var Handled: Boolean);
  129. var
  130. FN:String;
  131. begin
  132. //ModuleTemplate is a web module global property
  133. //To use the Template propery of the current web action (which is visible in
  134. //the object inspector for every Action), use
  135. //(Sender as TFPWebAction).Template.FileName := 'mytemplate1.html'; and so on.
  136. ModuleTemplate.FileName := 'uploadform.html';
  137. ModuleTemplate.AllowTagParams := true;
  138. ModuleTemplate.StartDelimiter := '{+';
  139. ModuleTemplate.EndDelimiter := '+}';
  140. ModuleTemplate.OnReplaceTag := @listfilesReplaceTag;
  141. FN := ARequest.QueryFields.Values['DELETE'];
  142. if FN <> '' then
  143. DeleteTheFile(FN)
  144. else
  145. HandleUploadedFiles;
  146. AResponse.Content := ModuleTemplate.GetContent;//Generate the response page using the template
  147. Handled := true;
  148. end;
  149. procedure TFPWebModule1.listfilesReplaceTag(Sender: TObject; const TagString:
  150. String; TagParams: TStringList; Out ReplaceText: String);
  151. var
  152. SL:TStringList;
  153. i:Integer;
  154. FileName, Uploader, One_Row:String;
  155. begin
  156. if AnsiCompareText(TagString, 'DATETIME') = 0 then
  157. begin
  158. ReplaceText := FormatDateTime(TagParams.Values['FORMAT'], Now);
  159. end else
  160. if AnsiCompareText(TagString, 'MAX_SIZE') = 0 then
  161. begin
  162. ReplaceText := IntToStr(MaxSize);
  163. end else
  164. if AnsiCompareText(TagString, 'UPLOAD_DIR') = 0 then
  165. begin
  166. ReplaceText := UploadDir;
  167. end else
  168. if AnsiCompareText(TagString, 'MESSAGES') = 0 then
  169. begin
  170. ReplaceText := TagParams.Values[Request.QueryFields.Values['_MSG']];
  171. end else
  172. if AnsiCompareText(TagString, 'FILELIST') = 0 then
  173. begin
  174. SL := TStringList.Create;
  175. if FileExists(FileDB) then
  176. SL.LoadFromFile(FileDB);
  177. if SL.Count > 0 then
  178. begin
  179. One_Row := TagParams.Values['ONE_ROW'];
  180. for i := 0 to SL.Count - 1 do
  181. begin
  182. FileName := SL.Names[i];
  183. Uploader := SL.Values[FileName];
  184. if (FileName <> '')and(Uploader <> '') then
  185. ReplaceText := ReplaceText + StringReplace(StringReplace(StringReplace(One_Row
  186. ,'~FILENAME', FileName, [])
  187. ,'~UPLOADER', Uploader, [])
  188. ,'~DFILENAME', HTTPEncode(FileName), []) + #13#10;
  189. end;
  190. end else begin
  191. ReplaceText := TagParams.Values['NOTHINGTOLIST'];
  192. end;
  193. SL.Free;
  194. end else
  195. {Message for tags not handled}
  196. begin
  197. ReplaceText := '[Template tag {+' + TagString + '+} is not implemented yet.]';
  198. end;
  199. end;
  200. initialization
  201. RegisterHTTPModule('TFPWebModule1', TFPWebModule1);
  202. end.