Node like HTTPServer lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Grahame Grieve · 2025-06-28 21:13 I've been doing a lot of work with Claude writing code in java and javascript, and so I decided to test Claude out for free pascal, and it's done a pretty good job. What I asked it to do was write a Node.js like framework for an HTTP server that would run in either unix or windows The outcome is here: https://github.com/HealthIntersections/fhirserver /tree/master/library/http I'm wondering whether this is something that other people would find useful, and I should spin it out into its own space? btw... why no HTTPS? I would never run my own server native on the web now - I always run it behind nginx, and let nginx handle basic things like web security and SSL. ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2025-06-28 22:36 Hey Grahame, I've had a quick look at what you've done and I do like what I see!! I'm giving it an A+ for effort !!  Having said that... You've duplicated something that already exists in Free Pascal. The fp-web package, in it's latest incarnation, already provides a router based implementation. It's no shame to re-invent the wheel when you're trying to learn stuff!!! I'm always quite adamant on that!! But you did re-invent the wheel Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2025-06-28 23:58 Hey Grahame, I felt I needed to include an example of using the routed version of fp-web. Here's a quick 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 program fpwebserver; {$mode objfpc}{$H+} uses  {$IFDEF UNIX}  cmem,  cthreads,  BaseUnix,  {$ENDIF}  SysUtils,  fphttpapp,  HTTPDefs,  httproute; const  cPort = 9191; procedure DefaultRoute(ARequest: TRequest; AResponse: TResponse);begin  AResponse.Content:=    '' +    '' +    'FP Web Server' +    '' +    '' +    '' +    '

FP Web Server

' +    '

Default Route' +    '' +    ''  ;end; procedure AboutRoute(ARequest: TRequest; AResponse: TResponse);begin  AResponse.Content:=    '' +    '' +    'FP Web Server: About' +    '' +    '' +  '

' +    '

FP Web Server: About

' +    '

About Route' +    '' +    ''  ;end; procedure RegisterRoutes;begin  // Responds to any method  HTTPRouter.RegisterRoute('/', rmAll, @DefaultRoute, True);  // Responds only to the GET method  HTTPRouter.RegisterRoute('/about', rmGet, @AboutRoute);end; {$IFDEF UNIX}procedure CleanUp(ASignal: LongInt); cdecl;begin  WriteLn;  WriteLn('Cleaning');  Application.Terminate;  Halt(0);end;{$ENDIF UNIX} begin  RegisterRoutes;   {$IFDEF UNIX}  if FpSignal(SIGINT, @CleanUp) = signalhandler(SIG_ERR) then begin    WriteLn({$I %FILE%}, {$I %LINE%}, Format('Failed to install signal error: %d', [ fpGetErrno ]));    Halt(1);  end;  if FpSignal(SIGKILL, @CleanUp) = signalhandler(SIG_ERR) then begin    WriteLn({$I %FILE%}, {$I %LINE%}, Format('Failed to install signal error: %d', [ fpGetErrno ]));    Halt(1);  end;  {$ENDIF UNIX}   Application.Title:= 'fp-web- httpserver';  Application.Port:= cPort;  Application.Threaded:= True;  Application.Initialize;  WriteLn(Format('Serving on http://localhost:%d', [cPort]));  Application.Run;end.  Hope that helps compare your effort and what comes with Free Pascal. Cheers, Gus ---------------------------------------------------------------------- Grahame Grieve · 2025-06-29 05:35 > But you did re-invent the wheel interesting - thanks. I did not know about FPWeb - or at least, I looked long ago and thought it wasn't what it is now, at least ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2025-06-29 06:36 Hey Grahame, Quote from: Grahame Grieve on June 29, 2025, 07:35:23 aminteresting - thanks. You're more than welcome !! Quote from: Grahame Grieve on June 29, 2025, 07:35:23 amI did not know about FPWeb - or at least, I looked long ago and thought it wasn't what it is now, at least And you are correct. In the past we had to deal with WEB Modules and all that Jazz. You can still do that, cuz backwards compatibility is a must. But you can also do it routed, like on the code I provided!! I'm guessing you haven't looked at it for quite a while Cheers, Gus ---------------------------------------------------------------------- Grahame Grieve · 2025-06-29 12:18 The event signature is Procedure (ARequest: TRequest; AResponse: TResponse) of object how do I get the client IP? Also, it looks like the request object parses the body and the URL - what happens if it's a POST and there are parameters in the both the URL and the body? ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2025-06-30 07:53 Hey Grahame, Quote from: Grahame Grieve on June 29, 2025, 02:18:48 pmThe event signature is Procedure (ARequest: TRequest; AResponse: TResponse) of object how do I get the client IP? I've never explored that, but I'm guessing that the ARequest variable will have something in there that will help. Looking at the 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   { THTTPHeader }   THTTPHeader = class(TObject)  {...}  public  {...}    Property RemoteAddress : String Index Ord(hvRemoteAddress) read GetHTTPVariable Write SetHTTPVariable;    Property RemoteAddr : String Index Ord(hvRemoteAddress) read GetHTTPVariable Write SetHTTPVariable; // Alias, Delphi-compat    Property RemoteHost : String Index Ord(hvRemoteHost) read  GetHTTPVariable Write SetHTTPVariable;  {...}  end;  { TRequest }   TRequest = class(THttpHeader)  {...}  end; I would investigate the above properties. Quote from: Grahame Grieve on June 29, 2025, 02:18:48 pmAlso, it looks like the request object parses the body and the URL - what happens if it's a POST and there are parameters in the both the URL and the body? There's a good wiki post about fp-web: https://wiki.lazarus.freepascal.org/fpWeb_Tutorial If you navigate to this section you'll find that those are in ARequest.QueryFields and .ARequest.ContentFields These are all good questions. And the programmers that implement it this way were probably rather thorough. One just has to dig into the code to try and get some answers when the wiki is short. Cheers, Gus