Lazarus

Programming => Networking and Web Programming => Topic started by: fjabouley on March 12, 2017, 08:11:43 pm

Title: TFPHTTPServer in a thread
Post by: fjabouley on March 12, 2017, 08:11:43 pm



Hello all !


I'm trying to put a http server in my program to handle simple http requests.
To do that I used this example http://forum.lazarus.freepascal.org/index.php/topic,32353.msg208620.html#msg208620, using fhttpserver library.


Everything works fine, but I got an issue freeing the Server, and a memory leak is present.


Here is an example :


Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3.  
  4. {$mode objfpc}{$H+}
  5.  
  6.  
  7. interface
  8.  
  9.  
  10. uses
  11.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  12.   fphttpserver, fpHTTP, fpWeb;
  13.  
  14.  
  15. type
  16.  
  17.  
  18.   { TForm1 }
  19.  
  20.  
  21.   TForm1 = class(TForm)
  22.     Button1: TButton;
  23.     Button2: TButton;
  24.     procedure Button1Click(Sender: TObject);
  25.     procedure Button2Click(Sender: TObject);
  26.     procedure FormDestroy(Sender: TObject);
  27.   private
  28.     { private declarations }
  29.   public
  30.     { public declarations }
  31.      procedure DoHandleRequest(Sender:TObject; var ARequest:TFPHTTPConnectionRequest; var AResponse:TFPHTTPConnectionResponse);
  32.  
  33.  
  34.   end;
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.    { THTTPServerThread }
  42.  
  43.  
  44.    THTTPServerThread = class(TThread)
  45.    Private
  46.      Fserver : TFPHTTPServer;
  47.    Public
  48.      Constructor Create(APort:Word; const OnRequest:THTTPServerRequestHandler);
  49.      Procedure Execute; Override;
  50.      Procedure DoTerminate; Override;
  51.      Property Server : TFPHTTPServer Read FServer;
  52.    end;
  53.  
  54.  
  55.  var
  56.    Form1: TForm1;
  57.    FServerThread:TFPHTTPServer;
  58.  
  59.  
  60. implementation
  61.  
  62.  
  63. {$R *.lfm}
  64.  
  65.  
  66.  
  67.  
  68. procedure TForm1.DoHandleRequest(Sender: TObject;
  69.   var ARequest: TFPHTTPConnectionRequest; var AResponse: TFPHTTPConnectionResponse);
  70. begin
  71.  showmessage( ARequest.QueryString);
  72. end;
  73.  
  74.  
  75. procedure TForm1.Button1Click(Sender: TObject);
  76. begin
  77.      FServerthread := THTTPServerThread.Create(8080,@DoHandleRequest);
  78.      FServerthread.Start;
  79. end;
  80.  
  81.  
  82. procedure TForm1.Button2Click(Sender: TObject);
  83. begin
  84.   FServerThread.Terminate;
  85. end;
  86.  
  87.  
  88. procedure TForm1.FormDestroy(Sender: TObject);
  89. begin
  90.     if Assigned(Fserverthread) then
  91.   begin
  92.     Fserverthread.Terminate;
  93.     Fserverthread.WaitFor;
  94.     FreeAndNil(Fserverthread);
  95.   end;
  96. end;
  97.  
  98.  
  99. constructor THTTPServerThread.Create(APort: Word;
  100.   const OnRequest: THTTPServerRequestHandler);
  101. begin
  102.   Inherited Create(True);
  103.   FServer := TFPHTTPServer.Create(Nil);
  104.      FServer.Threaded:=true;
  105.      FServer.Port := APort;
  106.      FServer.OnRequest := OnRequest;
  107.  
  108.  
  109. end;
  110.  
  111.  
  112. procedure THTTPServerThread.Execute;
  113. begin
  114.         try
  115.            FServer.Active:=true;
  116.            while not terminated do sleep(10);
  117.         finally
  118.            FreeAndNil(FServer);
  119.         end;
  120. end;
  121.  
  122.  
  123. procedure THTTPServerThread.DoTerminate;
  124. begin
  125.   inherited DoTerminate;
  126.   FServer.Active:=false;
  127. end;
  128.  
  129.  
  130.  
  131.  
  132. end.
  133.  
  134.  


