#1 2024-01-02 11:46:57

RaelB
Member
Registered: 2010-08-04
Posts: 46

Error after making a change to martin-doyle\04-InterfacedBasedServices

Hi,

I have run the martin-doyle\04-InterfacedBasedServices demo, and it works without problem.

Then I change the RestServer to require authentication, so I add the "True" parameter.

  SampleServer := TSampleServer.Create(Model, 
  ChangeFileExt(Executable.ProgramFileName, '.db'), True);

Now when I run the client, I get the error:

TServiceFactoryClient.Create(): IExample interface or TRestClientRoutingRest routing not supported by server [{
"errorCode":400,
"errorText":"Invalid URI"
}]

It does not make a difference if I login or not (i.e. HttpClient.SetUser...)

Can anyone reproduce?

How to go about debugging/resolving?

I'm using Delphi 10.4. Problem occurs with Mormot 2.1, but I also tried latest source with same result.

Thanks

Last edited by RaelB (2024-01-02 11:47:23)

Offline

#2 2024-01-02 13:15:26

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

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

Are you sure your user/password credentials are correct?

Did you debug on the server side, in the Uri() method, to see what is happening?

Offline

#3 2024-01-02 13:31:45

RaelB
Member
Registered: 2010-08-04
Posts: 46

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

My code in client:

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Model := CreateSampleModel;
  HttpClient := TRestHttpClient.Create('localhost', HttpPort, Model);
  try
    HttpClient.SetUser('User', 'synopse');
    HttpClient.ServiceDefine([IExample], sicShared);
    HttpClient.Services['Example'].Get(ExampleService);
  except
    On E: Exception do
      MainTrace.Send(E.classname, E.Message)
  end;
end;

Log file - shows that the auth works ok

