[SOLVED] duplicate route doesn't trigger exception lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Чебурашка · 2022-02-09 13:13 Hello, The following code does not show any exception here, but I would expect this to happen. Any ideas? me@debian:~/Documents/dev$ fpc -version [0.004] Free Pascal Compiler version 3.0.4+dfsg-22 [2019/01/24] for x86_64 [0.004] Copyright (c) 1993-2017 by Florian Klaempfl and others 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 project1;  uses   Classes, SysUtils   , HTTPDefs  , httproute; procedure PostCallback1(req: TRequest; res: TResponse);begin  // Actions on post eventend;procedure PostCallback2(req: TRequest; res: TResponse);begin  // Actions on post eventend; begin  try    HTTPRouter.RegisterRoute('/post' , TRouteMethod.rmPost, @PostCallback1, False);    HTTPRouter.RegisterRoute('/post' , TRouteMethod.rmPost, @PostCallback2, False);  except    on E: Exception do begin      Writeln(E.Message);    end;  end;end.  Thank you ---------------------------------------------------------------------- Thaddy · 2022-02-09 16:00 Empty procs are removed by default, so try -O- ---------------------------------------------------------------------- Чебурашка · 2022-02-09 16:08 Same. Anyway the problem is in RegisterRoute being called twice with same address/routemethod not in the fact that the callbacks are wiped because of optimization. Btw does really optimization wipe out a method that is referenced? 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 project2;  uses   Classes, SysUtils   , HTTPDefs  , httproute; procedure PostCallback1(req: TRequest; res: TResponse);begin  Writeln('hello');end;procedure PostCallback2(req: TRequest; res: TResponse);begin  Writeln('world');end; begin  try    HTTPRouter.RegisterRoute('/post' , TRouteMethod.rmPost, @PostCallback1, False);    HTTPRouter.RegisterRoute('/post' , TRouteMethod.rmPost, @PostCallback2, False);  except    on E: Exception do begin      Writeln(E.Message);    end;  end;end. ---------------------------------------------------------------------- irawan · 2022-02-10 02:45 PostCallback2 replaces PostCallback1. so there is no exception occured. ---------------------------------------------------------------------- Чебурашка · 2022-02-10 07:54 So HTTPRouter is intended to be callable twice with the same couple ('/path', rmPost)? Then what is the meaning of the inner method CheckDuplicates? For what I understand such a method should trigger a exception when '/path', rmPost already exists in the routes set. Apparently I am wrong can some one explain? 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 function THTTPRouter.CreateHTTPRoute(AClass : THTTPRouteClass; const APattern: String;AMethod: TRouteMethod; IsDefault: Boolean) : THTTPRoute; begin  CheckDuplicate(APattern,AMethod,isDefault);  Result:=AClass.Create(FRoutes);  With Result do    begin    URLPattern:=APattern;    Default:=IsDefault;    Method:=AMethod;    end;end; procedure THTTPRouter.CheckDuplicate(APattern: String; AMethod: TRouteMethod;  isDefault: Boolean);Var  I,DI : Integer;  R : THTTPRoute; begin  DI:=-1;  For I:=0 to FRoutes.Count-1 do    begin  R:=FRoutes[I];    if R.Default then      DI:=I;    if R.Matches(APattern,AMethod) then      Raise EHTTPRoute.CreateFmt(EDupl icateRoute,[APattern,RouteMethodToString(AMethod)]);    end;  if isDefault and (DI<>-1) then    Raise EHTTPRoute.CreateFmt(EDuplicateDe faultRoute,[APattern,RouteMethodToString(AMethod)]);end; function THTTPRoute.Matches(const APattern: String; AMethod: TRouteMethod  ): Boolean;begin  Result:=(CompareText(URLPattern,APattern)=0)          and ((Method=rmAll) or (AMethod=Method))end; ---------------------------------------------------------------------- PascalDragon · 2022-02-10 08:09 Quote from: Thaddy on February 09, 2022, 05:00:17 pmEmpty procs are removed by default, so try -O- Not if they are used (either by calling them or referencing them), which is the case here. ---------------------------------------------------------------------- Чебурашка · 2022-02-10 08:12 Quote from: tt on February 09, 2022, 05:08:34 pmBtw does really optimization wipe out a method that is referenced? Thanks PascalDragon ---------------------------------------------------------------------- engkin · 2022-02-10 11:59 Quote from: tt on February 10, 2022, 08:54:06 amSo HTTPRouter is intended to be callable twice with the same couple ('/path', rmPost)? Then what is the meaning of the inner method CheckDuplicates? For what I understand such a method should trigger a exception when '/path', rmPost already exists in the routes set. Apparently I am wrong can some one explain? 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 function THTTPRouter.CreateHTTPRoute(AClass : THTTPRouteClass; const APattern: String;AMethod: TRouteMethod; IsDefault: Boolean) : THTTPRoute; begin  CheckDuplicate(APattern,AMethod,isDefault);  Result:=AClass.Create(FRoutes);  With Result do    begin    URLPattern:=APattern;    Default:=IsDefault;    Method:=AMethod;    end;end; procedure THTTPRouter.CheckDuplicate(APattern: String; AMethod: TRouteMethod;  isDefault: Boolean);Var  I,DI : Integer;  R : THTTPRoute; begin  DI:=-1;  For I:=0 to FRoutes.Count-1 do    begin  R:=FRoutes[I];    if R.Default then      DI:=I;    if R.Matches(APattern,AMethod) then      Raise EHTTPRoute.CreateFmt(EDupl icateRoute,[APattern,RouteMethodToString(AMethod)]);    end;  if isDefault and (DI<>-1) then    Raise EHTTPRoute.CreateFmt(EDuplicateDe faultRoute,[APattern,RouteMethodToString(AMethod)]);end; function THTTPRoute.Matches(const APattern: String; AMethod: TRouteMethod  ): Boolean;begin  Result:=(CompareText(URLPattern,APattern)=0)          and ((Method=rmAll) or (AMethod=Method))end;   You are not wrong. The class changes the first pattern from '/post' to 'post/' before saving it. Later when it checks for double, it compares the second pattern with the modified pattern. Of course they don't match. The change happens inside THTTPRoute.SetURLPattern: 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 THTTPRoute.SetURLPattern(AValue: String); Var  V : String; begin  V:=IncludeHTTPPathDelimiter(AValue);  if (V<>'') and (V<>'/') and (V[1]='/') then    Delete(V,1,1);  if FURLPattern=V then Exit;  FURLPattern:=V;end; To trigger the exception, change your code to: 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     HTTPRouter.RegisterRoute('post/' , TRouteMethod.rmPost, @PostCallback1, False);    HTTPRouter.RegisterRoute('post/' , TRouteMethod.rmPost, @PostCallback2, False); ---------------------------------------------------------------------- PascalDragon · 2022-02-10 12:34 Quote from: engkin on February 10, 2022, 12:59:07 pmYou are not wrong. The class changes the first pattern from '/post' to 'post/' before saving it. Later when it checks for double, it compares the second pattern with the modified pattern. Of course they don't match. That should be reported as a bug then. ---------------------------------------------------------------------- Чебурашка · 2022-02-10 12:40 Probably is a small bug then... in page https://wiki.freepascal.org/fphttpserver thers an example telling 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 [...]  HTTPRouter.registerRoute('/', @route1);  HTTPRouter.registerRoute('/2', @route2);[...]  so people thinks / should be normally placed at beginning of path as I did (just taking there code as satring point). ---------------------------------------------------------------------- Чебурашка · 2022-02-10 13:00 Quote from: PascalDragon on February 10, 2022, 01:34:46 pmThat should be reported as a bug then. Reported. ---------------------------------------------------------------------- Чебурашка · 2022-02-10 13:26 https://gitlab.com/freepascal.org/fpc/source/- /commit/7b62186b9c9efddcb0114df889d5830d8634b0bd by Michael Van Canneyt