[SOLVED] Want a simple way to build a http file server lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- senglit · 2020-04-26 11:13 hi all, I need a simple http server for downloading wav files in my project. It should work like this: WHEN: a browser send request like typing "http://127.0.0.1/sample.wav" ACTION: the server send sample.wav to browser This server do not need user to login, do not need a http based management syste.... do not need anything but sending a wav file. I guess it should be very simple. Maybe 30 lines coding with a proper component/class? But I just don't know how to do it. Anyone has a suggestion? ---------------------------------------------------------------------- PascalDragon · 2020-04-26 11:33 Look at $fpcdir/packages/fcl- web/examples/simpleserver/simpleserver.pas. It has a few more bells and whistles (proxy support, SSL, etc.), but if stripped of these it essentially shows how to use fpWebFile. ---------------------------------------------------------------------- Leledumbo · 2020-04-26 13:46 Quote from: PascalDragon on April 26, 2020, 01:33:39 pmLook at $fpcdir/packages/fcl-web/examples/simpleserver/simpleserver.pas. It has a few more bells and whistles (proxy support, SSL, etc.), but if stripped of these it essentially shows how to use fpWebFile. That one is too complex, stripping won't be a viable option for OP. Here's a straightforward one: 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 {$mode objfpc} uses  Classes,SysUtils,fphttpapp,httproute,httpdefs; const  BaseDir = '/home/yourusername'; // change this accordingly procedure SendWAVData(ARequest : TRequest; AResponse : TResponse);var  LFilePath: String;begin  LFilePath := BaseDir + ARequest.PathInfo; // note that ARequest.PathInfo starts with /, careful on systems not using / as directory separator  AResponse.FreeContentStream := true;  AResponse.ContentStream := TFileStream.Create(LFilePath, fmOpenRead);  AResponse.ContentType := 'audio/wav'; // easily made dynamic by using fpmimetypes but I'll pass that to youend; begin  HTTPRouter.RegisterRoute('*path',@SendWAVData);  Application.Port := 8888;  Application.Initialize;  Application.Run;end. Less than 30 lines including empty lines and const section. ---------------------------------------------------------------------- senglit · 2020-04-26 14:28 Quote from: PascalDragon on April 26, 2020, 01:33:39 pmLook at $fpcdir/packages/fcl-web/examples/simpleserver/simpleserver.pas. It has a few more bells and whistles (proxy support, SSL, etc.), but if stripped of these it essentially shows how to use fpWebFile. Thanks to PascalDragon. I studied the file you mentioned and it inspired me to have a look on \lazarus\fpc\3.0.4\source\packages\fcl- web\examples\httpserver. At last I built a demo based on TFPHTTPServer. now it works. but only with a small problem: the Error message "Project *** raised exception class 'EHTTPServer' with message: Missing HTTP protocol version in request" shows from time to time. I searhed in this forum and found a topic which discuss the same question: https://forum.lazarus.freepascal.org/index.php/topic,40511.m sg279908.html#msg279908 It sees his/her problem was not solved perfectly at last. Anyone knows how to solve it? ---------------------------------------------------------------------- senglit · 2020-04-26 14:30 Quote from: Leledumbo on April 26, 2020, 03:46:19 pmQuote from: PascalDragon on April 26, 2020, 01:33:39 pmLook at $fpcdir/packages/fcl-web/examples/simpleserver/simpleserver.pas. It has a few more bells and whistles (proxy support, SSL, etc.), but if stripped of these it essentially shows how to use fpWebFile. That one is too complex, stripping won't be a viable option for OP. Here's a straightforward one: 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 {$mode objfpc} uses  Classes,SysUtils,fphttpapp,httproute,httpdefs; const  BaseDir = '/home/yourusername'; // change this accordingly procedure SendWAVData(ARequest : TRequest; AResponse : TResponse);var  LFilePath: String;begin  LFilePath := BaseDir + ARequest.PathInfo; // note that ARequest.PathInfo starts with /, careful on systems not using / as directory separator  AResponse.FreeContentStream := true;  AResponse.ContentStream := TFileStream.Create(LFilePath, fmOpenRead);  AResponse.ContentType := 'audio/wav'; // easily made dynamic by using fpmimetypes but I'll pass that to youend; begin  HTTPRouter.RegisterRoute('*path',@SendWAVData);  Application.Port := 8888;  Application.Initialize;  Application.Run;end. Less than 30 lines including empty lines and const section. I tried you suggestion and it works perfectly! Now I'm trying to modify it into a thread. Any hint? ---------------------------------------------------------------------- mr-highball · 2020-04-26 14:42 If you want a pretty simple way to do threading you can use ezthreads. Has single threads or you can have a thread pool defined where you queue tasks to the pool, https://github.com/mr-highball/ezthreads Otherwise you could define your own tthread descendant and override the execute method to do the work. If you mean that you just want your http server to be multithreaded I'm pretty sure there is a property on the server like "useThreads" that you just need to toggle to true (not at a computer) ---------------------------------------------------------------------- Leledumbo · 2020-04-28 20:41 Quote from: senglit on April 26, 2020, 04:30:22 pmI tried you suggestion and it works perfectly! Now I'm trying to modify it into a thread. Any hint? Depends on what kind of "thread-ization" you want. The Application object, which is of type THTTPApplication, has built-in Threaded property, which when set to true will serve each incoming request in its own thread. It's still unclear what you actually want to achieve, though. If you want speed you can actually cache the file content in memory instead.