#1 2015-08-04 13:13:08

marius maximus
Member
From: Olsztyn
Registered: 2015-06-11
Posts: 30

TSQLHttpServer and linux

Now I have 64bit Debian 8 wink

I compile server and client
"04 - HTTP Client-Server\Project04Server"
"04 - HTTP Client-Server\Project04Client"
Start server:
sudo ./Project04Server

Then I check 8080 port

"netstat -na |grep 8080
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN"

In my opinion LISTEN is OK wink

First test on linux:
1) telnet localhost 8080
2) wait 3s.
3) Message "Connection closed by foreign host."

In windows (server and telnet run on windows) this same test:
1) telnet localhost 8080
2) type "get index.html"
3) Result from serwer

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/str
ict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid URL</h2>
<hr><p>HTTP Error 400. The request URL is invalid.</p>
</BODY></HTML>

On windows server works correctly on linux serwer close Connection


Lazarus x64 Linux

Offline

#2 2015-08-04 21:52:19

marius maximus
Member
From: Olsztyn
Registered: 2015-06-11
Posts: 30

Re: TSQLHttpServer and linux

AB wrote:

x86-64 is not supported as a target for FPC, under Linux or Windows.
We started to support FPC with x86-32 under Linux and Windows.

Only Delphi as compiler is supported yet for Windows 64.

But  few comments to make it work ! One step to work !

The first problem( anyway very interesting )
In Delphi 32bit sizeof(TTextRec.Handle) = 4B
In Delphi 64bit sizeof(TTextRec.Handle) = 8B

In FPC/Lazarus
TTextRec.Handle type =  Longint (4B)

In function TCrtSocket.CreateSockIn and TCrtSocket.CreateSockOut you save into TTextRec.Handle  pointer


 
with TTextRec(SockIn^) do begin
    Handle := PtrInt(self);

My version use "userdata" to save pointer

 
with TTextRec(SockIn^) do begin
    Handle := PtrInt(self);
    PPtrInt(@UserData[1])^ :=  PtrInt(self);

And then replace all  (3x)
TCrtSocket(F.Handle)
with
TCrtSocket(PPtrInt(@f.UserData[1])^);

After that server reply HTML

Last edited by marius maximus (2015-08-04 21:53:38)


Lazarus x64 Linux

Offline

#3 2015-08-05 06:35:22

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

Re: TSQLHttpServer and linux

Please try http://synopse.info/fossil/info/1b58480d8e

Thanks for the feedback!
smile

Offline

#4 2015-08-05 08:07:25

marius maximus
Member
From: Olsztyn
Registered: 2015-06-11
Posts: 30

Re: TSQLHttpServer and linux

Thx very much !

Next step!
Now i test linux 64bit serwer by client from windows.

Problem is with function "WinHttpSendRequest" after call (function return FALSE) we have exception "Exception class EWinHTTP with message 'winhttp.dll error 12152 (invalid server response)'"

I look into wireshark and comapre windows<->windows and windows<-> linux connection
windows serwer <->windows client ALL WORKS OK !

GET /root/TimeStamp HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: no-cache
Content-Type: application/json; charset=UTF-8
Accept: */*
Accept-Encoding: synlz
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; Synopse mORMot 1.18.1735 TWinHTTP)
Host: 192.168.10.8:8080

HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Server: mORMot/1.18.1735 (Windows) Microsoft-HTTPAPI/1.0
X-Powered-By: Synopse mORMot 1.18.1735 http://synopse.info
Server-InternalState: 17
Date: Wed, 05 Aug 2015 07:41:41 GMT
Content-Length: 12

135254276713

linux 64bit serwer and windows client

GET /root/TimeStamp HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: no-cache
Content-Type: application/json; charset=UTF-8
Accept: */*
Accept-Encoding: synlz
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; Synopse mORMot 1.18.1735 TWinHTTP)
Host: 192.168.10.7:8080

HTTP/1.1 200 OK
Server-InternalState: 1
X-Powered-By: Synopse mORMot 1.18.1735 http://synopse.info
Server: mORMot/1.18.1735 (Linux)
Content-Length: 
Content-Type: text/plain; charset=UTF-8
Accept-Encoding: synlz,gzip
Connection: Keep-Alive

135254276817

the server responds correctly,
I need to think wink


Lazarus x64 Linux

Offline

