#include #include "RecordReader.h" #include "fastcgi.h" FCGI::RecordReader::RecordReader() : pBuffer(0), iBuffer(0), nPayload(0), iRecord(0), nPadding(0) { pBuffer = new char[MAX_RECORD_SIZE]; } FCGI::RecordReader::~RecordReader() { delete pBuffer; } bool FCGI::RecordReader::onRead(SOCKET socket) { int nSpace = MAX_RECORD_SIZE - nPayload; int nRead = ::recv(socket,pBuffer + nPayload,nSpace,0); if (nRead < 0) { return (EWOULDBLOCK == errno) || (EAGAIN == errno); } nPayload += nRead; for (;;) { int n = nPayload - iRecord; if (n < 8) { memcpy(pBuffer,pBuffer + iRecord,n); iRecord = iBuffer = 0; nPayload = n; break; } // Are we at the beginning of the record? if (iRecord == iBuffer) { char* p = pBuffer + iRecord; int iVersion = 255 & *p++; if (FCGI_VERSION_1 != iVersion) { return false; // We cannot handle this conversation. } pRecordHandler->iType = 255 & *p++; int v = (255 & *p++) << 8; pRecordHandler->idRequest = v | (255 & *p++); v = (255 & *p++) << 8; pRecordHandler->nLength = v | (255 & *p++); nPadding = 255 & *p++; ++p; // reserved iBuffer = (int) (p - pBuffer); } // Do we have the entire record? if (nPayload < (iRecord + 8 + pRecordHandler->nLength + nPadding)) { int n = nPayload - iRecord; memcpy(pBuffer,pBuffer + iRecord,n); iRecord = iBuffer = 0; nPayload = n; break; } // We now have the entire FCGI record. if (!pRecordHandler->onRecord(pBuffer + iRecord + 8)) { return false; } iRecord += 8 + pRecordHandler->nLength; // Is there anything left over after the record? if (iRecord == nPayload) { iBuffer = iRecord = nPayload = 0; break; } } return true; }