You are not logged in.
Sorry, my mistake. FPC & CodeTyphone, but I see that you have found and resolved.
Thank you, once again.
Thanks AB!
Unfortunately, the new error is in SynCrossPlatformREST:
SynCrossPlatformREST.pas(2712,26) Error: Incompatible types: got "Variant" expected "TID"
Hello AB!
Last night I picked up the latest mORmot version (2014-12-03 22:08:05) and the latest CodeTyphon version (V5.2) and now when compiling the app I get the following error:
"SynCrossPlatformSpecific.pas(92,3) Fatal: Cannot find unit Windows used by SynCrossPlatformSpecific.".
{$ifdef ISDWS}
uses
SmartCL.System,
System.Types,
w3c.date;
{$else}
uses
{$ifndef USETMONITOR}
Windows,
{$endif}
SysUtils,
Classes;
{$endif}
As I see it in SynCrossPlatform.inc no definition USETMONITOR for FPC.
Yes, in transmission encryption between client and server.
Something like in Windows version: "FClientStandard.Compression := [hcSynShaAes];"
Ticket UUID: 464bed6e1ccdb006e1415737740806e77bbd0aa4
Hello AB!
Do you have idea/plan when the encryption for FPC to be available?
After changes from 01.10.2014 in SynCommons.pas, the clients have reported to me that the mormot client application can not be started on some Windows XP machines.
Old code:
{$ifndef FPC}
{$ifndef DOPATCHTRTL}
if DebugHook=0 then // patch VCL/RTL only outside debugging
{$endif}
InitRedirectCode;
{$endif}
changed into:
{$ifndef FPC}
{$ifdef DOPATCHTRTL}
if DebugHook=0 then // patch VCL/RTL only outside debugging
InitRedirectCode;
{$endif}
{$endif}
I see that others have noticed this problem. Can we expect an update that will permanently solve this problem?
Best regards!
Here are results of RegressionTests:
Cross Platform Units for mORMot
---------------------------------
1. Running "Iso8601DateTime"
30003 tests passed in 00:00:068
2. Running "Base64Encoding"
304 tests passed in 00:00:000
3. Running "JSON"
18628 tests passed in 00:00:100
4. Running "Model"
1013 tests passed in 00:00:007
5. Running "Cryptography"
4 tests passed in 00:00:000
Tests failed: 0 / 49952
Time elapsed: 00:00:175
2014-09-08T10:07:29
Cross Platform Client for mORMot using TSQLRestServerAuthenticationDefault
----------------------------------------------------------------------------
1. Running "Connection"
0 tests passed in 00:00:006
2. Running "ORM"
!!! 209 test(s) failed / 4549
3. Running "ORMBatch"
4564 tests passed in 00:00:196
4. Running "Services"
25953 tests passed in 00:00:720
5. Running "CleanUp"
1 tests passed in 00:00:001
Tests failed: 209 / 35067
Time elapsed: 00:01:340
2014-09-08T10:07:29
Some tests failed... please fix it ASAP!
Press [Enter] to quit
Fedora 11 (64bit)
CodeTypon Version #5 (revision 4970) (64bit)
FPC V2.7.1.
I got the error after starting the RegressionTests. The Error is:
Project RegressionTests raised exception class 'External: SIGSEGV'
In file 'SynCrossPlatformJSON.pas at line 1350: result := BytesToBase64JSONString(GetTByteDynArrayProp(Instance,PropInfo)^);
Error is in function Function GetInstanceProp(Instance: TObject; PropInfo: TRTTIPropInfo): variant; when PropInfo^.PropType^.Kind = TKDYNARRAY.
RegressionTests.dpr(3,2) Fatal: Can not open include file "SynCrossPlatform.inc"
File is on CrossPlatform folder and folder is added into Paths.
Hello AB!
I have a problem with wrapped services on Client side (FPC/CodeTyphon).
The function is defined like "function GetLoginData(const username: string; const password: string): variant;
If I call the function with:
var
fTableJSON: variant;
begin
fTableJSON := FClientFunc.GetLoginData(FUser.Username, FUser.Password);
fTableJSON is: unsupported variant type: $0110
If I change that fTableJSON is string, situation is:
var
fTableJSON: string;
doc: variant;
begin
fTableJSON := FClientFunc.GetLoginData(FUser.Username, FUser.Password);
doc := JSONVariant(fTableJSON);
ftableJSON is: '[{"ID:1,"Username":"xx","FirstName":"System",..."Active":-1}]'
doc is: unsupported variant type: $0110.
Is it bug or I'm doing something wrong and how I can take field's values from received string?
OK, that means I have to replace the functions like JSONFileToObject/ObjectToJSONFile from mormot.pas with some other on the client side.
Is it possible to use mORMot.pas in FPC (Code Typon) on Linux?
Compiler gives me an error: mORMot.pas(1071,2) Fatal: Can not open include file "Synopse.inc". I need to use some functions from mORMot.pas like a JSONFileToObject. Is there any other alternative?
Thank you, again!
I'd be glad to help. I have to make FPC client that works with around thirty service functions, and I hope it will be a good test.
Thanks, I'll check after solve another compilation problem.
For example, on server function definition is:
function GetLoginData(username: RawUTF8; password: RawUTF8): RawJSON;
For FPC the Wrapper makes:
function GetLoginData(const username: string; const password: string): dynamic;
and CodeTypon compiler says:
mormotclient.pas(41,76) Error: Identifier not found "dynamic"
Well, then it's a bug in the FPC Wrapper?
Look, how looks a function:
function GetClient(const aServerAddress, aUserName,aPassword: string;
aServerPort: integer): TSQLRestClientHTTP;
begin
result := TSQLRestClientHTTP.Create(aServerAddress,aServerPort,GetModel,true); // aOwnModel=true
try
if (not result.Connect) or (result.ServerTimeStamp=0) then
raise ERestException.CreateFmt('Impossible to connect to %s:%d server',
[aServerAddress,aServerPort]);
if not result.SetUser(TSQLRestServerAuthenticationSSPI,aUserName,aPassword) then
raise ERestException.CreateFmt('%s:%d server rejected "%s" credentials',
[aServerAddress,aServerPort,aUserName]);
except
result.Free;
raise;
end;
end;
It is minor bug because user can delete that function and connect manual.
What is with the error regarding "dynamic"?
Ticket UUID: 464bed6e1ccdb006e1415737740806e77bbd0aa4
Ticket Title: Encryption in the SynCrossPlatform units
Thank you, again.
Thanks, I will!
Also, with mORMotClient.pas for FPC made from wrapper I get an error in function GetClient: mormotclient.pas(137,27) Error: Identifier not found "TSQLRestServerAuthenticationSSPI",
and for every service function which return RawJSON data type from server side in mORMotClient.pas I have error: mormotclient.pas(41,76) Error: Identifier not found "dynamic".
That's great, but I think that encryption will be also great for FPC and Delphi clients.
Now I need to make one app in version on Fedora 11 and I have chosen FPC (CodeTypeon or Lazarus). Server and Windows clients use your encryption and I am very pleased with how it all works. It would be best if I could use the existing server.
Thanks for information. Generated wrapper works very well.
When you said: "Our proprietary hcSynShaAes encryption is not part of the SynCrossPlatform units yet" are you talking about days, weeks, months or ...?
Hello AB!
1. Is it possible to use Interface functions on Client CrossPlatform side (CodeTyphon)? For example, on the server side I defined the interface with functions:
IRemoteServerStandard = interface(IInvokable)
['{FFFF753E-F6BB-4F60-B54D-9D3CA3961B87}']
function GetLoginData(username: RawUTF8; password: RawUTF8): RawJSON;
function SetAgencyInfo( id: int64; ipAddress: RawUTF8): boolean;
....
How can I call this function on the client side?
2. Is it possible to encrypt the connection as in Win version?
FClientStandard := TSQLHttpClient.Create(AnsiString(FIniData.WebAddress), AnsiString(IntToStr(FIniData.Port)), FModelStandard);
FClientStandard.Compression := [hcSynShaAes];
SynCrypto.CompressShaAesSetKey(RawByteString(c_CrKey));
Thanks!
Hi Ab!
I tried to compile the Sample "27-CrossPlatform" with Lazarus (V1.2.4), but I got an error: ".\SynCrossPlatformJSON.pas(534,34) Error: Identifier not found "RawByteString". Where is definition of RawByteString in Cross Platform?
Done and works perfectly.
Thanks AB!
Thanks AB!
I would like to try to override GetUser, but there do not see the password. My idea was to receive a username and password and check in MSSQLServer is user valid or not.
Also I found the problem with update TSQLAuthUser table.
For example, if the user decides to change its username (yes, users have that options...), update changes the data in the TSQLAuthUser table (UpdateToFile shows me the changed data), but he can not connect with new or old username. If he decides to return back the old username then he can connect with the old username. In same time, if user decides to change password, everything is OK.
If I understand it, the solution is:
- make in MSSQLSERVER tables TSQLAuthUser and TSQLAuthGroup
- make trigger on our table Users which update TSQLAuthUser table
- in server use VirtualTableExternalRegister
- change TSQLRestServerFullMemory into TSQLRestServerDB?
I don't know is it bottleneck or some my mistake. Such a user can not connect to after a few hours. Then I have to reset the server.
My idea is that TSQLRestServerAuthentication.ClientSetUser function read directly from the SQLServer User table when a user wants to connect, but I don't know how to do it. Is this possible?
Is that what you mean when you say: "just link directly to the external MSSQLServer table via ORM"? Do you have any example?
Hi AB!
In one our project we have SQLServer table with username and password data which users use for connect to our server via TSQLRestServerFullMemory. New users are added from the Web app which is independent of Mormot and for this reason I have added to timer every 120 seconds Mormot server reads sqlserver table and update existing user data and add new users like
EnterCriticalSection
try
ReadUserTable
LoopFromRecordSet and if UserID is exists Update it, else Add
finally
UpdateToFile all users and groups
LeaveCriticalSection
end
Does this concept is good or you have a suggestion for a better solution because we have a problem with the loggin process. With 200+ users in the database, some of them can not connect to Mormot server although the data is good.
Thanks, but our good optimized asm version sounds better solution in my case.
Thanks AB!
Everything is working properly.
Hi AB!
After test with Wireshark I found that communication Client-Server is not encrypted or have a problem.
For Example:
POST /root/RemoteVirtualShopServerStandard.MakeBill/9?session_signature=124B2EC4001A14F67AA2048C HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: no-cache
Content-Type: application/json; charset=UTF-8
Accept: */*
Accept-Encoding: synshaaes
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; Synopse mORMot 1.18 TWinHTTP)
Content-Length: 61
Host: demo.elbet.rs:213
[2,-1,47.62,1,1,1,"|01|02|03|04|05|06|",0,0,0,"",0,"",0,0,""]
The last row is what we send from client to server.
Server's answer looking OK:
Content-Type: application/json; charset=UTF-8
Content-Encoding: synshaaes
Server: Microsoft-HTTPAPI/2.0
X-Powered-By: SynCrtSock http://synopse.info
Server-InternalState: 0
Date: Mon, 06 Jan 2014 22:09:16 GMT
Content-Length: 640
....[.|4!..c....U..}'..[.1....b...2..c......#....g...LZO...fv.B...3.>@*...>.eR....8F=Sp.*.)..C..0...Q..c..S....w.q.).p.E.G.u.L.;`.(....zv.~...\.e.*..7.TL..e..a-H[..!...z?~....`..(.:Io....Z.P...n.L.D........6_.}..*w..{.A..n.........#.GxF.?.S.:....0.....e..........Z.oE.]/...Ed..Uv;M_|>Rz.[.'.Z-....bh....p...>.k..b.#d....._....r....ngK0Z).T..#R...1j.....&nC:.......%"0./..Zw>s6.....h.T.f&.fDl..3...s..~U.G..!H.m...pN..b.'.+A...bI...Y.4..'..........hC..p(R'y...!..Ip..o{.z.M*....J.cUF.......I.).....1...N... ..J$...t..\....+Jpf.....r..mh;......3..8.y.L.I..`..{.@.....^..*..Q.K.6x.....D..~O.?..L.I.........K.,Py..~..!......R...........@....4.Y
Is it possible to hide/encrypt the client's request?
Thanks again!
Thanks AB!
Everything is working perfect, also implementation is simple. Great job!
I have one question.
In line: "MyServer := TSQLHttpServer.Create('888',[DataBase],'+',useHttpApiRegisteringURI,32,secSynShaAes);" I sow value 32 which is ServerThreadPoolCount. In documentation explanation for that field is:
// - the ServerThreadPoolCount parameter will set the number of threads
// to be initialized to handle incoming connections (default is 32, which
// may be sufficient for most cases, maximum is 256)
Is that mean 32 maximal connection if I use sicClientDriven in ServiceRegister?
Hi!
I need to encrypt RESTFUL communication.
My idea was on client side encrypt data like in sample:
fTableJSON := FServiceStandard.GetAllConfigData(CryptDataUTF8(JSONEncode(['idAgency', AgencyID]), CrKeyIn));
and on server side decrypt data in GetAllConfigData function:
fParamsJSON := DecryptDataUTF8(inputData, CrKeyIn);
JSONDecode(fParamsJSON, ['idAgency'], Values, true);
...
Problem is when Server side receive RawUTF8 string value which contains byte 0 (zero). In that case received byte is wrong cause it has just bytes before zero byte.
For encrypt/decrypt data I use AESSHA256 function.
Do you have some suggestion how I can fix that problem or use encrypted server-client communication without SSL?
Thanks!
Looks like is ok. No fault occurs.
Thank you!
It was a pleasure to participate in solving this problem.
And I must say sorry, but still it is not OK. Last time I forgot to wrote to you that in test I used GetString instead GetS function. Now from mORMot side everything is OK, but problem is in Delphi.
Result.Fields[F].AsString call DataDB.pas procedure TStringField.SetAsString(const Value: string)
procedure TStringField.SetAsString(const Value: string);
begin
SetAsAnsiString(AnsiString(Value));
end;
AnsiString(Value) call System.pas procedure _LStrFromPWCharLen(var Dest: _AnsiStr; Source: PWideChar; Length: Integer; CodePage: Word);
_LStrFromPWCharLen variable Source is ok, but in line CharFromWChar(Pointer(Dest), DestLen, Source, Length, CodePage); variable Dest is not like Source. Probably because of CodePage 1252.
In this line Serbian Latin is: "Kompanija ŠDCCŽ" instead "Kompanija ŠĐČĆŽ" and Serbian Cyrillic: "????????? ?????" instead "Компанија ШЂЧЋЖ".
From that reason I told you that Delphi probably is not "pure" unicode. Maybe it is normal behavior but problem exist. DataSet in string fields can not show all unicode letters without changed code page. Wide string may be outdated, but it doing the job.
At this point my solution is:
Line 157: Add(aFieldName,ftString,aTable.FieldLengthMax(F,true));
Changed with line: Add(aFieldName,ftWideString,aTable.FieldLengthMax(F,true));
or
remove {$ifndef UNICODE} directives.
How is going, JSON field UTF8 must be datset wide string field.
Unfortunately the problem is still present.
I'll try explain with sample:
In MSSQL database I have nvarchar fields which have data for few languages. For example, field can has values:
English: "Company SDCCZ"
Serbian Latin: "Kompanija ŠĐČĆŽ"
Serbian Cyrillic: "Компанија ШЂЧЋЖ"
My regional settings are English USA - for customers I don't know.
With string field in DataSet and aTable.GetS(i,F) in DBGrid data look like:
English: "Company SDCCZ"
Serbian Latin: "Kompanija Š???Ž"
Serbian Cyrillic: "????????? ?????"
If I remove IFDEF, IFNDEF directives and set aForceWideString = true, in your last update, everything is ok and in DBGrid I have:
English: "Company SDCCZ"
Serbian Latin: "Kompanija ŠĐČĆŽ"
Serbian Cyrillic: "Компанија ШЂЧЋЖ"
Probably Delphi xe3 DataSet strings are not real unicode
Could you remove IFDEF/IFNDEF directives?
Ticket ID is: 2970335e406c1feb64d206972371d265b6ad79c9
Thanks!
However, the bug or feature, I guess I'm not the only one who needs to see letters from several code pages at the same time. Thanks!
Hi!
I found error in function TSQLTableToDataSet when translates UTF8 strings. In my case any Cyrilic letter translated into "?" because UTF8 fields treated like strings.
For solution I added two lines in unit mORmotVCL.pas:
with result.FieldDefs do begin
Types[F].SQLType := aTable.FieldType(F,@Types[F].EnumType);
case Types[F].SQLType of
sftBoolean:
Add(aFieldName,ftBoolean);
sftInteger:
Add(aFieldName,ftLargeint); // LargeInt=Int64
...
...
...
sftUTF8Text: //NEW DEFINITION - LINE 140
Add(aFieldName,ftWideString,aTable.FieldLengthMax(F,true));
else
Add(aFieldName,ftString,aTable.FieldLengthMax(F,true));
end;
end;
// and changed line 172:
sftUTF8Text:
result.Fields[F].AsString := UTF8ToString(aTable.GetU(i,F));
// result.Fields[F].AsString := String(aTable.GetS(i,F));
Should I create a new ticket for this bug?
Posted.
Ticket ID is 57bea48f30c8ef59f2bb83fc3eb9f96401f6bfa2.
Thanks!
Now, I started Sample 16 and got same Exception like in my app.
Debugger Exception Notification
Project Project16ServerHttp.exe raised exception class EAssertionFailed with message 'You should call TOleDBConnection.Free from the same thread which called its Create: i.e call MyProps.EndCurrentThread from an THttpServerGeneric.OnHttpThreadTerminate event - see ticket 213544v2f5 (C:\......\SynOleDB.pas line 1884)'.
Delphy XE3, Windows 7 64bit, compiled Debug 32bit and mORMot from yesterday.
I want make create TSQLDBConnectionProperties for each connected user and destroy TSQLDBConnectionProperties on logout or timeout.
something like:
- New user Login on TSQLHttpServer. Create in TSQLRestServerFullMemory new TSQLDBConnectionProperties for TServiceRemoteLiveServerStandard service (with that TSQLDBConnectionProperties TServiceRemoteLiveServerStandard services will use SQLServer database)
- User Logout on TSQLHttpServer. Destroy in TSQLRestServerFullMemory for TServiceRemoteLiveServerStandard service TSQLDBConnectionProperties
Probably you wish to create and destroy TIniData at inside your REST server, which will be done once.
And use threadvar ServiceContext inside your interface service.Or define any method to be called inside TServiceRemoteLiveServerStandard, do all "create try finaly destroy" operations.
Sample 14 - "14 - Interface based services" may help you.
I have interface based service.
type
TServiceRemoteLiveServerStandard = class(TInterfacedObject, IRemoteLiveServerStandard)
protected
fProps: TOleDBMSSQL2008ConnectionProperties;
public
destructor Destroy; override;
procedure AfterConstruction; override;
...
On event AfterConstruction I create props with DBConnection data and on destructor try to destroy props, but catch error "You should call TOleDBConnection.Free from the same thread which called its Create: i.e. call MyProps.EndCurrentThread from an THttpServerGeneric.OnHttpThreadTerminate event - see ticket 213544b2f5."
Does anybody can help me? What is solution? To move create and destroy props somewhere else and where?
procedure TServiceRemoteLiveServerStandard.AfterConstruction;
var
iniData: TiniData;
begin
inherited;
if fProps = nil then
begin
iniData := TiniData.Create;
try
JSONFileToObject(C_IniFileName, iniData);
fProps := TOleDBMSSQL2008ConnectionProperties.Create(
iniData.ServerName,
iniData.DatabaseName,
iniData.Username,
DecryptData(iniData.Password, c_ApplicationName)
);
finally
FreeAndNil(iniData);
end;
end;
end;
destructor TServiceRemoteLiveServerStandard.Destroy;
begin
// fProps.EndCurrentThread;
FreeAndNil(fProps);
inherited;
end;
Delphi XE3.
For my case, I found working around solution. Instead TDataSet I used TSQLTableJSON and everything is working fine.
On server side I put data from SQLServer into RawJSON, and on Client side receive data into RawUTF8. This part shows data correctly. Now if I RawUTF8 data move to:
1. TSQLTableJSON and fill ComboBox with it, everything is OK, but if I put data into
2. TDataSet and fill ComboBox with it, for each Cyrillic letters I'll get sign "?".
TSQLTableJSON filled: fData := TSQLTableJSON.Create([], '', fTableJSON);
TDataSet filled: fDataSet := JSONToDataSet(self, fTableJSON);
var declaration is:
var
fTableJSON: RawUTF8;
fData: TSQLTableJSON;
fDataSet: TDataSet;
How I sow, problem is on second constructor and Pointer: "JSONBuffer: PUTF8Char"
Hello,
In database we have test company with Serbian Latin and Cyrillic letters "Test Company ŠČĆ ШЛЧ".
When I try to move data received from Database into TDataSet, Serbian Latin and Cyrillic letters changed.
Here is code.
fTableJSON := FormDataModule.Service.GetCompanyList(FormDataModule.User.CompanyID); //"Test Company ŠČĆ ШЛЧ" ' It is OK!
fDataSet := JSONToDataSet(self, fTableJSON);
unit mORMot
constructor TSQLTableJSON.Create(const Tables: array of TClass; const aSQL,
aJSON: RawUTF8);
var len: integer;
begin
len := length(aJSON);
PrivateCopyChanged(pointer(aJSON),len); //"Test Company ŠČĆ ШЛЧ" ' Until here is OK!
Create(Tables,aSQL,pointer(fPrivateCopy),len);
end;
constructor TSQLTableJSON.Create(const Tables: array of TClass; //Here JSONBuffer is "Test Company ŠČĆ ШЛЧ"
const aSQL: RawUTF8; JSONBuffer: PUTF8Char; JSONBufferLen: integer);
begin // don't raise exception on error parsing
inherited Create(Tables,aSQL);
ParseAndConvert(JSONBuffer,JSONBufferLen);
end;
How can I avoid this problem?
Thanks, again!
You've helped me a lot. Every beginning is difficult.
Thank you for fast reply!
Before continuing to read the documentation, can I use, in my case, any of 18 samples from Samples folder or do you have some other suggestion?