📄 fcgiapp.c
字号:
ErrorReturn: streamCount = -1; NormalReturn: if(auxBuffPtr != NULL) free(auxBuffPtr); return streamCount;}/* * Copy n characters from *srcPtr to *destPtr, then increment * both *srcPtr and *destPtr by n. */static void CopyAndAdvance(char **destPtr, char **srcPtr, int n){ char *dest = *destPtr; char *src = *srcPtr; int i; for (i = 0; i < n; i++) *dest++ = *src++; *destPtr = dest; *srcPtr = src;}/* *---------------------------------------------------------------------- * * FCGX_FFlush -- * * Flushes any buffered output. * * Server-push is a legitimate application of FCGX_FFlush. * Otherwise, FCGX_FFlush is not very useful, since FCGX_Accept * does it implicitly. FCGX_FFlush may reduce performance * by increasing the total number of operating system calls * the application makes. * * Results: * EOF (-1) if an error occurred. * *---------------------------------------------------------------------- */int FCGX_FFlush(FCGX_Stream *stream){ if(stream->isClosed || stream->isReader) return 0; stream->emptyBuffProc(stream, FALSE); return (stream->isClosed) ? -1 : 0;}/* *---------------------------------------------------------------------- * * FCGX_FClose -- * * Performs FCGX_FFlush and closes the stream. * * This is not a very useful operation, since FCGX_Accept * does it implicitly. Closing the out stream before the * err stream results in an extra write if there's nothing * in the err stream, and therefore reduces performance. * * Results: * EOF (-1) if an error occurred. * *---------------------------------------------------------------------- */int FCGX_FClose(FCGX_Stream *stream){ if (stream == NULL) return 0; if(!stream->wasFCloseCalled) { if(!stream->isReader) { stream->emptyBuffProc(stream, TRUE); } stream->wasFCloseCalled = TRUE; stream->isClosed = TRUE; if(stream->isReader) { stream->wrNext = stream->stop = stream->rdNext; } else { stream->rdNext = stream->stop = stream->wrNext; } } return (stream->FCGI_errno == 0) ? 0 : EOF;}/* *---------------------------------------------------------------------- * * SetError -- * * An error has occurred; save the error code in the stream * for diagnostic purposes and set the stream state so that * reads return EOF and writes have no effect. * *---------------------------------------------------------------------- */static void SetError(FCGX_Stream *stream, int FCGI_errno){ /* * Preserve only the first error. */ if(stream->FCGI_errno == 0) { stream->FCGI_errno = FCGI_errno; } stream->isClosed = TRUE;}/* *---------------------------------------------------------------------- * * FCGX_GetError -- * * Return the stream error code. 0 means no error, > 0 * is an errno(2) error, < 0 is an FCGX_errno error. * *---------------------------------------------------------------------- */int FCGX_GetError(FCGX_Stream *stream) { return stream->FCGI_errno;}/* *---------------------------------------------------------------------- * * FCGX_ClearError -- * * Clear the stream error code and end-of-file indication. * *---------------------------------------------------------------------- */void FCGX_ClearError(FCGX_Stream *stream) { stream->FCGI_errno = 0; /* * stream->isClosed = FALSE; * XXX: should clear isClosed but work is needed to make it safe * to do so. For example, if an application calls FClose, gets * an I/O error on the write, calls ClearError and retries * the FClose, FClose (really EmptyBuffProc) will write a second * EOF record. If an application calls PutChar instead of FClose * after the ClearError, the application will write more data. * The stream's state must discriminate between various states * of the stream that are now all lumped under isClosed. */}/* *====================================================================== * Parameters *====================================================================== *//* * A vector of pointers representing the parameters received * by a FastCGI application server, with the vector's length * and last valid element so adding new parameters is efficient. */typedef struct Params { FCGX_ParamArray vec; /* vector of strings */ int length; /* number of string vec can hold */ char **cur; /* current item in vec; *cur == NULL */} Params;typedef Params *ParamsPtr;/* *---------------------------------------------------------------------- * * NewParams -- * * Creates a new Params structure. * * Results: * Pointer to the new structure. * *---------------------------------------------------------------------- */static ParamsPtr NewParams(int length){ ParamsPtr result; result = (Params *)Malloc(sizeof(Params)); result->vec = (char **)Malloc(length * sizeof(char *)); result->length = length; result->cur = result->vec; *result->cur = NULL; return result;}/* *---------------------------------------------------------------------- * * FreeParams -- * * Frees a Params structure and all the parameters it contains. * * Side effects: * env becomes invalid. * *---------------------------------------------------------------------- */static void FreeParams(ParamsPtr *paramsPtrPtr){ ParamsPtr paramsPtr = *paramsPtrPtr; char **p; if(paramsPtr == NULL) { return; } for (p = paramsPtr->vec; p < paramsPtr->cur; p++) { free(*p); } free(paramsPtr->vec); free(paramsPtr); *paramsPtrPtr = NULL;}/* *---------------------------------------------------------------------- * * PutParam -- * * Add a name/value pair to a Params structure. * * Results: * None. * * Side effects: * Parameters structure updated. * *---------------------------------------------------------------------- */static void PutParam(ParamsPtr paramsPtr, char *nameValue){ int size; *paramsPtr->cur++ = nameValue; size = paramsPtr->cur - paramsPtr->vec; if(size >= paramsPtr->length) { paramsPtr->length *= 2; paramsPtr->vec = (FCGX_ParamArray)realloc(paramsPtr->vec, paramsPtr->length * sizeof(char *)); paramsPtr->cur = paramsPtr->vec + size; } *paramsPtr->cur = NULL;}/* *---------------------------------------------------------------------- * * FCGX_GetParam -- obtain value of FCGI parameter in environment * * * Results: * Value bound to name, NULL if name not present in the * environment envp. Caller must not mutate the result * or retain it past the end of this request. * *---------------------------------------------------------------------- */char *FCGX_GetParam(const char *name, FCGX_ParamArray envp){ int len; char **p; if (name == NULL || envp == NULL) return NULL; len = strlen(name); for (p = envp; *p; ++p) { if((strncmp(name, *p, len) == 0) && ((*p)[len] == '=')) { return *p+len+1; } } return NULL;}/* *---------------------------------------------------------------------- * * Start of FastCGI-specific code * *---------------------------------------------------------------------- *//* *---------------------------------------------------------------------- * * ReadParams -- * * Reads FastCGI name-value pairs from stream until EOF. Converts * each pair to name=value format and adds it to Params structure. * *---------------------------------------------------------------------- */static int ReadParams(Params *paramsPtr, FCGX_Stream *stream){ int nameLen, valueLen; unsigned char lenBuff[3]; char *nameValue; while((nameLen = FCGX_GetChar(stream)) != EOF) { /* * Read name length (one or four bytes) and value length * (one or four bytes) from stream. */ if((nameLen & 0x80) != 0) { if(FCGX_GetStr((char *) &lenBuff[0], 3, stream) != 3) { SetError(stream, FCGX_PARAMS_ERROR); return -1; } nameLen = ((nameLen & 0x7f) << 24) + (lenBuff[0] << 16) + (lenBuff[1] << 8) + lenBuff[2]; } if((valueLen = FCGX_GetChar(stream)) == EOF) { SetError(stream, FCGX_PARAMS_ERROR); return -1; } if((valueLen & 0x80) != 0) { if(FCGX_GetStr((char *) &lenBuff[0], 3, stream) != 3) { SetError(stream, FCGX_PARAMS_ERROR); return -1; } valueLen = ((valueLen & 0x7f) << 24) + (lenBuff[0] << 16) + (lenBuff[1] << 8) + lenBuff[2]; } /* * nameLen and valueLen are now valid; read the name and value * from stream and construct a standard environment entry. */ nameValue = (char *)Malloc(nameLen + valueLen + 2); if(FCGX_GetStr(nameValue, nameLen, stream) != nameLen) { SetError(stream, FCGX_PARAMS_ERROR); free(nameValue); return -1; } *(nameValue + nameLen) = '='; if(FCGX_GetStr(nameValue + nameLen + 1, valueLen, stream) != valueLen) { SetError(stream, FCGX_PARAMS_ERROR); free(nameValue); return -1; } *(nameValue + nameLen + valueLen + 1) = '\0'; PutParam(paramsPtr, nameValue); } return 0;}/* *---------------------------------------------------------------------- * * MakeHeader -- * * Constructs an FCGI_Header struct. * *---------------------------------------------------------------------- */static FCGI_Header MakeHeader( int type, int requestId, int contentLength, int paddingLength){ FCGI_Header header; ASSERT(contentLength >= 0 && contentLength <= FCGI_MAX_LENGTH); ASSERT(paddingLength >= 0 && paddingLength <= 0xff); header.version = FCGI_VERSION_1; header.type = (unsigned char) type; header.requestIdB1 = (unsigned char) ((requestId >> 8) & 0xff); header.requestIdB0 = (unsigned char) ((requestId ) & 0xff); header.contentLengthB1 = (unsigned char) ((contentLength >> 8) & 0xff); header.contentLengthB0 = (unsigned char) ((contentLength ) & 0xff); header.paddingLength = (unsigned char) paddingLength; header.reserved = 0; return header;}/* *---------------------------------------------------------------------- * * MakeEndRequestBody -- * * Constructs an FCGI_EndRequestBody struct. * *---------------------------------------------------------------------- */static FCGI_EndRequestBody MakeEndRequestBody( int appStatus, int protocolStatus){ FCGI_EndRequestBody body; body.appStatusB3 = (unsigned char) ((appStatus >> 24) & 0xff); body.appStatusB2 = (unsigned char) ((appStatus >> 16) & 0xff); body.appStatusB1 = (unsigned char) ((appStatus >> 8) & 0xff); body.appStatusB0 = (unsigned char) ((appStatus ) & 0xff); body.protocolStatus = (unsigned char) protocolStatus; memset(body.reserved, 0, sizeof(body.reserved)); return body;}/* *---------------------------------------------------------------------- * * MakeUnknownTypeBody -- * * Constructs an FCGI_MakeUnknownTypeBody struct. * *---------------------------------------------------------------------- */static FCGI_UnknownTypeBody MakeUnknownTypeBody( int type){ FCGI_UnknownTypeBody body; body.type = (unsigned char) type; memset(body.reserved, 0, sizeof(body.reserved)); return body;}/* *---------------------------------------------------------------------- * * AlignInt8 -- * * Returns the smallest integer greater than or equal to n * that's a multiple of 8. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -