You are not logged in.
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
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
I get the same error, whether SetUser is first, in the middle or last..
Offline
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
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
@ab: Thanks for catching that. I didn't notice it.
@Thomas: My problem with your demo 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
@Thomas: My problem with your demo 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
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
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
Should be included with
https://github.com/synopse/mORMot2/commit/0476910c
Offline