20240102 13273442  #  +    server.TSampleServer(02604460).URI GET root/auth?username=User in=0 B
20240102 13273442  # srvr  	  Method GET root/auth=200 out=77 B in 1.78ms
20240102 13273442  # ret   	mormot.rest.server.TRestServerRoutingRest(02de67c0) {"result":"ae7dd4354359d5ececc51861bfc1a9d6f1c6b877ad68dc4960941dba8bd0dcc7"}
20240102 13273442  #  -    00.004.082
20240102 13273442  $  +    server.TSampleServer(02604460).URI GET root/auth?username=User&password=85f078ed616bfdf0174407281f45772e91031b1fe3ba4ece40bd88894a5cd2e7&clientnonce=4a651701_463d3e15c1e23861227694e85890d00f in=0 B
20240102 13273443  $ DB    	server.TSampleServer(02604460) prepared 99us Project04InterfaceBasedServer.db SELECT ID,LogonName,DisplayName,PasswordHashHexa,GroupRights FROM AuthUser WHERE LogonName=? LIMIT 1  [{id:4,detail:"SEARCH AuthUser USING INDEX sqlite_autoindex_AuthUser_1 (LogonName=?)"}] 
20240102 13273443  $ SQL   	server.TSampleServer(02604460) 1.60ms returned 1 row as 153 B SELECT ID,LogonName,DisplayName,PasswordHashHexa,GroupRights FROM AuthUser WHERE LogonName=:('User'): LIMIT 1
20240102 13273443  $ res   	mormot.db.raw.sqlite3.TSqlDatabase(0271a820) [{"ID":3,"LogonName":"User","DisplayName":"User","PasswordHashHexa":"67aeea294e1cb515236fd7829c55ec820ef888e8e221814d24d83b3dc4d825dd","GroupRights":3}] 
20240102 13273443  $ DB    	server.TSampleServer(02604460) prepared 147us Project04InterfaceBasedServer.db SELECT ID,Ident,SessionTimeout,AccessRights FROM AuthGroup WHERE RowID=?  [{id:2,detail:"SEARCH AuthGroup USING INTEGER PRIMARY KEY (rowid=?)"}] 
20240102 13273443  $ SQL   	server.TSampleServer(02604460) 1.78ms id=3 SELECT ID,Ident,SessionTimeout,AccessRights FROM AuthGroup WHERE RowID=?
20240102 13273444  $ DB    	server.TSampleServer(02604460) prepared 71us Project04InterfaceBasedServer.db SELECT Data FROM AuthUser WHERE RowID=?  [{id:2,detail:"SEARCH AuthUser USING INTEGER PRIMARY KEY (rowid=?)"}] 
20240102 13273444  $ SQL   	server.TSampleServer(02604460) 1.70ms id=3 len=0 B SELECT Data FROM AuthUser WHERE RowID=?
20240102 13273444  $ auth  	mormot.rest.server.TAuthSession(026541d0) New [User] session User/805670 created at /-288230374541098224 running Mozilla/5.0 (Win x86; mORMot) HCS/2.1.5794 Project04InterfaceBasedClient/0 {Windows 10 64bit 19045}
20240102 13273444  $ srvr  	 null Method GET root/auth=200 out=219 B in 22.12ms
20240102 13273444  $ ret   	mormot.rest.server.TRestServerRoutingRest(02de67c0) {"result":"805670+FC246362BC82654BC58AAE31301B27B4B41187C63123A9BC790B3FB1351286CA","logonid":3,"logonname":"User","logondisplay":"User","logongroup":3,"timeout":60,"server":"Project04InterfaceBasedServer","version":""}
20240102 13273444  $  -    00.025.008
20240102 13273444  %  +    server.TSampleServer(02604460).URI POST root/Example._contract_?session_signature=000c4b26006669c0f9a89362 in=2 B
20240102 13273445  % debug 	server.TSampleServer(02604460) TRestServerRoutingRest.Error: {  "errorCode":400,  "errorText":"Invalid URI"  }
20240102 13273445  % srvr  	  ? POST root/Example._contract_?session_signature=000c4b26006669c0f9a89362=400 out=49 B in 7.85ms
20240102 13273445  % ret   	mormot.rest.server.TRestServerRoutingRest(02de67c0) {  "errorCode":400,  "errorText":"Invalid URI"  }
20240102 13273445  %  -    00.012.346
20240102 13280023  "  +    server.TSampleServer(02604460).URI GET root/auth?userName=User&session=805670&session_signature=000c4b2600666a24c4f0fa26 in=0 B
20240102 13280024  " auth  	server.TSampleServer(02604460) Deleted session User:805670/1 from /-288230374541098224 soaGC=0
20240102 13280024  " srvr  	User  Method GET root/auth=200 out=0 B in 21.90ms
20240102 13280025  "  -    00.037.361
20240102 13284529  !  +    mormot.rest.http.server.TRestHttpServer(026141f0).Destroy
20240102 13284529  ! http  	mormot.rest.http.server.TRestHttpServer(026141f0) {"THttpApiServer(0260c610)":{ApiVersion:"HTTP API 2.0",ServerName:"mORMot2 (Win)",ProcessName:"root",Options:["hsoThreadSmooting"],Router:{"TUriRouter(026f7140)":{Gets:1}},Cloned:false,RegisteredUrl:"http://+:11111/root/",MaxBandwidth:4294967295,MaxConnections:4294967295}} finalized for 1 server
20240102 13284529  !  +    	mormot.rest.http.server.TRestHttpServer(026141f0).Shutdown(true)
20240102 13284529  !  -    	00.000.789

Offline

#4 2024-01-02 13:36:34

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

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

Try to define your services BEFORE calling SetUser().

This is the main idea: define your services, i.e. client URI routing, BEFORE using it.

Offline

#5 2024-01-02 13:50:34

RaelB
Member
Registered: 2010-08-04
Posts: 46

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

I get the same error, whether SetUser is first, in the middle or last..

Offline

#6 2024-01-02 14:51:57

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

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

ab wrote:

Try to define your services BEFORE calling SetUser().

Are you sure? Then all my comments in source code since mORMot1 are wrong:

  // IMPORTANT: First log in and then call ServiceDefine()!
  if not FServerRestClient.SetUser(pmcAdminUsername, pmcAdminPassword, {HashedPassword=} False) then
    Exit(scsErrLoginAdminUser); //=>

  if not InitializeServices then
    Exit(scsErrInitializeServices); //=>
end;

@RaelB: Have you already tried this example?

With best regards
Thomas

Offline

#7 2024-01-02 15:06:58

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

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

When you add the ', true' parameter to TSampleServer.Create() then you bypassed the overriden TSampleServer.Create constructor, which is responsible of calling  ServiceDefine().

