mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 18:49:16 +02:00
* Restructured for clarity
git-svn-id: trunk@17088 -
This commit is contained in:
parent
a41260fdf6
commit
92dfe16e9a
@ -21,7 +21,7 @@ unit custfcgi;
|
||||
Interface
|
||||
|
||||
uses
|
||||
Classes,SysUtils, httpdefs,custweb, custcgi, fastcgi;
|
||||
Classes,SysUtils, httpdefs, Sockets, custweb, custcgi, fastcgi;
|
||||
|
||||
Type
|
||||
{ TFCGIRequest }
|
||||
@ -73,6 +73,8 @@ Type
|
||||
Response : TFCgiResponse;
|
||||
end;
|
||||
|
||||
{ TFCgiHandler }
|
||||
|
||||
TFCgiHandler = class(TWebHandler)
|
||||
Private
|
||||
FOnUnknownRecord: TUnknownRecordEvent;
|
||||
@ -85,7 +87,9 @@ Type
|
||||
FPort: integer;
|
||||
function Read_FCGIRecord : PFCGI_Header;
|
||||
protected
|
||||
function WaitForRequest(out ARequest : TRequest; out AResponse : TResponse) : boolean; override;
|
||||
function ProcessRecord(AFCGI_Record: PFCGI_Header; out ARequest: TRequest; out AResponse: TResponse): boolean; virtual;
|
||||
procedure SetupSocket(var IAddress: TInetSockAddr; var AddressLength: tsocklen); virtual;
|
||||
function WaitForRequest(out ARequest : TRequest; out AResponse : TResponse) : boolean; override;
|
||||
procedure EndRequest(ARequest : TRequest;AResponse : TResponse); override;
|
||||
Public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
@ -127,11 +131,11 @@ ResourceString
|
||||
|
||||
Implementation
|
||||
|
||||
uses
|
||||
{$ifdef CGIDEBUG}
|
||||
dbugintf,
|
||||
uses
|
||||
dbugintf;
|
||||
{$endif}
|
||||
Sockets;
|
||||
|
||||
|
||||
{$undef nosignal}
|
||||
|
||||
@ -537,50 +541,83 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFCgiHandler.SetupSocket(var IAddress : TInetSockAddr; Var AddressLength : tsocklen);
|
||||
|
||||
begin
|
||||
AddressLength:=Sizeof(IAddress);
|
||||
Socket := fpsocket(AF_INET,SOCK_STREAM,0);
|
||||
if Socket=-1 then
|
||||
raise EFPWebError.CreateFmt(SNoSocket,[socketerror]);
|
||||
IAddress.sin_family:=AF_INET;
|
||||
IAddress.sin_port:=htons(Port);
|
||||
if FAddress<>'' then
|
||||
Iaddress.sin_addr := StrToHostAddr(FAddress)
|
||||
else
|
||||
IAddress.sin_addr.s_addr:=0;
|
||||
if fpbind(Socket,@IAddress,AddressLength)=-1 then
|
||||
begin
|
||||
CloseSocket(socket);
|
||||
Socket:=0;
|
||||
Terminate;
|
||||
raise Exception.CreateFmt(SBindFailed,[port,socketerror]);
|
||||
end;
|
||||
if fplisten(Socket,1)=-1 then
|
||||
begin
|
||||
CloseSocket(socket);
|
||||
Socket:=0;
|
||||
Terminate;
|
||||
raise Exception.CreateFmt(SListenFailed,[port,socketerror]);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TFCgiHandler.ProcessRecord(AFCGI_Record : PFCGI_Header; out ARequest: TRequest; out AResponse: TResponse): boolean;
|
||||
|
||||
var
|
||||
ARequestID : word;
|
||||
ATempRequest : TFCGIRequest;
|
||||
begin
|
||||
Result:=False;
|
||||
ARequestID:=BEtoN(AFCGI_Record^.requestID);
|
||||
if AFCGI_Record^.reqtype = FCGI_BEGIN_REQUEST then
|
||||
begin
|
||||
if ARequestID>FRequestsAvail then
|
||||
begin
|
||||
inc(FRequestsAvail,10);
|
||||
SetLength(FRequestsArray,FRequestsAvail);
|
||||
end;
|
||||
assert(not assigned(FRequestsArray[ARequestID].Request));
|
||||
assert(not assigned(FRequestsArray[ARequestID].Response));
|
||||
ATempRequest:=TFCGIRequest.Create;
|
||||
ATempRequest.RequestID:=ARequestID;
|
||||
ATempRequest.Handle:=FHandle;
|
||||
ATempRequest.ProtocolOptions:=Self.Protocoloptions;
|
||||
ATempRequest.OnUnknownRecord:=Self.OnUnknownRecord;
|
||||
FRequestsArray[ARequestID].Request := ATempRequest;
|
||||
end;
|
||||
if FRequestsArray[ARequestID].Request.ProcessFCGIRecord(AFCGI_Record) then
|
||||
begin
|
||||
ARequest:=FRequestsArray[ARequestID].Request;
|
||||
FRequestsArray[ARequestID].Response := TFCGIResponse.Create(ARequest);
|
||||
FRequestsArray[ARequestID].Response.ProtocolOptions:=Self.ProtocolOptions;
|
||||
AResponse:=FRequestsArray[ARequestID].Response;
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TFCgiHandler.WaitForRequest(out ARequest: TRequest; out AResponse: TResponse): boolean;
|
||||
|
||||
var
|
||||
IAddress : TInetSockAddr;
|
||||
AddressLength : tsocklen;
|
||||
ARequestID : word;
|
||||
AFCGI_Record : PFCGI_Header;
|
||||
ATempRequest : TFCGIRequest;
|
||||
|
||||
begin
|
||||
Result := False;
|
||||
AddressLength:=Sizeof(IAddress);
|
||||
|
||||
if Socket=0 then
|
||||
begin
|
||||
if Port<>0 then
|
||||
begin
|
||||
Socket := fpsocket(AF_INET,SOCK_STREAM,0);
|
||||
if Socket=-1 then
|
||||
raise EFPWebError.CreateFmt(SNoSocket,[socketerror]);
|
||||
IAddress.sin_family:=AF_INET;
|
||||
IAddress.sin_port:=htons(Port);
|
||||
if FAddress<>'' then
|
||||
Iaddress.sin_addr := StrToHostAddr(FAddress)
|
||||
else
|
||||
IAddress.sin_addr.s_addr:=0;
|
||||
if fpbind(Socket,@IAddress,AddressLength)=-1 then
|
||||
begin
|
||||
CloseSocket(socket);
|
||||
Socket:=0;
|
||||
Terminate;
|
||||
raise Exception.CreateFmt(SBindFailed,[port,socketerror]);
|
||||
end;
|
||||
if fplisten(Socket,1)=-1 then
|
||||
begin
|
||||
CloseSocket(socket);
|
||||
Socket:=0;
|
||||
Terminate;
|
||||
raise Exception.CreateFmt(SListenFailed,[port,socketerror]);
|
||||
end;
|
||||
end
|
||||
SetupSocket(IAddress,AddressLength)
|
||||
else
|
||||
Socket:=StdInputHandle;
|
||||
end;
|
||||
|
||||
if FHandle=THandle(-1) then
|
||||
begin
|
||||
FHandle:=fpaccept(Socket,psockaddr(@IAddress),@AddressLength);
|
||||
@ -590,43 +627,16 @@ begin
|
||||
raise Exception.CreateFmt(SNoInputHandle,[socketerror]);
|
||||
end;
|
||||
end;
|
||||
|
||||
repeat
|
||||
AFCGI_Record:=Read_FCGIRecord;
|
||||
if assigned(AFCGI_Record) then
|
||||
AFCGI_Record:=Read_FCGIRecord;
|
||||
if assigned(AFCGI_Record) then
|
||||
try
|
||||
ARequestID:=BEtoN(AFCGI_Record^.requestID);
|
||||
if AFCGI_Record^.reqtype = FCGI_BEGIN_REQUEST then
|
||||
begin
|
||||
if ARequestID>FRequestsAvail then
|
||||
begin
|
||||
inc(FRequestsAvail,10);
|
||||
SetLength(FRequestsArray,FRequestsAvail);
|
||||
end;
|
||||
assert(not assigned(FRequestsArray[ARequestID].Request));
|
||||
assert(not assigned(FRequestsArray[ARequestID].Response));
|
||||
|
||||
ATempRequest:=TFCGIRequest.Create;
|
||||
ATempRequest.RequestID:=ARequestID;
|
||||
ATempRequest.Handle:=FHandle;
|
||||
ATempRequest.ProtocolOptions:=Self.Protocoloptions;
|
||||
ATempRequest.OnUnknownRecord:=Self.OnUnknownRecord;
|
||||
FRequestsArray[ARequestID].Request := ATempRequest;
|
||||
end;
|
||||
if FRequestsArray[ARequestID].Request.ProcessFCGIRecord(AFCGI_Record) then
|
||||
begin
|
||||
ARequest:=FRequestsArray[ARequestID].Request;
|
||||
FRequestsArray[ARequestID].Response := TFCGIResponse.Create(ARequest);
|
||||
FRequestsArray[ARequestID].Response.ProtocolOptions:=Self.ProtocolOptions;
|
||||
AResponse:=FRequestsArray[ARequestID].Response;
|
||||
Result := True;
|
||||
Break;
|
||||
end;
|
||||
Result:=ProcessRecord(AFCGI_Record,ARequest,AResponse);
|
||||
Finally
|
||||
FreeMem(AFCGI_Record);
|
||||
AFCGI_Record:=Nil;
|
||||
end;
|
||||
until (1<>1);
|
||||
until Result;
|
||||
end;
|
||||
|
||||
{ TCustomFCgiApplication }
|
||||
|
Loading…
Reference in New Issue
Block a user