#5 2015-08-05 08:54:02

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

Re: TSQLHttpServer and linux

Content-Length: seems to be void under Linux.

Offline

#6 2015-08-05 10:52:59

marius maximus
Member
From: Olsztyn
Registered: 2015-06-11
Posts: 30

Re: TSQLHttpServer and linux

Next step wink
Please add in TCrtSocket.SockSend

this caseoption

    vtInt64:begin
      Str(vtInt64,tmp);
      SockSend(@tmp[1],length(tmp));
    end;

Last edited by marius maximus (2015-08-05 10:57:26)


Lazarus x64 Linux

Offline

#7 2015-08-05 12:36:59

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

Re: TSQLHttpServer and linux

Offline

#8 2015-08-05 13:18:10

marius maximus
Member
From: Olsztyn
Registered: 2015-06-11
Posts: 30

Re: TSQLHttpServer and linux

small mistake in your code

your read vInteger but value is in "vInt64^" field !!!

I have mistake too wink

Correct version:

    vtInt64:    begin
      Str(VInt64^,tmp);
      SockSend(@tmp[1],length(tmp));
    end;  

After this fix I see "04 - HTTP Client-Server" works almost correct.
linux server add data and return correct results to client(s).
Is only small bug in linux client after "Add the message" client show message "'Error adding the data'" but in database is new record smile
Windows client don't have this bug !

Last edited by marius maximus (2015-08-05 13:47:14)


Lazarus x64 Linux

Offline

#9 2015-08-05 16:42:31

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

Re: TSQLHttpServer and linux

Offline

#10 2015-08-05 20:48:49

marius maximus
Member
From: Olsztyn
Registered: 2015-06-11
Posts: 30

Re: TSQLHttpServer and linux

sometimes   "'Error adding the data'" is from this function

function Send(s: TSocket; Buf: pointer; len,flags,timeout: Integer): Integer;
var maxTicks: Int64;
begin
  maxTicks := GetTickCount64+timeout;
  repeat
    {$ifdef KYLIX3}
    result := LibC.Send(s,Buf^,len,flags);
    {$else}
    result := fpSend(s,pointer(Buf),len,flags);

    writeln('ggggggg',result);

    {$endif}
    if result>=0 then
      exit; // success
    if timeout<=0 then
      break;
    if (errno<>WSATRY_AGAIN) and (errno<>WSAEINTR) then
      break;
    sleep(1);
  until GetTickCount64>maxTicks;
  writeln('errno Send()=',errno);
  result := -1; // error
end;    

fpSend return -1
on console i see "'errno Send()=32"


I need to think smile


Lazarus x64 Linux

Offline

#11 2015-08-06 06:37:10

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

Re: TSQLHttpServer and linux

AFAIK this is

 ESysEPIPE       = 32;   { Broken pipe }

Meaning the connection was broken...

I guess the socket was closed or not properly defined (handle issue?).

Offline

#12 2015-08-06 08:58:17

marius maximus
Member
From: Olsztyn
Registered: 2015-06-11
Posts: 30

Re: TSQLHttpServer and linux

Next step:

Problem in "function THttpSocket.HeaderGetText: SockString;"

Is problem "fast length" on different platform wink




This error is similar to
http://synopse.info/forum/viewtopic.php?pid=16504


And similar is fix

function THttpSocket.HeaderGetText: SockString;
var i,L,n: integer;
    V: PtrInt;
    P: PAnsiChar;
begin
  // much faster than for i := 0 to Count-1 do result := result+Headers[i]+#13#10;
  result := '';
  n := length(Headers);
  if n=0 then
    exit;
  L := n*2; // #13#10 size
  dec(n);
  for i := 0 to n do
    if pointer(Headers[i])<>nil then
     {$ifdef FPC}
      inc(L,PInteger(PAnsiChar(pointer(Headers[i]))-sizeof(pointer))^); // fast add length(List[i])
     {$else} 
      inc(L,PInteger(PAnsiChar(pointer(Headers[i]))-4)^); // fast add length(List[i])
     {$endif}
    
  SetLength(result,L);
  P := pointer(result);
  for i := 0 to n do begin
    V := PtrInt(PAnsiChar(Headers[i]));
    if V<>0 then begin
      {$ifdef FPC}
      L := PInteger(V-sizeof(pointer))^;  // L := length(List[i])
      {$else}
      L := PInteger(V-4)^;  // L := length(List[i])
      {$eif}
      move(pointer(V)^,P^,L);
      inc(P,L);
    end;
    PWord(P)^ := 13+10 shl 8;
    inc(P,2);
  end;
