#1 2021-03-30 16:26:44

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

mORMot1 to mORMot2 conversion problems

I am converting a program from mORMot1 to mORMot2 (version 2021/03/29). It is a TMVCApplication. Delphi 10.4.2, Windows Server 2019, defined ONLYUSEHTTPSOCKET. I have 2 questions about this:

1) Under mORMot1 you could assign your own log class to TSQLRestServerDB with LogClass := TVGServerLog;. Under mORMot2 you can't do this with TRestServerDB anymore. How to do it right with mORMot2?

2) After switching to mORMot2 I always get the following error messages on the server:

000000000085548F  " EXC   ENetSock {Message:"SockRecvLn error 10053 after 0 chars"} [Pool1-Shop] at 765264
00000000015F92EB  " EXC   ENetSock {Message:"SockRecvLn error 10053 after 0 chars"} [Pool1-Shop] at 765264
0000000001AC3D8B  " EXC   ENetSock {Message:"SockRecvLn error 10053 after 0 chars"} [Pool1-Shop] at 765264
...

What could be the cause?

With best regards
Thomas

Offline

#2 2021-04-01 10:33:06

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

Re: mORMot1 to mORMot2 conversion problems

I want to specify the error 10053 a little bit more. This is the error message from the log file:

00000000655F5E17  F info  SetThreadName 1904=TVGSHttpSvr 80 Shop THttpSvrResp
0000000065A9D1E0  " EXC   ENetSock {Message:"SockRecvLn error 10053 after 0 chars"} [Pool1-Shop] at 765134 mormot.net.sock.pas TCrtSocket.SockRecvLn (2461) @FinalizeArray @FinalizeArray @FinalizeRecord mormot.net.sock.pas TNetSocketWrap.Close (1358) TMonitor.Destroy @FreeMem TObject.FreeInstance mormot.net.server.pas TSynThreadPoolTHttpServer.Task (2310) mormot.core.threads.pas TSynThreadPoolWorkThread.DoTask (2325) mormot.core.threads.pas TSynThreadPoolWorkThread.Execute (2364) mormot.core.threads.pas TSynThreadPoolWorkThread.Execute (2374) 

I have not found any direct connection between the call of a certain function and the occurrence of the error. At first glance, it looks like the error occurs sporadically. I could provide more information if I knew where to dig in.

With best regards
Thomas

Offline

#3 2021-04-02 07:49:42

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

Re: mORMot1 to mORMot2 conversion problems

I am not able to reproduce it here.
It seems to happen in a server thread. But THttpServerSocket.GetRequest first check for any broken socket before processing the request using GetHeader/GetBody - and SockRecvLn.

We need to know in which context SockRecvLn is called.
The call stack is not very detailed in the logs.

Could you try again forcing the stack frame to be always generated in the Project/options?
And perhaps also put the logs on verbose mode?
What is the client User-Agent (I have seen weird socket behavior with Safari e.g.)?

Offline

#4 2021-04-02 09:08:42

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

Re: mORMot1 to mORMot2 conversion problems

Thanks Arnaud for your answer. I will investigate the problem with error 10053 in more detail.

First, I would like to answer question one myself. If I had looked correctly, I would have noticed it myself. In mORMot2, TRest.LogClass is a read-only property. The function TRest.SetLogClass is not the setter function for property LogClass. Therefore:

mORMot1:
LogClass := TMyServerLog;

mORMot2:
SetLogClass(TMyServerLog);

With best regards
Thomas

Offline

#5 2021-04-02 10:40:42

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

Re: mORMot1 to mORMot2 conversion problems

It is a web app similar to the mORMot1 example "30 - MVC Server". For testing I use the Firefox browser. The Windows file "System32\drivers\etc\hosts" contains the following entry: "127.0.0.1 test.meine-domain.de". The following URL is called: "test.meine-domain.de". A RootRedirectGet := 'Shop/Default' then redirects to HTTP "test.meine-domain.de/Shop/Default".

The following steps lead to the error:
In unit mormot.net.server, the function THttpServerSocket.GetRequest() in line 1980 calls the function SockRecvLn(Command). When the error occurs "Command = ''". After that it jumps to the function TCrtSocket.SockRecvLn() in the unit mormot.net.sock. After the call to readln(SockIn^, Line) in line 2458 the variable "Line = ''". After the call to ioresult "Error = 10053". The exception is thrown.

With best regards
Thomas

Last edited by tbo (2021-04-02 10:46:50)

Offline

#6 2021-04-02 12:07:24

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

Re: mORMot1 to mORMot2 conversion problems

If you can, try to put a breakpoint into InputSock and check exactly where it returns an error.

Offline

#7 2021-04-02 17:16:40

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

Re: mORMot1 to mORMot2 conversion problems

First of all, the following observation: I have now tested it with the browsers Vivaldi (Chromium) and MS Edge. The problem does not occur here. It only occurs with Firefox for me.

The error occurs already on the simply designed login page. The page has 2 input fields for login name and password. The page consists of pure HTML, no JavaScript! The error is already triggered once without any further action by the user or the server program. It looks like Firefox sends something to the mORMot2 server that is not processed properly. I started to change the server from mORMot1 to mORMot2 3 days ago. Under mORMot1 the problem did not occur.

Before the exception, the following values are in InputSock():

F	(-1, 55217, 1, 1024, 0, 0, '', $764448, $764310, nil, $764410, (48, 2, 229, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), (#0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0), (#0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0), 0, 0, 0, (#0, #0, #0, #0, #0, #0), (#0, #0, #0))

sock	($FFFFFFFF, '', '', $359B080, nil, 5000, 0, 0, nlTCP, 10053, False, '', 0, '', ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), nil, (False, False, False, '', '', '', '', '', '', '', ''), (nil,nil))

It goes into this if loop:

  if not sock.SockIsDefined then
  begin
    result := WSAECONNABORTED; // on socket error -> raise ioresult error
    exit; // file closed = no socket -> error
  end;

With best regards
Thomas

Last edited by tbo (2021-04-02 17:21:29)

Offline

Board footer

Powered by FluxBB