routes.pp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. unit routes;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. sysutils, classes, httpdefs, httproute;
  6. Var
  7. BaseURL : String;
  8. Procedure RegisterRoutes;
  9. implementation
  10. uses webutil, fphttp;
  11. Type
  12. { TMyModule }
  13. TMyModule = Class(TCustomHTTPModule)
  14. procedure HandleRequest(ARequest: TRequest; AResponse: TResponse); override;
  15. end;
  16. { TMyIntf }
  17. TMyIntf = Class(TObject,IRouteInterface)
  18. public
  19. procedure HandleRequest(ARequest: TRequest; AResponse: TResponse);
  20. end;
  21. { TMyHandler }
  22. TMyHandler = Class(TRouteObject)
  23. public
  24. procedure HandleRequest(ARequest: TRequest; AResponse: TResponse);override;
  25. end;
  26. Var
  27. C1,C2 : TComponent;
  28. MyIntf : TMyIntf;
  29. Procedure DumpRoutes(L : TStrings; AURL : String);
  30. Function DefaultReps(S : String) : string;
  31. begin
  32. Result:=StringReplace(S,'*path','somepath',[]);
  33. Result:=StringReplace(Result,':param1','theparam1',[]);
  34. Result:=StringReplace(Result,':param2','theparam2',[]);
  35. Result:=StringReplace(Result,':param','theparam',[]);
  36. If (Result<>'') and (Result[1]='/') then
  37. Delete(Result,1,1);
  38. end;
  39. Var
  40. I : Integer;
  41. P : String;
  42. begin
  43. THTTPRouter.SanitizeRoute(AURL);
  44. L.Add('<A NAME="routes"/>');
  45. L.Add('<H1>Try these routes:</H1>');
  46. For I:=0 to HTTPRouter.RouteCount-1 do
  47. begin
  48. P:=DefaultReps(HTTPRouter[i].URLPattern);
  49. L.Add('<A HREF="'+BaseURL+'/'+P+'">'+P+'</a><br>');
  50. end;
  51. end;
  52. Procedure RequestToResponse(ATitle : String; ARequest : TRequest; AResponse : TResponse; RouteParams : Array of String);
  53. Var
  54. L : TStrings;
  55. S : String;
  56. begin
  57. L:=TStringList.Create;
  58. try
  59. L.Add('<HTML>');
  60. L.Add('<HEAD>');
  61. L.Add('<TITLE>'+ATitle+'</TITLE>');
  62. L.Add('</HEAD>');
  63. L.Add('<BODY>');
  64. L.Add('<H1>'+ATitle+'</H1>');
  65. L.Add('<A HREF="#routes">Jump to routes overview</A>');
  66. if (Length(RouteParams)>0) then
  67. begin
  68. L.Add('<H2>Routing parameters:</H2>');
  69. L.Add('<table>');
  70. L.Add('<tr><th>Param</th><th>Value</th></tr>');
  71. for S in RouteParams do
  72. L.Add('<tr><td>'+S+'</th><th>'+ARequest.RouteParams[S]+'</th></tr>');
  73. L.Add('</table>');
  74. end;
  75. DumpRequest(ARequest,L,False);
  76. DumpRoutes(L,ARequest.URL);
  77. L.Add('</BODY>');
  78. L.Add('</HTML>');
  79. AResponse.Content:=L.Text;
  80. AResponse.SendResponse;
  81. finally
  82. L.Free;
  83. end;
  84. end;
  85. Procedure RequestToResponse(ATitle : String; ARequest : TRequest; AResponse : TResponse);
  86. begin
  87. RequestToResponse(ATitle,ARequest,AResponse,[]);
  88. end;
  89. Procedure SimpleCallBack(ARequest : TRequest; AResponse : TResponse);
  90. begin
  91. RequestToResponse('Simple callback',ARequest,AResponse);
  92. end;
  93. Procedure DefaultCallBack(ARequest : TRequest; AResponse : TResponse);
  94. begin
  95. RequestToResponse('Default callback (*path)',ARequest,AResponse,['path']);
  96. end;
  97. Procedure ParamPathMiddle(ARequest : TRequest; AResponse : TResponse);
  98. begin
  99. RequestToResponse('Path in the middle (onepath/*path/new)',ARequest,AResponse,['path']);
  100. end;
  101. Procedure ParamPath(ARequest : TRequest; AResponse : TResponse);
  102. begin
  103. RequestToResponse('Parametrized path (onepath/:param)',ARequest,AResponse,['param']);
  104. end;
  105. Procedure ParamPaths2(ARequest : TRequest; AResponse : TResponse);
  106. begin
  107. RequestToResponse('Parametrized path (onepath/:param)',ARequest,AResponse,['param1','param2']);
  108. end;
  109. Procedure ComponentPath(AData : Pointer; ARequest : TRequest; AResponse : TResponse);
  110. begin
  111. RequestToResponse('Component path (component: '+TComponent(AData).Name+')',ARequest,AResponse);
  112. end;
  113. { TMyModule }
  114. procedure TMyModule.HandleRequest(ARequest: TRequest; AResponse: TResponse);
  115. begin
  116. RequestToResponse('Old-fashioned Module',ARequest,AResponse);
  117. end;
  118. { TMyHandler }
  119. procedure TMyHandler.HandleRequest(ARequest: TRequest; AResponse: TResponse);
  120. begin
  121. RequestToResponse('Route object',ARequest,AResponse);
  122. end;
  123. { TMyIntf }
  124. procedure TMyIntf.HandleRequest(ARequest: TRequest; AResponse: TResponse);
  125. begin
  126. RequestToResponse('Interface object',ARequest,AResponse);
  127. end;
  128. Procedure RegisterRoutes;
  129. begin
  130. if (C1=Nil) then
  131. begin
  132. C1:=TComponent.Create(Nil);
  133. C1.Name:='ComponentRoute1';
  134. C2:=TComponent.Create(Nil);
  135. C2.Name:='ComponentRoute2';
  136. MyIntf:=TMyIntf.Create;
  137. end;
  138. HTTPRouter.RegisterRoute('simple',rmall,@SimpleCallBack);
  139. HTTPRouter.RegisterRoute('onepath/:param',rmall,@ParamPath);
  140. HTTPRouter.RegisterRoute('twopaths/:param1/:param2',rmall,@ParamPaths2);
  141. HTTPRouter.RegisterRoute('onepath/*path/new',rmall,@ParamPathMiddle);
  142. RegisterHTTPModule('module',TMyModule,True);
  143. HTTPRouter.RegisterRoute('/component/1',C1,rmall,@ComponentPath);
  144. HTTPRouter.RegisterRoute('/component/2',C2,rmall,@ComponentPath);
  145. HTTPRouter.RegisterRoute('/interfaced',rmall,MyIntf);
  146. HTTPRouter.RegisterRoute('/routed/object',rmall,TMyHandler);
  147. // This will catch all other paths
  148. HTTPRouter.RegisterRoute('*path',rmall,@DefaultCallBack,True);
  149. end;
  150. begin
  151. FreeAndNil(C1);
  152. FreeAndNil(C2);
  153. end.