#1 2023-10-27 11:01:36

squirrel
Member
Registered: 2015-08-13
Posts: 143

Difference in URL parsing between mORMot1 and 2

I notice a difference between how urls are parsed between mORMot 1 and 2 and was wondering if there is a setting to get the original behaviour back.  Sample code:

  TMyRestServer = class(TSQLRestServerFullMemory)
  published
    procedure Method1(Ctxt: TSQLRestServerURIContext);
  end;
...
procedure TMyRestServer.Method1(Ctxt: TSQLRestServerURIContext);
begin
  Ctxt.Returns('{"value":"hello"}');
end;

When using mORMot1, accessing all these urls will give the same response:
https://127.0.0.1:8084/test/Method1
https://127.0.0.1:8084/test/Method1/
https://127.0.0.1:8084/test/Method1/someval

{"value":"hello"}

But with mORMot2, all of the above works except for https://127.0.0.1:8084/test/Method1/ which returns:
{"errorCode":400,"errorText":"Invalid URI"}

Is this the expected behaviour?

Offline

#2 2023-10-27 12:16:46

tbo
Member
Registered: 2015-04-20
Posts: 311

Re: Difference in URL parsing between mORMot1 and 2

squirrel wrote:

Is this the expected behaviour?

I can't reproduce your observation with this example. Please compare what you do differently.

PS: Sorry, I missed the slash at the end. Yes, with slash 400 is returned.

With best regards
Thomas

Last edited by tbo (2023-10-27 12:25:45)

Offline

#3 2023-10-27 12:43:08

squirrel
Member
Registered: 2015-08-13
Posts: 143

Re: Difference in URL parsing between mORMot1 and 2

The example-03 does not compile, but I've created my own tiny example dpr here which shows the difference between mORMot 1 and 2 and can be used to highlight/test the issue:
https://paste.ee/p/tKeqf

Offline

#4 2023-10-27 13:29:40

tbo
Member
Registered: 2015-04-20
Posts: 311

Re: Difference in URL parsing between mORMot1 and 2

squirrel wrote:

The example-03 does not compile, ...

The example compiles for me without errors, warnings or hints. You do not specify which Delphi version you are using, nor which mORMot commit.

If the function name is expanded with a slash, the log shows following:

GET Files/GetAllFileNames/=400
mormot.rest.server.TRestServerRoutingRest {  "errorCode":400,  "errorText":"Invalid URI"  }

The following is written in help:

function TServiceCalculator.Add(n1, n2: integer): integer;
will accept such requests:
- URL='root/Calculator.Add' and InBody='[ 1,2 ]'
- URL='root/Calculator.Add?+%5B+1%2C2+%5D' // decoded as ' [ 1,2 ]'
- URL='root/Calculator.Add?n1=1&n2=2'      // in any order, even missing

If the help is correct, it is the expected result.

PS: If you put a breakpoint in function TRestServer.Uri() at position "node := fRouter.Lookup(ctxt);", you can trace it.

With best regards
Thomas

Last edited by tbo (2023-10-27 14:15:47)

Offline

#5 2023-10-27 13:36:16

squirrel
Member
Registered: 2015-08-13
Posts: 143

Re: Difference in URL parsing between mORMot1 and 2

I'm using Delphi 10.3.

example-03:
in u_SharedTypes, the following line causes [dcc32 Error] u_SharedTypes.pas(75): E2034 Too many actual parameters
      pmCheckedFileName^ := TPath.Combine(dirName, fileName, False)
Removing the ,false parameter will cause it to compile.

I hope there is a way to restore the mORMot1 uri parsing that allows the trailing /, since I am porting projects to mORMot 2 that depends on it being consistent.

Offline

#6 2023-10-27 14:23:38

tbo
Member
Registered: 2015-04-20
Posts: 311

Re: Difference in URL parsing between mORMot1 and 2

squirrel wrote:

example-03:
in u_SharedTypes, the following line causes [dcc32 Error] u_SharedTypes.pas(75): E2034 Too many actual parameters
      pmCheckedFileName^ := TPath.Combine(dirName, fileName, False)
Removing the ,false parameter will cause it to compile.

You are right, in Delphi 10.3 the definition still looks like this: "class function TPath.Combine(const Path1, Path2: string): string;".

With best regards
Thomas

Offline

#7 2023-11-06 09:30:52

squirrel
Member
Registered: 2015-08-13
Posts: 143

Re: Difference in URL parsing between mORMot1 and 2

If it is possible to get the OnBeforeURI to trigger for when the uri has a trailing / then I can do a redirect or handle it somehow.

Offline

#8 2023-11-07 11:11:00

squirrel
Member
Registered: 2015-08-13
Posts: 143

Re: Difference in URL parsing between mORMot1 and 2

Is there any way to get OnBeforeURI to trigger in this scenario in mORMot 2 like it does in 1?

Offline

#9 2023-11-08 01:05:51

htits2008
Member
Registered: 2015-03-25
Posts: 27

Re: Difference in URL parsing between mORMot1 and 2

en,I have same trouble。and it take me afew day try to read forum and change my code。

      //Server.RootRedirectToUri('/static/web/'); //old code ,
      Server.RootRedirectToUri('/static/web');
      server.Route.Get('/static/web','/static/web/index.html',urmGet);
      server.Route.get('/static/assets/*','/static/web/assets/*',urmGet); 

Offline

#10 2023-11-08 05:28:29

squirrel
Member
Registered: 2015-08-13
Posts: 143

Re: Difference in URL parsing between mORMot1 and 2

Unfortunately this doesn’t only affect my root function, but All my method functions. It is breaking bookmarked links at the clients and 3rd party integrators to the extent that upgrading to mormot 2 is now blocked.

Offline

#11 2023-11-08 06:27:56

squirrel
Member
Registered: 2015-08-13
Posts: 143

Re: Difference in URL parsing between mORMot1 and 2

Thanks to @htits2008 for pointing me in the right direction.  For anybody else affected by the same issue, here is a procedure to fix it.  Just remember to add all new methods where you call it, otherwise they will still be affected by it.  Maybe there is a way to get a list of all the method based functions (not the interface functions) and step through them at create time so that this procedure can be called without parameters?  Will check later when more time is available:

procedure FixURIRoutingMess(const HttpServer: TRestHttpServer; const methods: array of string);
var
  I, R: Integer;
  J: TUriRouterMethod;
  tmpURI: string;
begin
  for I := 0 to Length(methods) -1 do
    for R := 0 to HttpServer.RestServerCount -1 do
    begin
      tmpURI := '/' + HttpServer.RestServer[R].Model.Root + '/' + methods[I];
      for J := urmGet to urmHead do
        HttpServer.Route.Rewrite(J, tmpURI + '/', J, tmpURI);
    end;
end;

This can be called something like this (based on the pastee sample above):

  FixURIRoutingMess(aHttpsServer, ['method1']);

Last edited by squirrel (2023-11-08 07:32:19)

Offline

#12 2023-11-08 07:54:51

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,024
Website

Re: Difference in URL parsing between mORMot1 and 2

I will try to restore it back to what mORMot 1 does.

Offline

#13 2023-11-08 07:56:25

squirrel
Member
Registered: 2015-08-13
Posts: 143

Re: Difference in URL parsing between mORMot1 and 2

If it is possible, that will be wonderful!  Thanks @ab! big_smile

Last edited by squirrel (2023-11-08 08:00:06)

Offline

Board footer

Powered by FluxBB