⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fcgiapp.c

📁 FastCGI,语言无关的、可伸缩架构的CGI开放扩展
💻 C
📖 第 1 页 / 共 5 页
字号:
  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 + -