[SOLVED] webserver does not receive files lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- egsuh · 2022-12-04 14:04 I was replying to questions on webserver related questions, but ironically I cannot make my own webserver to receive files. I think I had similar experience in the past, but cannot remember how I solved it. Server-side code is as following. It will display the local file names. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TwmWebTests.upfileRequest(Sender: TObject; ARequest: TRequest;  AResponse: TResponse; var Handled: Boolean);var   i: integer;   s: string;begin   s := Format('Files uploaded (count=%d):
', [ARequest.Files.Count]);   for i := 0 to ARequest.Files.Count-1 do begin       s += ARequest.Files[i].LocalFileName + '
';   end;   AResponse.Content := s;   Handled:= True;end;  And html file that sends file to the server is : Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  
File Upload 
 
   When I select a file and submit from the browser, it displays following. So, there are no problem in setting up webserver itself. Quote     Files Uploaded (count=0): Server is Windows Server 2019 Standard. ---------------------------------------------------------------------- Leledumbo · 2022-12-04 23:47 Quote from: egsuh on December 04, 2022, 03:04:16 pm
File Upload File upload requires: Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i enctype="multipart/form-data" in the form attribute, cannot be with the default "application/x-www-form-urlencoded". ---------------------------------------------------------------------- egsuh · 2022-12-05 05:27 Wow, now it works. Following is displayed on submission. QuoteFiles uploaded (count=1): C:\Windows\TEMP\CGI00016.tmp There are many web pages that explain how to write HTML for file uploads, but I couldn't find any example that specified enctype. ---------------------------------------------------------------------- Leledumbo · 2022-12-06 06:43 Quote from: egsuh on December 05, 2022, 06:27:44 amThere are many web pages that explain how to write HTML for file uploads, but I couldn't find any example that specified enctype. No idea with that, when I first learned it back about 15 years ago, all tutorials specifically mention it. I guess today people don't really write HTML by hand and forget about this detail? I really don't know. But I do know many frameworks provide a function that only needs to be passed any element, typically div, then it magically turns into a file upload, hiding it from the programmer. ---------------------------------------------------------------------- krolikbest · 2022-12-07 19:20 Hi, to avoid create new thread I linked my question there. So simply code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program project1; {$mode objfpc}{$H+} uses   {$IFDEF UNIX}{$IFDEF UseCThreads}  cthreads,  {$ENDIF}{$ENDIF}  sysutils, fphttpapp, HTTPDefs, fpwebfile, httproute; procedure Test(aReq: TRequest; aRes: TResponse);var  n: Integer;  f: TUploadedFile;  i: Integer;  s : string; begin   n := AReq.Files.Count;   if n = 0 then   begin      aRes.Code:=200;      aRes.Contents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'fileUploader.html');   end      else   begin     f := AReq.Files[0];     f.LocalFileName:=ExtractFilePath(ParamStr(0)); //apparently this does not set a default folder     s:=f.LocalFileName;     ARes.Code:=200;     ARes.Content := s;   end;end; begin  Application.Port:=8080;  HTTPRouter.RegisterRoute('/',@Test, true);  Application.threaded := true;  Application.Initialize;  Application.Run;end.                      It works but question is how can I set a specified folder on server side  for uploaded files? Using LocalFileName as I did seems to be incorrect.. Regards, ---------------------------------------------------------------------- krolikbest · 2022-12-07 19:37 Ach, ok. Solved ---------------------------------------------------------------------- Leledumbo · 2022-12-08 03:41 Left a trace for future people who have the same problem. As in most other implementations, uploaded files are typically downloaded into a temporary directory. In fcl-web implementation, it's in whatever returned by GetTempDir, which typically reads TEMP environment variable so users can override it from the command line. There are however, multiple other ways to do the same from application level: TRequest.DefaultRequestUploadDir, this is a class variable, can be set in global context not requiring any instance to be made firstWrite your own HTTP server implementation with a TRequest descendant that overrides GetTempUploadFileName (to be honest, this is too much)Just pick your option. ---------------------------------------------------------------------- krolikbest · 2022-12-08 08:19 Hi,  currently I'm writing without access to the code so a bit from memory but I did something like:  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i      f := AReq.Files[0];     s:=f.FileName;     ARes.Code:=200;     ARes.Contents.LoadFromStream(f.Stream); //this line loads contents of the uploaded file     ARes.Contents.SaveToFile(your_path_file); //this line save this contents to the new created file     ARes.Content := s; Of course such solution still writes in TempDir as well and to avoid it one need to follow your tips. Then there is no need to use my solution. Regards, ---------------------------------------------------------------------- egsuh · 2022-12-08 09:29 Aren’t there anything like f.savetofile(your_file_path)? ---------------------------------------------------------------------- krolikbest · 2022-12-08 11:30 Hi  f is TUploadedFile class according to https://wiki.freepascal.org/fpWeb_Tutorial#Reading_File_Uploads. Didn't check if is it possible to simply use f.saveToFile. ---------------------------------------------------------------------- Leledumbo · 2022-12-08 14:49 Quote from: egsuh on December 08, 2022, 10:29:44 amAren’t there anything like f.savetofile(your_file_path)? Unfortunately, no. This is the interface of TUploadedFile: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   TUploadedFile = Class(TCollectionItem)  Private    FContentType: String;    FDescription: String;    FDisposition: String;    FFieldName: String;    FFileName: String;    FLocalFileName: String;  FSize: Int64;    FStream : TStream;  Protected    // Note that this will free the file stream, to be able to close it - file is share deny write locked!    Procedure DeleteTempUploadedFile; virtual;    function GetStream: TStream; virtual;    Procedure FreeStream; virtual;  Public    Destructor Destroy; override;    Property FieldName : String Read FFieldName Write FFieldName;    Property FileName : String Read FFileName Write FFileName;    Property Stream : TStream Read GetStream;    Property Size : Int64 Read FSize Write FSize;    Property ContentType : String Read FContentType Write FContentType;    Property Disposition : String Read FDisposition Write FDisposition;    Property LocalFileName : String Read FLocalFileName Write FLocalFileName;    Property Description : String Read FDescription Write FDescription;  end; You can, however, make your own implementation that has such a method by extending this class and assigning it to httpdefs' UploadedFileClass variable. But for me, this interface is enough for most use cases. The Stream property is the key to do everything possible to uploaded files. ---------------------------------------------------------------------- krolikbest · 2022-12-08 19:07 Hi, Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i       SetLength(f, AReq.Files.Count);      f[0] := AReq.Files[0];      ms:=TMemoryStream.Create;      f[0].Stream.Position:=0;      ms.CopyFrom(f[0].Stream, f[0].Stream.Size);      ms.SaveToFile(ExtractFilePath(ParamStr(0))+'\tst.txt');      ms.Free;           Regards,