{$mode objfpc} uses fcgi,sockets,sysutils; var sock:integer; df:text; function readdata(sock:integer; pdata:pointer; len:integer):boolean; // читает данные из сокета, генерирует ошибку при неудаче // возвращает истину при получении данных, ложь - если данных нет var count:integer; begin result:=true; while len<>0 do begin writeln(df,'readdata begin, len=',len); close(df);append(df); count:=fprecv(sock,pdata,len,0); writeln(df,'readdata end, count=',count); close(df);append(df); if count<0 then raise Exception.Create('Read data error'); if count=0 then begin raise Exception.Create('Read data end'); result:=false; exit; end; inc(pdata,count); dec(len,count); end; end; procedure getNameValue(var pdata:pbyte;var name,value:ansistring); // читает пару имя-значение из памяти, перемещает указатель var namelen:integer; valuelen:integer; begin if (pdata^<128) then begin namelen:=pdata^; inc(pdata); end else begin namelen:=((pdata[0] and 127)shl 24)+(pdata[1] shl 16)+(pdata[2] shl 8)+pdata[3]; inc(pdata,4); end; if (pdata^<128) then begin valuelen:=pdata^; inc(pdata); end else begin valuelen:=((pdata[0] and 127)shl 24)+(pdata[1] shl 16)+(pdata[2] shl 8)+pdata[3]; inc(pdata,4); end; setlength(name,namelen); move(pdata^,pchar(name)^,namelen); inc(pdata,namelen); setlength(value,valuelen); move(pdata^,pchar(value)^,valuelen); inc(pdata,valuelen); end; procedure work_BEGIN_REQUEST(pBRB:PFCGI_BeginRequestBody); begin writeln (df,'role - ',ntohs(pBRB^.role)); writeln (df,'flags - ',pBRB^.flags); end; procedure work_PARAMS(pPRMS:PByte; len:word); var name,value:ansistring; pend:pbyte; begin pend:=pprms; inc(pend,len); while pprms<>pend do begin getNameValue(pprms,name,value); writeln(df,'namelength - ',length(name),'; name - ',name); writeln(df,'valuelength - ',length(value),'; value - ',value); end; end; procedure work_STDIN(pSTDIN:PByte; len:word); begin writeln(df,'STDIN_DATA:'); if len=0 then abort; // завершение данных от сервера while len<>0 do begin write(df,char(pSTDIN^)); dec(len); inc(pSTDIN); end; end; procedure work(); var header:FCGI_Header; data:array[word]of byte; padding:array[byte]of byte; begin sock:=fpaccept(FCGI_LISTENSOCK_FILENO,nil,nil); writeln(df,'Сокет - ',sock); if sock=-1 then exit; while readdata(sock,@header,sizeof(header)) do begin header.requestID:=ntohs(header.requestID); header.contentLength:=ntohs(header.contentLength); writeln(df,'-----------------'); writeln(df,'Длина заголовка - ',sizeof(header)); writeln (df,'version - ',header.version); writeln (df,'reqtype - ',header.reqtype); writeln (df,'requestID - ',header.requestID); writeln (df,'contentLength - ',header.contentLength); writeln (df,'paddingLength - ',header.paddingLength); readdata(sock,@data,header.contentLength); readdata(sock,@padding,header.paddingLength); case header.reqtype of FCGI_BEGIN_REQUEST: work_BEGIN_REQUEST(@data); FCGI_PARAMS: work_PARAMS(@data,header.contentLength); FCGI_STDIN: work_STDIN(@data,header.contentLength); { FCGI_ABORT_REQUEST = 2, FCGI_END_REQUEST = 3, FCGI_PARAMS = 4, FCGI_STDIN = 5, FCGI_STDOUT = 6, FCGI_STDERR = 7, FCGI_DATA = 8, FCGI_GET_VALUES = 9, FCGI_GET_VALUES_RESULT = 10, FCGI_UNKNOWN_TYPE = 11); } else exit; end; end; end; begin assign(df,'/tmp/debugfile.txt'); rewrite(df); try work(); finally close(df); end; halt(1); end.