summaryrefslogtreecommitdiff
path: root/packages/fcl-web/src
diff options
context:
space:
mode:
authormichael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2>2010-09-03 08:18:41 +0000
committermichael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2>2010-09-03 08:18:41 +0000
commit5b77a90936b563755d75e3a5d4ed1bd748210551 (patch)
tree762ba43da1185491cec85f20a95215129d214963 /packages/fcl-web/src
parentddbf639519e67dbcffb2eeaaccf6ae57928d4bed (diff)
downloadfpc-5b77a90936b563755d75e3a5d4ed1bd748210551.tar.gz
* Better error handling when reading from socket.
* Handle case where (windows) tcp/ip stack returns only partial number of bytes git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@15940 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/fcl-web/src')
-rw-r--r--packages/fcl-web/src/base/custfcgi.pp75
1 files changed, 51 insertions, 24 deletions
diff --git a/packages/fcl-web/src/base/custfcgi.pp b/packages/fcl-web/src/base/custfcgi.pp
index f2b34e1dda..2f9ce950ec 100644
--- a/packages/fcl-web/src/base/custfcgi.pp
+++ b/packages/fcl-web/src/base/custfcgi.pp
@@ -120,10 +120,12 @@ Type
end;
ResourceString
- SNoInputHandle = 'Failed to open input-handle passed from server. Socket Error: %d';
- SNoSocket = 'Failed to open socket. Socket Error: %d';
- SBindFailed = 'Failed to bind to port %d. Socket Error: %d';
- SListenFailed = 'Failed to listen to port %d. Socket Error: %d';
+ SNoInputHandle = 'Failed to open input-handle passed from server. Socket Error: %d';
+ SNoSocket = 'Failed to open socket. Socket Error: %d';
+ SBindFailed = 'Failed to bind to port %d. Socket Error: %d';
+ SListenFailed = 'Failed to listen to port %d. Socket Error: %d';
+ SErrReadingSocket = 'Failed to read data from socket. Error: %d';
+ SErrReadingHeader = 'Failed to read FastCGI header. Read only %d bytes';
Implementation
@@ -433,44 +435,69 @@ end;
function TFCgiHandler.Read_FCGIRecord : PFCGI_Header;
+ function ReadBytes(ReadBuf: Pointer; ByteAmount : Word) : Integer;
+
+ Var
+ P : PByte;
+ Count : Integer;
+
+ begin
+ Result := 0;
+ P:=ReadBuf;
+ if (ByteAmount=0) then exit;
+ Repeat
+ Count:=sockets.fpRecv(FHandle, P, ByteAmount, NoSignalAttr);
+ If (Count>0) then
+ begin
+ Dec(ByteAmount,Count);
+ P:=P+Count;
+ Inc(Result,Count);
+ end
+ else if (Count<0) then
+ Raise HTTPError.CreateFmt(SErrReadingSocket,[Count]);
+ until (ByteAmount=0) or (Count=0);
+ end;
+
var Header : FCGI_Header;
- BytesRead : integer;
+ {I,}BytesRead : integer;
ContentLength : word;
PaddingLength : byte;
ResRecord : pointer;
ReadBuf : pointer;
+ s : string;
- function ReadBytes(ByteAmount : Word) : boolean;
- begin
- result := False;
- if ByteAmount>0 then
- begin
- BytesRead := sockets.fpRecv(FHandle, ReadBuf, ByteAmount, NoSignalAttr);
- if BytesRead<>ByteAmount then
- begin
-// SendDebug('FCGIRecord incomplete');
-// SendDebug('BytesRead: '+inttostr(BytesRead)+', expected: '+inttostr(ByteAmount));
- exit;
- end
- else
- Result := True;
- end;
- end;
begin
Result := Nil;
ResRecord:=Nil;
ReadBuf:=@Header;
- if not ReadBytes(Sizeof(Header)) then exit;
+ BytesRead:=ReadBytes(ReadBuf,Sizeof(Header));
+ If (BytesRead<>Sizeof(Header)) then
+ Raise HTTPError.CreateFmt(SErrReadingHeader,[BytesRead]);
ContentLength:=BetoN(Header.contentLength);
PaddingLength:=Header.paddingLength;
Getmem(ResRecord,BytesRead+ContentLength+PaddingLength);
PFCGI_Header(ResRecord)^:=Header;
ReadBuf:=ResRecord+BytesRead;
- ReadBytes(ContentLength);
+ BytesRead:=ReadBytes(ReadBuf,ContentLength);
ReadBuf:=ReadBuf+BytesRead;
- ReadBytes(PaddingLength);
+ BytesRead:=ReadBytes(ReadBuf,PaddingLength);
Result := ResRecord;
+{
+ Writeln('Dumping record ', Sizeof(Header),',',Contentlength,',',PaddingLength);
+ For I:=0 to Sizeof(Header)+ContentLength+PaddingLength-1 do
+ begin
+ Write(Format('%:3d ',[PByte(ResRecord)[i]]));
+ If PByte(ResRecord)[i]>30 then
+ S:=S+char(PByte(ResRecord)[i]);
+ if (I mod 16) = 0 then
+ begin
+ writeln(' ',S);
+ S:='';
+ end;
+ end;
+ Writeln(' ',S)
+}
end;
function TFCgiHandler.WaitForRequest(out ARequest: TRequest; out AResponse: TResponse): boolean;