I asked our god rvk and here is his answer :


Quote
Ok, the problem is the FServer.Active := true;
That just starts the listening server and execution stops until a response is received.
So it's essentially a loop itself so you can remove the while not terminated again.
You need to add the DoTerminate again to be able to stop the FServer.


But the problem is, that the DoTerminate is never executed in the thread anymore.
(you can see that by putting showmessages or breakpoints in the right places)


I'm not familiar with the TFPHTTPServer in a thread.
You could try to stop the server directory instead of calling Terminate but that didn't work for me either.


The main question is : How to stop correctly the thread/server ?


Thanks  !!!!

Title: Re: TFPHTTPServer in a thread
Post by: rvk on March 12, 2017, 10:19:04 pm
Additionally we tried this:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. begin
  3.   // FServerThread.Terminate;
  4.   FServerThread.FServer.Active := False;
  5. end;
to stop the FServer in the thread directly in the hope execution will continue in the execute-function of the thread but it didn't.

So, how does one stop the execution of TFPHTTPServer.Active := True; ?
Title: Re: TFPHTTPServer in a thread
Post by: russdirks on April 07, 2017, 12:20:03 am
I'm also interested in a solution to this.  My code is very similar to the above.  Since there is no way to normally exit from the Execute method,  I try to stop the server using a public method that is called from the main program:

Code: Pascal  [Select][+][-]
  1.  
  2. procedure CServerThread.Execute;
  3. begin
  4.    m_owner.m_server.Active := true;     // this does not return until the server is deactivated
  5.    m_owner.LogMsg('server is inactive');
  6. end;
  7.  
  8.  
  9. procedure CHttpServer.stopServer;
  10. begin
  11.     m_server.Active := false;
  12. end;
  13.  

This produces an ESocketError : Could not accept a client connection on socket: 476, error 10038.

This is on Windows 10.
Title: Re: TFPHTTPServer in a thread
Post by: russdirks on April 07, 2017, 01:23:50 am
Just tried my code on OSX and I was able to stop the server fine, so maybe it is a Windows thing.
Title: Re: TFPHTTPServer in a thread
Post by: tudi_x on July 17, 2017, 05:54:54 pm
what are the options for Windows in this case? Synapse?

thank you
Title: Re: TFPHTTPServer in a thread
Post by: Cyrax on July 17, 2017, 10:24:27 pm
what are the options for Windows in this case? Synapse?

thank you

AFAIK, same?
Title: Re: TFPHTTPServer in a thread
Post by: Blestan on July 17, 2017, 10:50:01 pm
take look on my ultramachine api backend... it not fully funtional yet but the multithreaded http server works and its stable and tested on win 10 and debian 8.4
Title: Re: TFPHTTPServer in a thread
Post by: rvk on July 18, 2017, 10:36:14 am
what are the options for Windows in this case? Synapse?
It seems that the latest version 1.8RC2 with FPC 3.1.1 can stop the server under Windows with FServer.Active := False;

Do you have problems with it?
Title: Re: TFPHTTPServer in a thread
Post by: tudi_x on July 18, 2017, 12:53:17 pm
I have tested the attached project with Lazarus 1.8 RC3 and FPC 3.0.2.
I need to stay with FPC3.0.2 as this is for production module.
The stopping of the server does not occur when pressing the stop button.

Please advise why you would think is working with the FPC3.1.1 version?

thank you
Title: Re: TFPHTTPServer in a thread
Post by: rvk on July 18, 2017, 01:09:25 pm
Please advise why you would think is working with the FPC3.1.1 version?
I tested it and it worked :)

I do see some problems with your code.
DoTerminate is never executed for the thread. You might think that _t.Terminate will call _t.DoTerminate at some point but it doesn't (I'm not sure why but thread-expert might be able to explan that one).

I did the following to you code to get it working:
- move Server variable in thread to public (we need to call it directly to stop the server)
- you could also create a terminate method for that (but I did it this way)
- set FreeOnTerminate to true
- move Server.Free; to destroy of the thread. Not in the execute. You create it in create() so free it in destroy.


