TFPHTTPServer in a thread lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- fjabouley · 2017-03-12 19:11 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/ind ex.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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1;  {$mode objfpc}{$H+}  interface  uses  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,  fphttpserver, fpHTTP, fpWeb;  type    { TForm1 }    TForm1 = class(TForm)    Button1: TButton;    Button2: TButton;    procedure Button1Click(Sender: TObject);    procedure Button2Click(Sender: TObject);    procedure FormDestroy(Sender: TObject);  private    { private declarations }  public    { public declarations }     procedure DoHandleRequest(Sender:TObject; var ARequest:TFPHTTPConnectionRequest; var AResponse:TFPHTTPConnectionResponse);    end;         { THTTPServerThread }     THTTPServerThread = class(TThread)   Private   Fserver : TFPHTTPServer;   Public     Constructor Create(APort:Word; const OnRequest:THTTPServerRequestHandler);     Procedure Execute; Override;     Procedure DoTerminate; Override;     Property Server : TFPHTTPServer Read FServer;   end;   var   Form1: TForm1;   FServerThread:TFPHTTPServer;  implementation  {$R *.lfm}    procedure TForm1.DoHandleRequest(Sender: TObject;  var ARequest: TFPHTTPConnectionRequest; var AResponse: TFPHTTPConnectionResponse);begin showmessage( ARequest.QueryString);end;  procedure TForm1.Button1Click(Sender: TObject);begin     FServerthread := THTTPServerThread.Create(8080,@DoHandleRequest);     FServerthread.Start;end;  procedure TForm1.Button2Click(Sender: TObject);begin  FServerThread.Terminate;end;  procedure TForm1.FormDestroy(Sender: TObject);begin    if Assigned(Fserverthread) then  begin    Fserverthread.Terminate;    Fserverthread.WaitFor;    FreeAndNil(Fserverthread);  end;end;  constructor THTTPServerThread.Create(APort: Word;  const OnRequest: THTTPServerRequestHandler);begin  Inherited Create(True);  FServer := TFPHTTPServer.Create(Nil);     FServer.Threaded:=true;     FServer.Port := APort;     FServer.OnRequest := OnRequest;  end;  procedure THTTPServerThread.Execute;begin        try           FServer.Active:=true;           while not terminated do sleep(10);        finally           FreeAndNil(FServer);        end;end;  procedure THTTPServerThread.DoTerminate;begin  inherited DoTerminate;  FServer.Active:=false;end;    end.   I asked our god rvk and here is his answer : QuoteOk, 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  !!!! ---------------------------------------------------------------------- rvk · 2017-03-12 21:19 Additionally we tried this: 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 TForm1.Button2Click(Sender: TObject);begin  // FServerThread.Terminate;  FServerThread.FServer.Active := False;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; ? ---------------------------------------------------------------------- russdirks · 2017-04-06 22:20 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  procedure CServerThread.Execute;begin   m_owner.m_server.Active := true;     // this does not return until the server is deactivated   m_owner.LogMsg('server is inactive');end;  procedure CHttpServer.stopServer;begin    m_server.Active := false;end;  This produces an ESocketError : Could not accept a client connection on socket: 476, error 10038. This is on Windows 10. ---------------------------------------------------------------------- russdirks · 2017-04-06 23:23 Just tried my code on OSX and I was able to stop the server fine, so maybe it is a Windows thing. ---------------------------------------------------------------------- tudi_x · 2017-07-17 15:54 what are the options for Windows in this case? Synapse? thank you ---------------------------------------------------------------------- Cyrax · 2017-07-17 20:24 Quote from: tudi_x on July 17, 2017, 05:54:54 pmwhat are the options for Windows in this case? Synapse? thank you AFAIK, same? ---------------------------------------------------------------------- Blestan · 2017-07-17 20:50 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 ---------------------------------------------------------------------- rvk · 2017-07-18 08:36 Quote from: tudi_x on July 17, 2017, 05:54:54 pmwhat 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? ---------------------------------------------------------------------- tudi_x · 2017-07-18 10:53 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 ---------------------------------------------------------------------- rvk · 2017-07-18 11:09 Quote from: tudi_x on July 18, 2017, 12:53:17 pmPlease 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit http_listen; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, fphttpapp, fphttpserver; type  THTTPServerThread = class(TThread)  private    _Error: string;  public    Server: TFPHTTPServer;    constructor Create(APort: word; const OnRequest: THTTPServerRequestHandler);    destructor Destroy; override;    procedure Execute; override;    property Error: string read _Error;  end; implementation constructor THTTPServerThread.Create(APort: word; const OnRequest: THTTPServerRequestHandler);begin  Server := TFPHTTPServer.Create(nil);  Server.Port := APort;  Server.OnRequest := OnRequest;  _Error := 'nil';  Self.FreeOnTerminate := true;  inherited Create(False);end; destructor THTTPServerThread.Destroy;begin  Server.Free;end; procedure THTTPServerThread.Execute;begin  try    Server.Active := True;  except    on E: Exception do    begin      _Error := E.Message;    end;  end;end; end.And main.pas looks like this: 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 unit main; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,  StdCtrls, http_listen, fphttpserver; type  TForm1 = class(TForm)    stop: TButton;    start: TButton;    Memo1: TMemo;    procedure FormCreate(Sender: TObject);  procedure startClick(Sender: TObject);    procedure stopClick(Sender: TObject);    procedure onRequest(Sender: TObject; var ARequest: TFPHTTPConnectionRequest;      var AResponse: TFPHTTPConnectionResponse);  end; var  Form1: TForm1;  _t: THTTPServerThread; implementation {$R *.lfm}procedure TForm1.startClick(Sender: TObject);begin  start.Enabled := False;  _t := THTTPServerThread.Create(8001, @onRequest);  stop.Enabled := True;end; procedure TForm1.FormCreate(Sender: TObject);begin  stop.Enabled := False;end; procedure TForm1.stopClick(Sender: TObject);begin  stop.Enabled := False;  // _t.Terminate;  _t.Server.Active := False; // <-- _t is automatically freed  start.Enabled := True;end; procedure TForm1.onRequest(Sender: TObject; var ARequest: TFPHTTPConnectionRequest;  var AResponse: TFPHTTPConnectionResponse);begin  Memo1.Append('HTTP request');end;  end.This worked fine for me (Lazarus 18RC2 FPC 3.1.1). ---------------------------------------------------------------------- tudi_x · 2017-07-18 11:23 worked beautifully. i will try to make a wiki page with the LinkedIn Outh2 integration code you helped me. thank you very much rvk ---------------------------------------------------------------------- euMesmo · 2019-07-17 15:54 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. ---------------------------------------------------------------------- lucamar · 2019-07-17 22:28 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. ---------------------------------------------------------------------- euMesmo · 2019-07-17 22:48 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. ---------------------------------------------------------------------- rvk · 2019-07-18 08:03 Quote from: euMesmo on July 18, 2019, 12:48:02 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 ---------------------------------------------------------------------- euMesmo · 2019-07-18 10:43 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. ---------------------------------------------------------------------- rvk · 2019-07-18 10:58 Quote from: euMesmo on July 18, 2019, 12:43:24 pmI 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). ---------------------------------------------------------------------- lucamar · 2019-07-18 13:48 You can use rvk's code 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.OnRequest(Sender: TObject;  var ARequest: TFPHTTPConnectionRequest;  var AResponse: TFPHTTPConnectionResponse);var  AFilename: String;begin  AFilename := ARequest.URI;  {Get rid of the starting bars so we won't serve from '/'   Theres should be only one, but just in case ...}  while AFilename.StartsWith('/') or AFilename.StartsWith('.') do    Delete(AFilename, 1, 1);  {Alternatively, one could just do:    AFilename := GeCurrentDir + AFilename;  or whatever the web-root directory is,  but that's not very secure}   { If we find the file, serve it; if not, fawn about it}  if FileExists(AFilename) then begin    AResponse.Code := 200;    AResponse.Content := ReadFileToString(AFilename);  end else begin    AResponse.Code := 404;    AResponse.Content := 'Sorry, don''t have any "' + AFilename +'"';  end;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. ---------------------------------------------------------------------- euMesmo · 2019-07-18 19:42 Many thanks to rvk and lucamar, your comments have been very helpful. ---------------------------------------------------------------------- euMesmo · 2019-07-27 13:51 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. ---------------------------------------------------------------------- rvk · 2019-07-27 23:00 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if Length(FBuffer)=0 then  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? ---------------------------------------------------------------------- lucamar · 2019-07-28 01:06 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? ---------------------------------------------------------------------- rvk · 2019-07-28 06:58 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) ---------------------------------------------------------------------- euMesmo · 2019-07-30 11:40 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. ---------------------------------------------------------------------- julkas · 2019-07-30 13:00 @euMesmo Check also this - https://www.freepascal.org/~michael/articles/webserver1/webserver1.pdf ---------------------------------------------------------------------- julkas · 2019-07-30 15:09 I have tested Lazarus HTTP Web server example. It's not working for me ---------------------------------------------------------------------- Thaddy · 2019-07-30 15:31 remove wmecho from the uses clause. ---------------------------------------------------------------------- julkas · 2019-07-30 16:11 Quote from: Thaddy on July 30, 2019, 05:31:50 pmremove wmecho from the uses clause. @Thaddy Can you explain, why removing wmecho from uses clause resolves problem? Who have successfully tested this Lazarus example? ---------------------------------------------------------------------- Thaddy · 2019-07-30 17:20 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. ---------------------------------------------------------------------- rvk · 2019-07-30 17:23 Quote from: Thaddy on July 30, 2019, 07:20:10 pmWorks. 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. ---------------------------------------------------------------------- Thaddy · 2019-07-30 17:38 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. ---------------------------------------------------------------------- julkas · 2019-07-30 18:23 Quote from: Thaddy on July 30, 2019, 07:20:10 pmBecause 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. ---------------------------------------------------------------------- rvk · 2019-07-30 19:19 Quote from: Thaddy on July 30, 2019, 07:38:44 pmNo. 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? ---------------------------------------------------------------------- euMesmo · 2019-07-30 23:16 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. ---------------------------------------------------------------------- julkas · 2019-07-31 06:11 Quote from: euMesmo on July 31, 2019, 01:16:47 amHi 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. ---------------------------------------------------------------------- Leledumbo · 2019-08-02 06:13 Quote from: euMesmo on July 31, 2019, 01:16:47 amHowever 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. ---------------------------------------------------------------------- euMesmo · 2019-08-03 23:24 Quote from: julkas on July 31, 2019, 08:11:53 amInstall 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. ---------------------------------------------------------------------- euMesmo · 2019-08-03 23:27 Quote from: Leledumbo on August 02, 2019, 08:13:28 amIntentional, 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. ---------------------------------------------------------------------- julkas · 2019-08-04 10:27 Quote from: euMesmo on August 04, 2019, 01:24:41 amQuote from: julkas on July 31, 2019, 08:11:53 amInstall 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 ---------------------------------------------------------------------- euMesmo · 2019-08-06 11:44 Hi julkas. THanks for the feedback. I'm gonna try it. ---------------------------------------------------------------------- julkas · 2019-08-06 12:23 Quote from: euMesmo on August 06, 2019, 01:44:37 pmHi 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 ---------------------------------------------------------------------- noszone · 2021-04-01 08:48 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 ---------------------------------------------------------------------- noszone · 2021-04-01 09:46 I found it. Please refer to below code in case if need: AResponse.SetCustomHeader('Access-Control-Allow-Origin','*'); AResponse.SendHeaders;