You are not logged in.
Pages: 1
Hello Arnaud,
Is it possible to call an interface based service asynchronously and have a callback when the call is complete? If not is it possible to call an interface based service in a different thread? If so would I need a separate TSQLHttpClient for each thread?
Or is there some other way?
Thanks,
Adrian
Thanks for the reply, I agree that application users are a better way to do it, but does this mean that I would have to pass the application user in each interface service function? So have a UserID or something parameter on each method? This is what I was trying to avoid by auto adding a user, then on the server I could simply identify the user using SessionUserName.
So what is the best way of identify the current application user on the server?
Thanks!
Thanks for your reply, I have moved the register user code to the server and this part is now working.
So now I am trying to auto register a user in OnAuthentificationFailed as described in your documentation on windows authentication. I am using interface services and my setup for standalone (debug) application is as follows:
FModel:=TSQLModel.Create([TSQLAuthUser,TSQLAuthGroup],BIAPIModelName);
FClient:=TSQLRestClientDB.Create(FModel,nil,ChangeFileExt(paramstr(0),'.db'),TSQLRestServerDB,True);
FClient.Server.CreateMissingTables;
FClient.OnAuthentificationFailed:=AuthentificationFailed;
FClient.Server.ServiceRegister(TBMAPI,[TypeInfo(IBIAPI)],sicClientDriven);
FClient.SetUser('','');
FClient.ServiceRegisterClientDriven(TypeInfo(IBIAPI),FAPI);
which I believe is correct.
But I have a chicken/egg situation. I need to call FAPI.RegisterUser in OnAuthentificationFailed, but FAPI is not yet defined as it comes from FClient.ServiceRegisterClientDriven(TypeInfo(IBIAPI),FAPI) which is after SetUser.
If I move the ServiceRegisterClientDriven before SetUser the authentication fails there.
So basically how do I call an interface service in OnAuthentificationFailed?
Please help!
Thanks for your reply, most helpful.
I am now trying:
group:=TSQLAuthGroup.Create;
user:=TSQLAuthUser.Create;
try
User.LogonName:=NetworkUsername;
User.PasswordPlain:='';
user.GroupRights:=group;
id:=FClient.AddOrUpdate(user,true);
finally
User.Free;
group.Free;
end;
It returns 0 for id and if I debug to find out why, I see that it exits in TSQLRestClientURI.EngineAdd here:
if URI(url,'POST',nil,@Head,@SentData).Lo<>HTTP_CREATED then
exit; // response must be '201 Created'
it returns 403 so exits.
Can you help further? Thanks in advance.
Hello,
I am trying to authenticate with Windows authentication, so far I have:
FModel:=TSQLModel.Create([TSQLAuthUser,TSQLAuthGroup],BIAPIModelName);
FClient:=TSQLHttpClient.Create('localhost',BIAPIPort,FModel);
FClient.SetUser('','');
FClient.ServiceRegister([TypeInfo(IBIAPI)],sicShared);
This seems right but fails as I do not have the users in TSQLAuthUser. As I want to automatically add users I have tried:
FClient:=TSQLRestClientDB.Create(FModel,nil,ChangeFileExt(paramstr(0),'.db'),TSQLRestServerDB,True);
FClient.Server.CreateMissingTables;
FClient.Server.ServiceRegister(TBMAPI,[TypeInfo(IBIAPI)],sicClientDriven);
user:=TSQLAuthUser.Create;
try
User.LogonName:=NetworkUsername;
FClient.Add(user,true);
finally
User.Free;
end;
FClient.SetUser('','');
FClient.ServiceRegisterClientDriven(TypeInfo(IBIAPI),FAPI);
But the user is not added to the table, I have opened the .db file in "DB Browser for SQLite" and there are no added users. So the authentication still fails.
I have also tried using TSQLRestServerAuthenticationNone, this works, but the property CurrentServiceContext.Request.SessionUsername on the server is empty, and I need this.
So what am I doing wrong?
Thanks and also thanks for all the great work!
Adrian
Hello,
How can I call RecordLoadJSON that has soReadIgnoreUnknownFields option set in the custom reader?
Thanks,
Adrian
Hello Arnaud,
I'm using your excellent mORMot library, specifically Client-Server services via interfaces as described in section 16 of the documentation.
But I am getting a "record too small" error, raised from line 52734 in mORMot.pas
smvRecord:
if ArgTypeInfo^.RecordType^.Size<=PTRSIZ then
raise EInterfaceFactoryException.CreateUTF8(
'%.Create: % record too small in %.% method % parameter',
[self,ArgTypeName^,fInterfaceTypeInfo^.Name,URI,ParamName^]) else
SizeInStorage := PTRSIZ; // handle only records when passed by ref
else
SizeInStorage := PTRSIZ;
An example record that causes this is:
TMyRec =record
Prop :string;
end;
If I change it to:
TMyRec =record
Dummy: Integer;
Prop :string;
end;
It works.
But a simple record just containing a string should work in my opinion. Maybe the condition should be:
if ArgTypeInfo^.RecordType^.Size<PTRSIZ then
So less than and not less than or equals to? What do you think?
Thanks for a wonderful library!
Adrian
Hello,
I think I have found a bug in your excellent SynPDF components.
I am using DRAW_TEXT with nothing special only DT_NOPREFIX and DT_WORDBREAK. In an older version of SynPDF, from 11 September 2013 everything works fine. But the latest version of SynPDF seems to draw text that contains spaces incorrectly. Instead of one space I get many spaces and the text is spread out across the page.
The bug occurs in TPdfEnum.TextOut because if I replace this procedure with code from the older version from 11 September 2013 then it all works again. So it is something to do with the code changes relating to disabling text clipping and I think the problem is when you save and restore the canvas.
Just try creating a PDF using DrawText with some text that has spaces in it.
Anyway just thought I would let you know.
AY
It's great that you fix things so quickly!
I've been doing a lot of investigation today and it seems that just setting FullDebugMode is not enough to catch all 64bit pointer arithmetic errors. For example if we take the line of code in TMD5.Update where I originally had my AV:
Move(p^, Pointer(PtrUInt(@in_) + 64 - t)^, len);
Evaluating the source and destination of the Move at runtime (with FullDebugMode on) I get:
Source = 00007FF5FFA18010
Dest = 0000000008CDF6B0
As you can see the source address is over 4GB but the destination isn't. This is probably because "in_" is a static array and not dynamically allocated at run time and is therefore in the same address space as the application. So to catch all pointer arithmetic errors the application needs to be loaded at an address higher than 4GB. This is the reason I had my AV when my dll was loaded by IIS and not when it was loaded by my test program. IIS loaded it a higher address.
The second StackOverflow link in my original message describes a registry key that will change the memory allocation to top down on a machine wide setting. But it seems that this can cause instability problems as some 64bit applications have pointer arithmetic errors!!!!
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference
Interesting stuff this! One thing I have learnt over my many years of doing this is that you cannot make assumptions about anything!
Adrian
Hello Arnaud,
I just run the full set of regression tests (TestSQL3.dpr) under Win64 and it reported no memory leak nor corruption.
So we could assume that pointer arithmetic is correct...
I'm not too sure about this, what about these lines for example from TAES.DoBlocks:
oIn := pointer(integer(pIn)+Count);
oOut := pointer(integer(pOut)+Count);
I too am using FullDebugMode, it's turning out very useful!
Adrian
That's great, thanks for the quick response.
Hello Arnaud,
I have been using your excellent PDF components for some time now and also SynCrypto.pas to generate MD5s. But I believe I have found a number of bugs in the 64bit version of your tools.
If you look at TMD5.Update, specifically the two Move(...) calls:
Move(p^, Pointer(Cardinal(@in_) + 64 - t)^, len);
Move(p^, Pointer(Cardinal(@in_) + 64 - t)^, t);
You are taking the 64bit address of @in_ truncating it to a 32-bit cardinal, adding an offset and converting it back to a 64bit pointer. I'm sure you see where I am going with this! If the address of @in_ is less than 4GB then this code works fine. If the address of @in_ is greater than 4GB an access violation occurs as an invalid pointer is created as the address of @in_ is truncated.
I have a dll which works perfect from a small test program, but as soon as it is run from IIS I get an access violation on the Move in SynCrypto.pas. This is probably because IIS is in a higher address space.
I'm sure you have tested under 64bit but I believe you have just been lucky and everything has been below 4GB. There is a similar bug and discussion here on StackOverflow:
http://stackoverflow.com/questions/1593 … on-on-win8
A quick search of your source code shows other pointer arithmetic bugs where the pointer is first truncated to 32bit. A simple fix for the two lines above is:
Move(p^, Pointer(NativeUInt(@in_) + 64 - t)^, len);
Move(p^, Pointer(NativeUInt(@in_) + 64 - t)^, t);
So simply replace the Cardinal with NativeUInt.
One way to test for these kinds of bugs is to do top down allocation tests as described here:
http://stackoverflow.com/questions/5442 … ows#545097
Anyway I hope you can fix your source soon and please keep up the good work, these really are excellent components.
Adrian
Pages: 1