You are not logged in.
I have huge project implemented by delphi vcl with 600 forms.
I use madexcept to catch and show unhandeded exceptions.
if mormot can handle this. I mean if there is onException Event handler or somthing like this. I can replace it with mormot.
Myabe OnBeforeException event can help.
I also show call stack to end user when exception is unhandeled:
https://gist.github.com/a-nouri/8ddfe5d … 8bdf28ae69
show_error function shows error in form to end user. and then sent to my website and I save unhandedled exceptions in table in web site by php.
Very useful. Thank you so much.
I tried
TAppLog.Family.StackTraceUse := stOnlyManual;
and
TAppLog.Family.LevelStackTrace := [];
with not success!
Is there a way to set TSynLog that don't capture exceptions?
After upgrading to the new version I encountered another problem. madexcept stopped working and to solve the issue I had to use the following option:
TAppLog.Family.Level := [sllInfo, sllWarning]
instead of
TAppLog.Family.Level := LOG_VERBOSE
I actually used mormot logging feature in a Windows desktop project.
Solved with this commit.
Thank you so much
Yes.
type
TClient = record
ConnectionId: THttpServerConnectionID;
ComputerName: string;
end;
TClients = array of TClient;
TInt64DynArray = array of Int64;
FClients := TSynDictionary.Create(TypeInfo(TInt64DynArray), TypeInfo(TClients));
Hi AB, many thanks to great framework.
I have
FClients: TSynDictionary;
TSynDictionary.SaveToJson generate below json :
{1:{"ConnectionId":1,"ComputerName":"Test"},2:{"ConnectionId":2,"ComputerName":"Comp"}}
which is not valid json.
how can I remove "{1:","{2:", ... from Result.
TThread.Queue Solved the issue!
EchoFrame method:
procedure TForm2.EchoFrame(Sender: TWebSocketProcess; const Frame: WebSocketFrame);
begin
case Frame.opcode of
focContinuation:
begin
TThread.Synchronize(nil, procedure
begin
Memo1.Lines.Add('connected');
end);
end;
end;
end;
I think there is issue in somewhere in mormot.
When lProto.OnIncomingFrame assigned before socket upgrade this function takes 5 seconds to finish
procedure TWebSocketProcess.WaitThreadStarted;
var
endtix: Int64;
begin
endtix := GetTickCount64 + 5000;
repeat
SleepHiRes(0);
until fProcessEnded or
(fState <> wpsCreate) or
(GetTickCount64 > endtix);
end;
Is this bug or abnormal behaviour?
I accidentally changed the position of a line and the problem was solved. But why should this happen?
var
ClientWS : THttpClientWebSockets;
lProto : TWebSocketProtocolEcho;
begin
lProto := TWebSocketProtocolEcho.Create('meow','');
ClientWS := THttpClientWebSockets.Create;
ClientWS.Open('127.0.0.1', '12346');
ClientWS.WebSocketsUpgrade('', '', false, [], lProto, '');
lProto.OnIncomingFrame := EchoFrame; //this line moved here
Why you don't share it in github. It can help mormot community and make it popular farmework.
I created TWebSocketServer server and TWebSocketProtocolChat. When I connect it with JS it is fast.
But when I connect with below code it takes 5 second to upgrade.
var
ClientWS : THttpClientWebSockets;
lProto : TWebSocketProtocolEcho;
begin
lProto := TWebSocketProtocolEcho.Create('meow','');
lProto.OnIncomingFrame := EchoFrame;
ClientWS := THttpClientWebSockets.Create;
ClientWS.Open('127.0.0.1', '8383');
ClientWS.WebSocketsUpgrade('', '', false, [], lProto, '');
Yes. Solved. thanks alot
for creating multiple file I am using multiple classes:
TDbLog = class(TSynLog); // Log for database operations
TApiLog = class(TSynLog); // Log for API calls
Is this correct ?
I can't figure out this code work properly. when I replace myLog1 with TSynLog it works.
var
myLog1,myLog2: TSynLog;
begin
myLog1 := TSynLog.Create();
myLog1.Family.Level := LOG_VERBOSE;
myLog1.Family.DestinationPath := 'D:\SynLog1\';
myLog1.Family.FileExistsAction := acAppend;
myLog1.Log(sllInfo, 'Logging initialized.');
end;
I am using FK allways but for show message to end user I use information schema table to find all fk's and then create my own message. It is so easy and it is one function for checking refrential integrity.
this is for mysql:
select REFERENCED_TABLE_NAME,CONSTRAINT_NAME,group_concat(COLUMN_NAME) COLUMN_NAME,
group_concat(REFERENCED_COLUMN_NAME) REFERENCED_COLUMN_NAME,
group_concat(COLUMN_NAME,'=',REFERENCED_COLUMN_NAME) col_ref
from INFORMATION_SCHEMA.KEY_COLUMN_USAGE
where TABLE_SCHEMA = :TABLE_SCHEMA
and TABLE_NAME = :TABLE_NAME
and referenced_column_name is not NULL
group by REFERENCED_TABLE_NAME,CONSTRAINT_NAME
parsing error message can not create understandable message. when user want to delete product number 1 I show this message:
product 1 used in invoice 123 and can not deleted.
invoice 123 is first invoice that used product number 1.
Excellent.Thank you
order is not matter. suppose json = {"a": 1,"b":2}
fdocdict := DocDict (json);
what is the problem with:
fdocdict[0].key
fdocdict[0].value
or somthing like that.
maybe conevrting docdict to varinat can help?
I mean somthing like this:
for docdict in DocList do
docdict .get_item_by_index(0);
get item value for docdict with index.
Is there a option to get key and value with index of item?
DocList.Items[0].key
DocList.Items[0].Value
I have epass3003 token. How can I connect it and sign string with it?
Thank You
Suppose I have valid certificate purchased, is it possible sign executables with mormot?
Sorry for the stupid question.
Using StringToUtf8 solved the problem:
msg := StringToUtf8(Edit1.Text);
I have another problem. This code does not generate correct result for unicode characters. for ansi chars it is ok.
Seems I have problem converting string to rawbytestring?
var CryptPrivateKeyRsa := TCryptPrivateKeyRsa.Create;
CryptPrivateKeyRsa.Load(ckaRsa, nil,Memo1.Lines.Text,'');
var msg: RawByteString;
msg := Edit1.Text;
//var sig := CryptPrivateKeyRsa.Sign(caaRS256,msg);
var sig := CryptPrivateKeyRsa.Sign(caaRS256,pointer(msg),Length(msg));
var sig64:= BinToBase64(sig);
Memo3.Lines.Text := sig64;
Thank you so much.
solved ❤️
Hi.
I got abstract error in Generate:
var
LICryptPrivateKey: ICryptPrivateKey;
begin
LICryptPrivateKey := TCryptPrivateKey.Create;
TCryptPrivateKey(LICryptPrivateKey).Generate(caaRS256);
This one works.
I don't know is it right or not.
RegisterOpenSsl;
var aa := CryptAsymOpenSsl[caaPS512].Create('secp256r1');
//secp192r1 ,secp224r1 ,secp256r1 = prime256v1 ,secp384r1 ,secp521r1 , brainpoolP256r1 ,brainpoolP384r1 ,brainpoolP512r1
var prv,pub: RawUtf8;
prv := Memo1.Lines.Text;
aa.Sign(msg,prv,sig);
pub := Memo2.Lines.Text;
if aa.Verify(msg,pub,sig) then
ShowMessage('verified');
I am trying to use
OpenSslSign('',pointer(msg),pointer(priv),Length(msg),Length(priv),sig)
raise Access violation in mormot.crypt.openssl
function :
function BIO_new_mem_buf(buf: pointer; len: integer): PBIO;
There is no mormot.core.rsa but mormot.crypt.rsa was in uses clause.
when I set ckaRsa : key.Load(ckaRsa,pub,Memo1.Lines.Text,'');
erorr : TCryptPublicKeyEcc.Create: unsupported ckaNone
I debuged it little bit in TCryptPublicKeyEcc.Load function only ckaEcc256 supported.
Result is empty string:
key = '-----BEGIN RSA PRIVATE KEY----- ...'
var pub := TCryptPublicKeyEcc.Create;
pub.Load(ckaEcc256, Memo2.Lines.Text);
var key := TCryptPrivateKeyEcc.Create;
key.Load(ckaEcc256,pub,Memo1.Lines.Text,'');
var s := key.Sign(caaRS256,'1'); // s = ''
Hi.
I can't find a way for signing a file with mormot.
I search forum and googled and can't find anything about that.
I confused with woDontStoreVoid because of documentation in mormot.core.text:
// - woDontStoreVoid will avoid serializing numeric properties equal to 0 and
// string properties equal to '' (replace both deprecated woDontStore0 and
behaviour is different:
when numeric field has 0 value or string has '' it serialize it to {"num":0,"str":""}. but when it is null doesn't serialize it.
I think documentation need to be correct?
I find a way:
var
MyCalss: TMyCalss;
json: string;
MyArray: TMyArray;
begin
SetLength(MyArray, 1);
MyArray[0] := TClass.Create;
MyCalss := TMyCalss.Create;
MyCalss.ID := 1;
MyCalss.ArrayClass := MyArray;
json := ObjectToJson(MyCalss,[woDontStoreVoid]);
json := StringReplace(json,'[{}]','[]',[rfReplaceAll]);
result => {"ID":1,"ArrayClass":[{}]}
then StringReplace replace [{}] with [].
I hope it is safe way!
Thank you for great framewotk
Yes it works.
But when the field is of arrayof class type and is not assigned, it will also delete it.
type
TMyCalss = class
private
fid: integer;
fqty:TNullableInteger;
FOtherClass:TArrayOfOtherClass;
published
property id: integer read fid write fid;
property qty: TNullableInteger read fqty write fqty;
property OtherClass: TArrayOfOtherClass read FOtherClass write FOtherClass;
end;
In many cases api report this as error and expect [] for nil array.
I have class like this:
type
TMyCalss = class
private
fid: integer;
fqty:TNullableInteger;
fdescr:TNullableUtf8;
published
property id: integer read fid write fid;
property qty: TNullableInteger read fqty write fqty;
property descr: TNullableUtf8 read fdescr write fdescr;
end;
json := ObjectToJson(MyCalss ,[]);
is there an option create json without null values?
[{"id":1,"qty":null,"fdesc":"descr"}] => [{"id":1,"fdesc":"descr"}]
It is nice TTextWriterWriteObjectOption include woReomveNullValues or something like that
2,147,483,647 for id field can be reah quickly.
I prefer bigint over integer for this reason.
I had previously used integer ids for a few clients. Then I set up a replication. Since the id was autoinc, it quickly exceeded the maximum integer and I had to change the id to bigint.
The reason why integer fills up quickly is that I had to use auto_increment_offset and auto_increment_increment to avoid duplicate ids. For example, considering the number of branches, set auto_increment_increment to 100 and auto_increment_offset to the branch number
In this case, branch number one will be 1,101,201,... and branch number two will be 2,102,202, ...
When numbering, the database assigns the first available number after the last number to the branch.
That is, if branch number one has created number 101, the first number of branch number two will be 102.
That is why integer will quickly reach its maximum value
Solved. Thank you.
I have identified the location of the error in the source below.
https://gist.github.com/a-nouri/cb11785 … c11425d05c
And I call it :
procedure TForm1.Button1Click(Sender: TObject);
var
MyCryptAndHash: TMyCryptAndHash;
Enc: string;
begin
MyCryptAndHash := TMyCryptAndHash.Create;
Enc := MyCryptAndHash.AESEncrypt('111', '01234567890123456789012345678912');
MyCryptAndHash.Free;
end;
After adding mormot.crypt.rsa to the uses section, the problem is solved.
In mormot.crypt.secure function Cipher return nil. Function can't resolve algoname because it is not initilized
I found a problem and it took me a whole day. When using the encryption functions. The mormot.crypt.rsa unit must be used.
Otherwise, the output of some functions is nil and causes problems. For example:
CryptCipher := Decrypt('aes-256-gcm', Pointer(Lkey));
Seems, in the intialziation section of the mormot.crypt.rsa unit, some classes are created and initialized.
I just wanted to make sure that what I was doing was correct and that I had done a standard and proper encryption. And I needed your confirmation.
Which seemed to be correct. Thank you.
After couple of days I can't figure out right way to encrypt AES GCM.
Even AIs don't give the right answer. I can't find any educational resources on YouTube or anywhere else.
TCryptAesCipher in mormot.crypt.secure is not visible?!
I can't use it
I had used TAes for Aes Gcm before, you suggested I use ICryptCipher. I tried using the suggested method.
But I wanted to see if the string encrypted with the first method can be decrypted with high level ICryptCipher. My attempt was unsuccessful.
Encrypted string does not decrypt with AESDecrypt with error: TAesGcm.DecryptPkcs7: Invalid Input.
function AESEncrypt2(PlainText: string; Key: RawByteString): string;
var
akey : RawByteString;
CryptCipher: ICryptCipher;
dest,Bytes: TBytes;
begin
akey := HexToBin(SHA256(Key));
Bytes := TEncoding.UTF8.GetBytes(PlainText);
CryptCipher := Encrypt('aes-256-gcm', Pointer(akey));
CryptCipher.Process(Bytes, dest, nil);
Result := TNetEncoding.Base64.EncodeBytesToString(dest);
end;
function AESDecrypt(CipherText: string; Key: RawByteString): string;
var
AES: mormot.crypt.core.TAesGcm;
akey : RawByteString;
begin
akey := HexToBin(SHA256(Key));
AES := mormot.crypt.core.TAesGcm.Create(pointer(akey)^, 256);
try
Result := AES.DecryptPkcs7(Base64ToBin(CipherText), False);
finally
AES.Free;
end;
end;
Thank you. Solved
Hi,
when I set ResultAsJsonObjectWithoutResult = true in server side, in client side I got only first record. Json is ok in rest dbugger!
var
I: IAttachmentService;
json: RawJson;
begin
if HttpClient.Services['AttachmentService'].get(I) then
begin
json := I.GetAttachTypeList(); // json contains first record only!
end;
end;
Yes it is interface-based service.
Solved.
Thank you so much.