http_listen looks like this:
Code: Pascal  [Select][+][-]
  1. unit http_listen;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, fphttpapp, fphttpserver;
  9.  
  10. type
  11.   THTTPServerThread = class(TThread)
  12.   private
  13.     _Error: string;
  14.   public
  15.     Server: TFPHTTPServer;
  16.     constructor Create(APort: word; const OnRequest: THTTPServerRequestHandler);
  17.     destructor Destroy; override;
  18.     procedure Execute; override;
  19.     property Error: string read _Error;
  20.   end;
  21.  
  22. implementation
  23.  
  24. constructor THTTPServerThread.Create(APort: word; const OnRequest: THTTPServerRequestHandler);
  25. begin
  26.   Server := TFPHTTPServer.Create(nil);
  27.   Server.Port := APort;
  28.   Server.OnRequest := OnRequest;
  29.   _Error := 'nil';
  30.   Self.FreeOnTerminate := true;
  31.   inherited Create(False);
  32. end;
  33.  
  34. destructor THTTPServerThread.Destroy;
  35. begin
  36.   Server.Free;
  37. end;
  38.  
  39. procedure THTTPServerThread.Execute;
  40. begin
  41.   try
  42.     Server.Active := True;
  43.   except
  44.     on E: Exception do
  45.     begin
  46.       _Error := E.Message;
  47.     end;
  48.   end;
  49. end;
  50.  
  51. end.
And main.pas looks like this:
Code: Pascal  [Select][+][-]
  1. unit main;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
  9.   StdCtrls, http_listen, fphttpserver;
  10.  
  11. type
  12.   TForm1 = class(TForm)
  13.     stop: TButton;
  14.     start: TButton;
  15.     Memo1: TMemo;
  16.     procedure FormCreate(Sender: TObject);
  17.     procedure startClick(Sender: TObject);
  18.     procedure stopClick(Sender: TObject);
  19.     procedure onRequest(Sender: TObject; var ARequest: TFPHTTPConnectionRequest;
  20.       var AResponse: TFPHTTPConnectionResponse);
  21.   end;
  22.  
  23. var
  24.   Form1: TForm1;
  25.   _t: THTTPServerThread;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30. procedure TForm1.startClick(Sender: TObject);
  31. begin
  32.   start.Enabled := False;
  33.   _t := THTTPServerThread.Create(8001, @onRequest);
  34.   stop.Enabled := True;
  35. end;
  36.  
  37. procedure TForm1.FormCreate(Sender: TObject);
  38. begin
  39.   stop.Enabled := False;
  40. end;
  41.  
  42. procedure TForm1.stopClick(Sender: TObject);
  43. begin
  44.   stop.Enabled := False;
  45.   // _t.Terminate;
  46.   _t.Server.Active := False; // <-- _t is automatically freed
  47.   start.Enabled := True;
  48. end;
  49.  
  50. procedure TForm1.onRequest(Sender: TObject; var ARequest: TFPHTTPConnectionRequest;
  51.   var AResponse: TFPHTTPConnectionResponse);
  52. begin
  53.   Memo1.Append('HTTP request');
  54. end;
  55.  
  56.  
  57. end.
This worked fine for me (Lazarus 18RC2 FPC 3.1.1).
Title: Re: TFPHTTPServer in a thread
Post by: tudi_x on July 18, 2017, 01:23:50 pm
worked beautifully.
i will try to make a wiki page with the LinkedIn Outh2 integration code you helped me.

thank you very much rvk
Title: Re: TFPHTTPServer in a thread
Post by: euMesmo on July 17, 2019, 05:54:19 pm
Good afternoon.
Searching the internet I found this forum.
I am developing a multiplatform application in Lazarus. This application creates html, css and javascript files which I want users to be able to preview on a web server.
I have tried what is proposed in this forum but I have a problem. How can I indicate, in my application, what is the path to show the files that the program creates?
Thank you for your work, time and attention.
Greetings.
Title: Re: TFPHTTPServer in a thread
Post by: lucamar on July 18, 2019, 12:28:31 am
Make your program create a web page at some fixed point with links to the created fle?

