Recent

Author Topic: Using TCustomHTTPApplication in GUI Application  (Read 1109 times)

d.ioannidis

  • Full Member
  • ***
  • Posts: 233
    • Nephelae
Using TCustomHTTPApplication in GUI Application
« on: September 11, 2023, 10:30:53 am »
Hi,

  I wanted to see if TCustomHTTPApplication can be used in GUI Application's and the following code is working .  As I'm not too familiar with the LCL, can someone review the code and see if there is a catch or bad practice ?

EDIT: Free Pascal 3.2.2 / Lazarus 2.2.6

TCustomHTTPApplication  in a Thread
Code: Pascal  [Select][+][-]
  1. unit uHTTPSrv;
  2.  
  3. {$mode ObjFPC}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, custhttpapp;
  9.  
  10. type
  11.  
  12.   { TWebServerThread }
  13.  
  14.   TWebServerThread = class(TThread)
  15.   private
  16.     FHTTPApp: TCustomHTTPApplication;
  17.   protected
  18.     procedure Execute; override;
  19.   public
  20.     constructor Create(APort: word);
  21.     destructor Destroy; override;
  22.     procedure TerminateHTTPApp;
  23.   end;
  24.  
  25. implementation
  26.  
  27. { TWebServerThread }
  28.  
  29. procedure TWebServerThread.Execute;
  30. begin
  31.   FHTTPApp.Run;
  32.   while not (Terminated and FHTTPApp.Terminated) do Sleep(1);
  33. end;
  34.  
  35. constructor TWebServerThread.Create(APort: word);
  36. begin
  37.   FHTTPApp := TCustomHTTPApplication.Create(nil);
  38.   FHTTPApp.Port := (APort);
  39.   FHTTPApp.Threaded := True;
  40.   FHTTPApp.Initialize;
  41.   inherited Create(False);
  42. end;
  43.  
  44. destructor TWebServerThread.Destroy;
  45. begin
  46.   FreeAndNil(FHTTPApp);
  47.   inherited Destroy;
  48. end;
  49.  
  50. procedure TWebServerThread.TerminateHTTPApp;
  51. begin
  52.   if Assigned(FHTTPApp) then
  53.     FHTTPApp.Terminate;
  54. end;
  55.  
  56. end.



Managing TCustomHTTPApplication  from main form thread.
Code: Pascal  [Select][+][-]
  1. uses
  2.    ........, uHTTPSrv,  HTTPDefs, httproute;    
  3.  
  4. { TfrmAppMain }
  5.  
  6.   TfrmAppMain = class(TForm)
  7.     .........
  8.     procedure FormCreate(Sender: TObject);
  9.     .........
  10.   private
  11.     FWebServer: TWebServerThread;
  12.     procedure StartHTTPApiServer;
  13.     procedure StopHTTPApiServer;
  14.   public
  15.  
  16. procedure TfrmAppMain.FormCreate(Sender: TObject);
  17. begin
  18.  
  19.   HTTPRouter.RegisterRoute('/', TDefaultRoute, True);
  20.   HTTPRouter.RegisterRoute('/echo/:echo', TEchoRoute);
  21.  
  22. end;
  23.  
  24. procedure TfrmAppMain.StartHTTPApiServer;
  25. begin
  26.   if not Assigned(FWebServer) then
  27.     FWebServer := TWebServerThread.Create(22100);
  28. end;
  29.  
  30. procedure TfrmAppMain.StopHTTPApiServer;
  31. begin
  32.   if Assigned(FWebServer) then
  33.   begin
  34.     FWebServer.TerminateHTTPApp;
  35.     FWebServer.Terminate;
  36.     FWebServer.WaitFor();
  37.     FreeAndNil(FWebServer);
  38.   end;
  39. end;
  40.  
  41.  



The routes
Code: Pascal  [Select][+][-]
  1.   { TDefaultRoute }
  2.  
  3.   TDefaultRoute = class(TRouteObject)
  4.     procedure HandleRequest(ARequest: TRequest; AResponse: TResponse); override;
  5.   end;
  6.  
  7.   { TEchoRoute }
  8.  
  9.   TEchoRoute = class(TRouteObject)
  10.     procedure HandleRequest(ARequest: TRequest; AResponse: TResponse); override;
  11.   end;
  12.  
  13. { TDefaultRoute }
  14.  
  15. procedure TDefaultRoute.HandleRequest(ARequest: TRequest; AResponse: TResponse);
  16. begin
  17.   if ARequest.URI <> '/' then
  18.   begin
  19.     AResponse.Code := 404;
  20.     AResponse.CodeText := 'Not Found';
  21.   end
  22.   else
  23.   begin
  24.     AResponse.Content := ApplicationName;
  25.     AResponse.Code := 200;
  26.     AResponse.CodeText := 'OK';
  27.     AResponse.ContentLength := Length(AResponse.Content);
  28.   end;
  29. end;
  30.  
  31. { TEchoRoute }
  32.  
  33. procedure TEchoRoute.HandleRequest(ARequest: TRequest; AResponse: TResponse);
  34. begin
  35.   AResponse.Content := ARequest.RouteParams['echo'];
  36.   AResponse.Code := 200;
  37.   AResponse.CodeText := 'OK';
  38.   AResponse.ContentLength := Length(AResponse.Content);
  39. end;
  40.  

regards,
« Last Edit: September 11, 2023, 10:42:27 am by d.ioannidis »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8836
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Using TCustomHTTPApplication in GUI Application
« Reply #1 on: September 12, 2023, 11:04:37 am »
As I'm not too familiar with the LCL, can someone review the code and see if there is a catch or bad practice ?
Don't use the CustomXXX classes directly, they're meant to be extended. That's what THTTPApplication is for if you want something out of the box.
Apart from that, you're creating the thread UNsuspended, meaning it will directly call Execute after creation. Just be aware and ensure route registration is executed before calling FHTTPApp.Run as I don't think you can register routes on the fly, they might be cached.

 

TinyPortal © 2005-2018