end;   

Or use this metod
{$ifdef FPC}PStrRec(Pointer(PtrUInt(U)-STRRECSIZE))^.length ....

This remove error "'Error adding the data'" and all works OK

Last edited by marius maximus (2015-08-06 10:06:11)


Lazarus x64 Linux

Offline

#13 2015-08-06 13:31:05

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

Re: TSQLHttpServer and linux

Offline

#14 2015-08-06 15:13:34

marius maximus
Member
From: Olsztyn
Registered: 2015-06-11
Posts: 30

Re: TSQLHttpServer and linux

Well done!
   
Now I open project from "14 - Interface based services" directory wink

First problem "procedure CallMethod(var Args: TCallMethodArgs);" it is only assembler sad
Exists "pure pascal" version ?

I need to think wink


Lazarus x64 Linux

Offline

#15 2015-08-24 20:28:41

marius maximus
Member
From: Olsztyn
Registered: 2015-06-11
Posts: 30

Re: TSQLHttpServer and linux

Next step to full suport x64 linux

After this fix "14 - Interface based services" server start works OK , client return correct result

procedure CallMethod(var Args: TCallMethodArgs);
{$ifdef CPUARM}
begin
  raise EInterfaceFactoryException.Create('FPC+ARM not supported yet');
end;
{$else}
{$ifdef CPU64}
{$ifdef FPC}
asm
    //.params 64    // size for 64 parameters
    //.pushnv r12   // generate prolog+epilog to save and restore non-volatile r12
    mov r12,Args
    // copy stack content (if any)
    mov RDI,[r12].TCallMethodArgs.StackAddr
    lea RSI,[rsp+$20]
    mov RDX, [r12].TCallMethodArgs.StackSize
    call Move
    // call method
    mov RDI,[r12+TCallMethodArgs.Regs+REGRDI*8-8]
    mov RSI,[r12+TCallMethodArgs.Regs+REGRSI*8-8]
    mov RDX, [r12+TCallMethodArgs.Regs+REGRDX *8-8]
    mov RCX, [r12+TCallMethodArgs.Regs+REGRCX *8-8]
    mov R8,[r12+TCallMethodArgs.Regs+REGR8*8-8]
    mov R9,[r12+TCallMethodArgs.Regs+REGR9*8-8]
    movsd xmm0,[r12+TCallMethodArgs.Regs+REGXMM0*8-8]
    movsd xmm1,[r12+TCallMethodArgs.Regs+REGXMM1*8-8]
    call [r12].TCallMethodArgs.method
    // retrieve result
    mov [r12].TCallMethodArgs.res64,rax
    mov cl,[r12].TCallMethodArgs.resKind
    cmp cl,smvDouble
    je @d
    cmp cl,smvDateTime
    je @d
    cmp cl,smvCurrency
    jne @e
@d: movsd [r12].TCallMethodArgs.res64,xmm0
@e:
end;
{$else}

Last edited by marius maximus (2015-08-24 20:30:34)


Lazarus x64 Linux

Offline

#16 2015-08-25 09:33:33

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

Re: TSQLHttpServer and linux

I'm afraid there may be issues with the XMM* registers.
Under Windows, there is either a R*register or a XMM* register used at a given slot: their address in TCallMethodArgs.Reg[] do overlap.
Under Linux, all the R* registers and XMM* registers are used, in order: their addresses do NOT overlap.

I tried to make it one step further.
See http://synopse.info/fossil/info/16c7d9aa04
But it is not yet finished...

Offline

#17 2015-08-25 19:11:23

marius maximus
Member
From: Olsztyn
Registered: 2015-06-11
Posts: 30

Re: TSQLHttpServer and linux

My bookmarks (for future) about linux64.
In api.pdf (page 23) we found exaple for function with many  parameters (double, struct and long double)   
AMD64 ABI
Calling conventions for different C++ compilers and operating systems
Wikipedia
Stack frame layout on x86-64

and windows
Parameter Passing

Last edited by marius maximus (2015-08-25 19:51:54)


Lazarus x64 Linux

Offline

Board footer

Powered by FluxBB