diff options
| author | michael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2011-03-07 21:40:29 +0000 |
|---|---|---|
| committer | michael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2011-03-07 21:40:29 +0000 |
| commit | ed8557ec9aa31810231ee85e1f4f55d457380c9e (patch) | |
| tree | 4c2893d6e9a160f0d03cf27d120f38f6c6dd6716 /packages/fcl-web | |
| parent | 544193b2b80c2acbc97d5c1ab498f1fb33d546ee (diff) | |
| download | fpc-ed8557ec9aa31810231ee85e1f4f55d457380c9e.tar.gz | |
* Restructured for clarity
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@17088 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/fcl-web')
| -rw-r--r-- | packages/fcl-web/src/base/custfcgi.pp | 146 |
1 files changed, 78 insertions, 68 deletions
diff --git a/packages/fcl-web/src/base/custfcgi.pp b/packages/fcl-web/src/base/custfcgi.pp index 535de2f403..540dd44d9a 100644 --- a/packages/fcl-web/src/base/custfcgi.pp +++ b/packages/fcl-web/src/base/custfcgi.pp @@ -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 } |