Or if it's a CGI or similar just return a redirection.
Title: Re: TFPHTTPServer in a thread
Post by: euMesmo on July 18, 2019, 12:48:02 am
Hello lucamar, thank you for answering.
My program http://www.webardora.net, to make a preview, creates the files in a temporary folder that I then open with the default browser as a local file. Although the program has the possibility for the user to install a web server and indicate its path to create the files there and open them as "localhost" I would like to be able to do it from the same program without users having to install anything.

I have already tried the rvk solution but I am lost at the point that just as I can indicate a server port can also indicate the path to open html.

Thank you very much. Excuseme, english is not my language.
Title: Re: TFPHTTPServer in a thread
Post by: rvk on July 18, 2019, 10:03:24 am
... I would like to be able to do it from the same program without users having to install anything.
So the target computer doesn't have a browser? And you don't want to install or rely on an external browser?

In that case you shouldn't even need a TFPHTTPServer, because you don't even have a browser.
You would need to use some HTML-viewer component.
Like THtmlPort https://wiki.freepascal.org/THtmlPort or fpbrowser https://wiki.freepascal.org/fpbrowser

If the target computer does have a browser and you want to provide a webpage to that browser via localhost you can look at the example here:
https://wiki.freepascal.org/Light_Web_Server
Title: Re: TFPHTTPServer in a thread
Post by: euMesmo on July 18, 2019, 12:43:24 pm
Thank you for your interest rvk, but that is not the problem.

I will try to explain. My application creates web pages (html+css+js) based on parameters entered by the user. To preview the application creates all the necessary files in a temporary folder and then the application opens the html file in the browser that the system has by default. The problem is that several of the contents it creates cannot be seen in the browser in local (cross-origin error) by using "file:///..." being necessary "http://".

In case the computer has installed a web server (WAMP type) the application creates the files in a temporary folder of the folder to which the "localhost" points and then opens the browser with the url of the localhost and the html created.

I would like the application to have an integrated web server so that the user does not have to install any WAMP type server and that when the preview is made it opens in the browser under an http server.

When I saw the rvk code I thought it was what I was looking for but my problem is that I don't know in which path I should create the files to call localhost:8001 from the system's default browser.

I hope I have explained.
Thank you for your time.
Title: Re: TFPHTTPServer in a thread
Post by: rvk on July 18, 2019, 12:58:38 pm
I would like the application to have an integrated web server so that the user does not have to install any WAMP type server and that when the preview is made it opens in the browser under an http server.

When I saw the rvk code I thought it was what I was looking for but my problem is that I don't know in which path I should create the files to call localhost:8001 from the system's default browser.
Ok, that makes it clearer.
The code in this topic was for a specific different problem.