So the ', true' parameter is to be added in TSampleServer.Create:

inherited Create(AModel, ADBFileName, true);

The problem came from a confusion/imprecision in the code sample: this constructor should be defined as "reintroduce" to avoid such issue:
https://github.com/synopse/mORMot2/commit/fb2d65dd

Offline

#8 2024-01-02 16:08:20

RaelB
Member
Registered: 2010-08-04
Posts: 46

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

@ab: Thanks for catching that. I didn't notice it.

@Thomas: My problem with your demo smile is that I get this error:

First chance exception at $75ADF932. Exception class EOSException with message 'TFileStreamEx.Create(C:\Delphi\Components_Full\Database\mORMot2\ex\ThirdPartyDemos\tbo\04-HttpServer-InterfaceServices\bin\TestRestServer_20240102_175743.log) failed as ERROR_PATH_NOT_FOUND'. Process TestRestServer.exe (5340)

It is occurring in mormot.core.os

constructor TFileStreamEx.CreateFromHandle(const aFileName: TFileName; aHandle: THandle);
begin
  if not ValidHandle(aHandle) then
    raise EOSException.CreateFmt('%s.Create(%s) failed as %s',
      [ClassNameShort(self)^, aFileName, GetErrorText(GetLastError)]);
  inherited Create(aHandle); // TFileStreamFromHandle constructor which own it 
  fFileName := aFileName;
end;

called from mormot.core.log TSynLog.CreateLogWriter.

I added this code to the server:

var
  MainServer: TTestServerMain;
  LogFamily: TSynLogFamily;
begin
{$IFDEF DEBUG}
  ReportMemoryLeaksOnShutdown := True;
{$ENDIF}

  LogFamily := SQLite3Log.Family;
  LogFamily.Level := LOG_VERBOSE;
  LogFamily.PerThreadLog := ptIdentifiedInOnFile;
  LogFamily.EchoToConsole := LOG_VERBOSE;
  LogFamily.NoFile := True;  

But error still occurs. My assumption is that it is working on a different SynLog instance. Still not sure of the cause of the actual error..

Last edited by RaelB (2024-01-02 16:08:43)

Offline

#9 2024-01-02 16:22:08

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

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

Perhaps the error comes from "NoFile := true".

Try to set it to 'false', or to move it.

Offline

#10 2024-01-02 17:09:11

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

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

RaelB wrote:

@Thomas: My problem with your demo smile is that I get this error:

First chance exception at $75ADF932. Exception class EOSException with message 'TFileStreamEx.Create(C:\Delphi\Components_Full\Database\mORMot2\ex\ThirdPartyDemos\tbo\04-HttpServer-InterfaceServices\bin\TestRestServer_20240102_175743.log) failed as ERROR_PATH_NOT_FOUND'. Process TestRestServer.exe (5340)

I have tested it with the following and it works for me without any problems:

  • Windows 10

  • Delphi 12 Athens

  • mORMot2 Version 2.2

Unfortunately, I can't help you.

With best regards
Thomas

Offline

#11 2024-01-02 18:45:09

RaelB
Member
Registered: 2010-08-04
Posts: 46

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

Ok... I found the cause of the problem:

procedure TRestServerLog.ComputeFileName;
begin
  inherited ComputeFileName;
  FFileName := StringReplace(FFileName, ' ', '_', [rfReplaceAll]);
end;

My path to the project is:
"C:\Delphi\Components Full\Database\mORMot2", so this code creates an invalid path, and I didn't notice this in the error message.
I imagine the code should actually just modify the log filename, not the full path.

Offline

#12 2024-01-02 18:57:52

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

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

RaelB wrote:

I imagine the code should actually just modify the log filename, not the full path.

You are right. It should look like this:

procedure TServerLog.ComputeFileName;
begin
  inherited ComputeFileName;
  FFileName := MakePath([ExtractFilePath(FFileName), StringReplace(ExtractFileName(FFileName), ' ', '_', [rfReplaceAll])]);
end;

With best regards
Thomas

Offline

#13 2024-01-03 11:00:14

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

Re: Error after making a change to martin-doyle\04-InterfacedBasedServices

Offline

Board footer

Powered by FluxBB