Did you look at some other examples of TFPHTTPServer yet.
For example: lazarus_directory\fpc\3.0.4\source\packages\fcl-web\examples\httpserver
(sample source also here: https://github.com/alrieckert/freepascal/blob/master/packages/fcl-web/examples/httpserver/simplehttpserver.pas)

You can see that with Serv.Port:=8080; you can set the port to use (i.e. http://localhost:8080 in this line)
In TTestHTTPServer.HandleRequest() you see that the requested file (in ARequest.Url) is read from the BaseDir (which you can set with Serv.BaseDir:=ExtractFilePath(ParamStr(0)); )

So simplehttpserver.pas should have everything you need to supply a default browser with a complete website on an alternate port (other than 80).
Title: Re: TFPHTTPServer in a thread
Post by: lucamar on July 18, 2019, 03:48:19 pm
You can use rvk's code (https://forum.lazarus.freepascal.org/index.php/topic,36178.msg253151.html#msg253151) without problems (I just tested it).

Just add some code to the OnRequest method (in the main form) to handle returning the files from wherever you put them.

This is an extremely simple example which just tries to find the file(s) in the current directory, but nothing prevents you from serving them from anywhere else. In that case, though, you will have to deal with the paths in the request by yourself--but that's not cumbersome or difficult:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.OnRequest(Sender: TObject;
  2.   var ARequest: TFPHTTPConnectionRequest;
  3.   var AResponse: TFPHTTPConnectionResponse);
  4. var
  5.   AFilename: String;
  6. begin
  7.   AFilename := ARequest.URI;
  8.   {Get rid of the starting bars so we won't serve from '/'
  9.    Theres should be only one, but just in case ...}
  10.   while AFilename.StartsWith('/') or AFilename.StartsWith('.') do
  11.     Delete(AFilename, 1, 1);
  12.   {Alternatively, one could just do:
  13.     AFilename := GeCurrentDir + AFilename;
  14.   or whatever the web-root directory is,
  15.   but that's not very secure}
  16.  
  17.   { If we find the file, serve it; if not, fawn about it}
  18.   if FileExists(AFilename) then begin
  19.     AResponse.Code := 200;
  20.     AResponse.Content := ReadFileToString(AFilename);
  21.   end else begin
  22.     AResponse.Code := 404;
  23.     AResponse.Content := 'Sorry, don''t have any "' + AFilename +'"';
  24.   end;
  25. end;

With my test program running ((it incorporates the example code) if, for example, I ask in the browser for:
  http://localhost:8081/unit1.pas
it shows the source for the unit.
Title: Re: TFPHTTPServer in a thread
Post by: euMesmo on July 18, 2019, 09:42:32 pm
Many thanks to rvk and lucamar, your comments have been very helpful.
Title: Re: TFPHTTPServer in a thread
Post by: euMesmo on July 27, 2019, 03:51:42 pm
I've been testing rvk's code by adding lucamar's code but I can't get it to work properly.

Everything works fine if you open simple files like plain text or static html (without css or js).

As you can see in the attachment, if I run the server in "start", and, in the browser I open (http://localhost:8001/01taller/01taller.htm) an html containing css and javascript seems not to load the styles of the file css. However, javascript seems to work correctly.

I added to the lucamar code the line "Arequest.ProtocolVersion:='HTTP/1.1';" because it returned an error message "Missing HTTP protocol version in request".

I have tried several things, such as adding mimetypes but I can't move forward. Can you help me?

Thank you very much.
Title: Re: TFPHTTPServer in a thread
Post by: rvk on July 28, 2019, 01:00:52 am
I can confirm there is something really weird going on in fphttpserver.

You should have seen the .css request but instead you get the "no HTTP/" exception.

Tracing though it, I see that for the .css request, the function TFPHTTPConnection.ReadString() is failing. It returns an empty first line for the received headers (resulting in the "no HTTP/" exception). The FBuffer does contain the correct headers with the request for the .css.

Exact tracing resulted in the line
Code: Pascal  [Select][+][-]
  1. if Length(FBuffer)=0 then
  2.   FillBuffer;
If the highlighted line is executed, the Result in the debugger becomes inaccessible. The later Result:=Result+xx then results in an empty string.

Are we dealing with another case of de-referenced (result)string here?
Title: Re: TFPHTTPServer in a thread
Post by: lucamar on July 28, 2019, 03:06:23 am
I can't replicate. Both my old test and your program (after correcting the main program to "use" cthreads) work as they should and serve all files.

This is your program output (in the memo):
01taller/01taller.htm
01taller/01tallerProble_resources/css/ardoraTest.css
01taller/01tallerProble_resources/js/jquery.js
01taller/01tallerProble_resources/js/jquery-ui.min.js
01taller/01tallerProble_resources/js/jquery.ui.touch-punch.min.js
01taller/01tallerProble_resources/js/ardoraTestCFG.js
01taller/01tallerProble_resources/js/ardoraScorm.js
01taller/01tallerProble_resources/js/ardoraTest.js
01taller/01tallerProble_resources/js/ardoraTab.js

This on an Ubuntu 12.04 box with Laz/FPC 2.0.2/3.0.4, if it matters. Oh! I tested only with one browser: Midori (WebKit-based).

ETA: Tested using wget (which is much more picky) to "mirror" the page and it also "downloads" the page, style-sheet and scripts without problems. Curious, isn't it?
Title: Re: TFPHTTPServer in a thread
Post by: rvk on July 28, 2019, 08:58:23 am
I can replicate the problem on Wondows 10 with (a few weeks old) Lazarus/FPC trunk.

I'll try stable/release and latest trunk today.

But I've seen a similar problem a few weeks ago with a dereferenced string.
I'll also try to chance it to shortstring {$H-} and propper buffer to see if it resolves it.
(Shortstrings are not reference counted)

Title: Re: TFPHTTPServer in a thread
Post by: euMesmo on July 30, 2019, 01:40:26 pm
I have tested W7, W10 and UbuntuMate18 with Lazarus 2.0.0, firefox and chrome and the same thing happens in all of them.

I understand this is some kind of fpweb bug.
Title: Re: TFPHTTPServer in a thread
Post by: julkas on July 30, 2019, 03:00:39 pm
@euMesmo Check also this - https://www.freepascal.org/~michael/articles/webserver1/webserver1.pdf
Title: Re: TFPHTTPServer in a thread
Post by: julkas on July 30, 2019, 05:09:58 pm
I have tested Lazarus HTTP Web server example. It's not working for me  >:D
Title: Re: TFPHTTPServer in a thread
Post by: Thaddy on July 30, 2019, 05:31:50 pm
remove wmecho from the uses clause.
Title: Re: TFPHTTPServer in a thread
Post by: julkas on July 30, 2019, 06:11:58 pm
remove wmecho from the uses clause.
@Thaddy Can you explain, why removing wmecho from uses clause resolves problem?
Who have successfully tested this Lazarus example?
Title: Re: TFPHTTPServer in a thread
Post by: Thaddy on July 30, 2019, 07:20:10 pm
Because wmecho is not needed and makes it fail to compile because it can not be found.
After that, try to start the server and ask for a page (must exist) like index.html.
Works.
Title: Re: TFPHTTPServer in a thread
Post by: rvk on July 30, 2019, 07:23:40 pm
Works.
Did you try the example of TS?
Did you try a bigger website with .css-files?

It definitely fails in TFPHTTPConnection.ReadString() like a mentioned for the .css request.
Title: Re: TFPHTTPServer in a thread
Post by: Thaddy on July 30, 2019, 07:38:44 pm
No. I got a compile error in trunk, removed the unit and tested basic functionality. The simpleserver works and serves what you ask. I did not test anything else.
Title: Re: TFPHTTPServer in a thread
Post by: julkas on July 30, 2019, 08:23:31 pm
Because wmecho is not needed and makes it fail to compile because it can not be found.
After that, try to start the server and ask for a page (must exist) like index.html.
Works.
I don't know if wmecho is needed. I have found this unit. After successfully compilation and run open chrom and make request, app fails with exception.
Continue tomorrow. I think code is broken or has bug.
This example must working out of the box.
Title: Re: TFPHTTPServer in a thread
Post by: rvk on July 30, 2019, 09:19:05 pm
No. I got a compile error in trunk, removed the unit and tested basic functionality. The simpleserver works and serves what you ask. I did not test anything else.
Yes, neat. It works with one index.htm  :(

But when serving a complete website (with css), even the simpleserver example craps out.

Try it with the website provided (and attached), which contains .css files.

For me, there is really something fishy going on in function TFPHTTPConnection.ReadString() and shows a real potential problem in core FPC. Like we had a few weeks ago with the wrong reference counting in the pure calculator app (which was also confirmed a real problem).

Can anybody test simplehttpserver.lpi (in fpc\packages\fcl-web\examples\httpserver) with attached website and confirm the problem?
Title: Re: TFPHTTPServer in a thread
Post by: euMesmo on July 31, 2019, 01:16:47 am
Hi rvk.
Yes, I tested the simplehttpserver on W7 with firefox and chrome and it works after commenting the line "if FCount>=5 then Active:=false" as it prevented the complete loading of all files.

As anecdote, the avast antivirus considers simplehttpserver a "threat".

However there is something "strange", when closing the browser the exception "EHTTPServer" appears with the message: "Missing HTTP protocol version in request".  If we click on the continue button of the exception message the server is still working.
I have placed in the code the line "Arequest.ProtocolVersion:='HTTP/1.1';" but it doesn't seem to solve it.

I have tried a bigger web (several html+css+js), the only problem is that when, from the web, a new html file is requested, the exception reappears. Clicking on the continue button of the exception message continues to work and loads the html, even html inserted into iframes.
Title: Re: TFPHTTPServer in a thread
Post by: julkas on July 31, 2019, 08:11:53 am
Hi rvk.
Yes, I tested the simplehttpserver on W7 with firefox and chrome and it works after commenting the line "if FCount>=5 then Active:=false" as it prevented the complete loading of all files.

As anecdote, the avast antivirus considers simplehttpserver a "threat".

However there is something "strange", when closing the browser the exception "EHTTPServer" appears with the message: "Missing HTTP protocol version in request".  If we click on the continue button of the exception message the server is still working.
I have placed in the code the line "Arequest.ProtocolVersion:='HTTP/1.1';" but it doesn't seem to solve it.

I have tried a bigger web (several html+css+js), the only problem is that when, from the web, a new html file is requested, the exception reappears. Clicking on the continue button of the exception message continues to work and loads the html, even html inserted into iframes.
Install Apache or nginx ... and you have working solution.
I have same exception.
Title: Re: TFPHTTPServer in a thread
Post by: Leledumbo on August 02, 2019, 08:13:28 am
However there is something "strange", when closing the browser the exception "EHTTPServer" appears with the message: "Missing HTTP protocol version in request".  If we click on the continue button of the exception message the server is still working.
Intentional, the exception actually happens internally and handled gracefully without ever leaking out of the webserver unit code. But GDB will still catch it unless you whitelist it.
Title: Re: TFPHTTPServer in a thread
Post by: euMesmo on August 04, 2019, 01:24:41 am
Install Apache or nginx ... and you have working solution.
I have same exception.

Yeah, it's the solution I'm using for my application. But if I could insert an http server into my application, users would no longer have to "add" anything. If that server also supported php it would be perfect.
Title: Re: TFPHTTPServer in a thread
Post by: euMesmo on August 04, 2019, 01:27:31 am
Intentional, the exception actually happens internally and handled gracefully without ever leaking out of the webserver unit code. But GDB will still catch it unless you whitelist it.
Indeed, once compiled there is no problem, maybe a little slow but everything seems to work fine.
Title: Re: TFPHTTPServer in a thread
Post by: julkas on August 04, 2019, 12:27:10 pm
Install Apache or nginx ... and you have working solution.
I have same exception.

Yeah, it's the solution I'm using for my application. But if I could insert an http server into my application, users would no longer have to "add" anything. If that server also supported php it would be perfect.
Check - https://wiki.freepascal.org/Brook_for_Free_Pascal
Title: Re: TFPHTTPServer in a thread
Post by: euMesmo on August 06, 2019, 01:44:37 pm
Hi julkas. THanks for the feedback. I'm gonna try it.
Title: Re: TFPHTTPServer in a thread
Post by: julkas on August 06, 2019, 02:23:36 pm
Hi julkas. THanks for the feedback. I'm gonna try it.
there are two Brook projects -
https://github.com/risoflora/brookframework
https://github.com/risoflora/brookfreepascal
Title: Re: TFPHTTPServer in a thread
Post by: noszone on April 01, 2021, 10:48:49 am
Does anyone know how to set header - Access-Control-Allow-Origin "*" for this http server? I am trying to read the page from JavaScript, but receiving CORS policy:

Access to XMLHttpRequest at 'http://127.0.0.1:8001/' from origin 'https://192.168.0.34:8443' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
index.js:62 GET http://127.0.0.1:8001/ net::ERR_FAILED
Title: Re: TFPHTTPServer in a thread
Post by: noszone on April 01, 2021, 11:46:43 am
I found it. Please refer to below code in case if need:

AResponse.SetCustomHeader('Access-Control-Allow-Origin','*');
AResponse.SendHeaders;
TinyPortal © 2005-2018