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

📄 fcgiapp.c

📁 FastCGI,语言无关的、可伸缩架构的CGI开放扩展
💻 C
📖 第 1 页 / 共 5 页
字号:
        if(headerLen < sizeof(header)) {            continue;	};        headerLen = 0;        /*         * Interpret header.  eorStop prevents ProcessHeader from reading         * past the end-of-record when using stream to read content.         */        data->eorStop = TRUE;        stream->stop = stream->rdNext;        status = ProcessHeader(header, stream);        data->eorStop = FALSE;        stream->isClosed = FALSE;        switch(status) {            case STREAM_RECORD:                /*                 * If this stream record header marked the end of stream                 * data deliver EOF to the stream client, otherwise loop                 * and deliver data.                 *                 * XXX: If this is final stream and                 * stream->rdNext != data->buffStop, buffered                 * data is next request (server pipelining)?                 */                if(data->contentLen == 0) {                    stream->wrNext = stream->stop = stream->rdNext;                    stream->isClosed = TRUE;                    return;	        }                break;	    case SKIP:                data->skip = TRUE;                break;            case BEGIN_RECORD:                /*                 * If this header marked the beginning of a new                 * request, return role information to caller.                 */                return;                break;            case MGMT_RECORD:                break;            default:                ASSERT(status < 0);                SetError(stream, status);                return;                break;	}    }}/* *---------------------------------------------------------------------- * * NewStream -- * *      Creates a stream to read or write from an open ipcFd. *      The stream performs reads/writes of up to bufflen bytes. * *---------------------------------------------------------------------- */static FCGX_Stream *NewStream(        FCGX_Request *reqDataPtr, int bufflen, int isReader, int streamType){    /*     * XXX: It would be a lot cleaner to have a NewStream that only     * knows about the type FCGX_Stream, with all other     * necessary data passed in.  It appears that not just     * data and the two procs are needed for initializing stream,     * but also data->buff and data->buffStop.  This has implications     * for procs that want to swap buffers, too.     */    FCGX_Stream *stream = (FCGX_Stream *)Malloc(sizeof(FCGX_Stream));    FCGX_Stream_Data *data = (FCGX_Stream_Data *)Malloc(sizeof(FCGX_Stream_Data));    data->reqDataPtr = reqDataPtr;    bufflen = AlignInt8(min(max(bufflen, 32), FCGI_MAX_LENGTH + 1));    data->bufflen = bufflen;    data->mBuff = (unsigned char *)Malloc(bufflen);    data->buff = AlignPtr8(data->mBuff);    if(data->buff != data->mBuff) {        data->bufflen -= 8;    }    if(isReader) {        data->buffStop = data->buff;    } else {        data->buffStop = data->buff + data->bufflen;    }    data->type = streamType;    data->eorStop = FALSE;    data->skip = FALSE;    data->contentLen = 0;    data->paddingLen = 0;    data->isAnythingWritten = FALSE;    data->rawWrite = FALSE;    stream->data = data;    stream->isReader = isReader;    stream->isClosed = FALSE;    stream->wasFCloseCalled = FALSE;    stream->FCGI_errno = 0;    if(isReader) {        stream->fillBuffProc = FillBuffProc;        stream->emptyBuffProc = NULL;        stream->rdNext = data->buff;        stream->stop = stream->rdNext;        stream->stopUnget = data->buff;        stream->wrNext = stream->stop;    } else {        stream->fillBuffProc = NULL;        stream->emptyBuffProc = EmptyBuffProc;        stream->wrNext = data->buff + sizeof(FCGI_Header);        stream->stop = data->buffStop;        stream->stopUnget = NULL;        stream->rdNext = stream->stop;    }    return stream;}/* *---------------------------------------------------------------------- * * FCGX_FreeStream -- * *      Frees all storage allocated when *streamPtr was created, *      and nulls out *streamPtr. * *---------------------------------------------------------------------- */void FCGX_FreeStream(FCGX_Stream **streamPtr){    FCGX_Stream *stream = *streamPtr;    FCGX_Stream_Data *data;    if(stream == NULL) {        return;    }    data = (FCGX_Stream_Data *)stream->data;    data->reqDataPtr = NULL;    free(data->mBuff);    free(data);    free(stream);    *streamPtr = NULL;}/* *---------------------------------------------------------------------- * * SetReaderType -- * *      Re-initializes the stream to read data of the specified type. * *---------------------------------------------------------------------- */static FCGX_Stream *SetReaderType(FCGX_Stream *stream, int streamType){    FCGX_Stream_Data *data = (FCGX_Stream_Data *)stream->data;    ASSERT(stream->isReader);    data->type = streamType;    data->eorStop = FALSE;    data->skip = FALSE;    data->contentLen = 0;    data->paddingLen = 0;    stream->wrNext = stream->stop = stream->rdNext;    stream->isClosed = FALSE;    return stream;}/* *---------------------------------------------------------------------- * * NewReader -- * *      Creates a stream to read streamType records for the given *      request.  The stream performs OS reads of up to bufflen bytes. * *---------------------------------------------------------------------- */static FCGX_Stream *NewReader(FCGX_Request *reqDataPtr, int bufflen, int streamType){    return NewStream(reqDataPtr, bufflen, TRUE, streamType);}/* *---------------------------------------------------------------------- * * NewWriter -- * *      Creates a stream to write streamType FastCGI records, using *      the ipcFd and RequestId contained in *reqDataPtr. *      The stream performs OS writes of up to bufflen bytes. * *---------------------------------------------------------------------- */static FCGX_Stream *NewWriter(FCGX_Request *reqDataPtr, int bufflen, int streamType){    return NewStream(reqDataPtr, bufflen, FALSE, streamType);}/* *---------------------------------------------------------------------- * * FCGX_CreateWriter -- * *      Creates a stream to write streamType FastCGI records, using *      the given ipcFd and request Id.  This function is provided *      for use by cgi-fcgi.  In order to be defensive against misuse, *      this function leaks a little storage; cgi-fcgi doesn't care. * *---------------------------------------------------------------------- */FCGX_Stream *FCGX_CreateWriter(        int ipcFd,        int requestId,        int bufflen,        int streamType){    FCGX_Request *reqDataPtr = (FCGX_Request *)Malloc(sizeof(FCGX_Request));    reqDataPtr->ipcFd = ipcFd;    reqDataPtr->requestId = requestId;    /*     * Suppress writing an FCGI_END_REQUEST record.     */    reqDataPtr->nWriters = 2;    return NewWriter(reqDataPtr, bufflen, streamType);}/* *====================================================================== * Control *====================================================================== *//* *---------------------------------------------------------------------- * * FCGX_IsCGI -- * *      This routine determines if the process is running as a CGI or *      FastCGI process.  The distinction is made by determining whether *      FCGI_LISTENSOCK_FILENO is a listener ipcFd or the end of a *      pipe (ie. standard in). * * Results: *      TRUE if the process is a CGI process, FALSE if FastCGI. * *---------------------------------------------------------------------- */int FCGX_IsCGI(void){    if (isFastCGI != -1) {        return !isFastCGI;    }    if (!libInitialized) {        int rc = FCGX_Init();        if (rc) {            /* exit() isn't great, but hey */            exit((rc < 0) ? rc : -rc);        }    }    isFastCGI = OS_IsFcgi(FCGI_LISTENSOCK_FILENO);    return !isFastCGI;}/* *---------------------------------------------------------------------- * * FCGX_Finish -- * *      Finishes the current request from the HTTP server. * * Side effects: * *      Finishes the request accepted by (and frees any *      storage allocated by) the previous call to FCGX_Accept. * *      DO NOT retain pointers to the envp array or any strings *      contained in it (e.g. to the result of calling FCGX_GetParam), *      since these will be freed by the next call to FCGX_Finish *      or FCGX_Accept. * *---------------------------------------------------------------------- */void FCGX_Finish(void){    FCGX_Finish_r(&the_request);}/* *---------------------------------------------------------------------- * * FCGX_Finish_r -- * *      Finishes the current request from the HTTP server. * * Side effects: * *      Finishes the request accepted by (and frees any *      storage allocated by) the previous call to FCGX_Accept. * *      DO NOT retain pointers to the envp array or any strings *      contained in it (e.g. to the result of calling FCGX_GetParam), *      since these will be freed by the next call to FCGX_Finish *      or FCGX_Accept. * *---------------------------------------------------------------------- */void FCGX_Finish_r(FCGX_Request *reqDataPtr){    int close;    if (reqDataPtr == NULL) {        return;    }    close = !reqDataPtr->keepConnection;    /* This should probably use a 'status' member instead of 'in' */    if (reqDataPtr->in) {        close |= FCGX_FClose(reqDataPtr->err);        close |= FCGX_FClose(reqDataPtr->out);	close |= FCGX_GetError(reqDataPtr->in);    }    FCGX_Free(reqDataPtr, close);}void FCGX_Free(FCGX_Request * request, int close){    if (request == NULL)         return;    FCGX_FreeStream(&request->in);    FCGX_FreeStream(&request->out);    FCGX_FreeStream(&request->err);    FreeParams(&request->paramsPtr);    if (close) {        OS_IpcClose(request->ipcFd);        request->ipcFd = -1;    }}int FCGX_OpenSocket(const char *path, int backlog){    int rc = OS_CreateLocalIpcFd(path, backlog);    if (rc == FCGI_LISTENSOCK_FILENO && isFastCGI == 0) {        /* XXX probably need to call OS_LibInit() again for Win */        isFastCGI = 1;    }    return rc;}int FCGX_InitRequest(FCGX_Request *request, int sock, int flags){    memset(request, 0, sizeof(FCGX_Request));    /* @@@ Should check that sock is open and listening */    request->listen_sock = sock;    /* @@@ Should validate against "known" flags */    request->flags = flags;    request->ipcFd = -1;    return 0;}/* *---------------------------------------------------------------------- * * FCGX_Init -- * *      Initilize the FCGX library.  This is called by FCGX_Accept() *      but must be called by the user when using FCGX_Accept_r(). * * Results: *	    0 for successful call. * *---------------------------------------------------------------------- */int FCGX_Init(void){    char *p;    if (libInitialized) {        return 0;    }    FCGX_InitRequest(&the_request, FCGI_LISTENSOCK_FILENO, 0);    if (OS_LibInit(NULL) == -1) {        return OS_Errno ? OS_Errno : -9997;    }    p = getenv("FCGI_WEB_SERVER_ADDRS");    webServerAddressList = p ? StringCopy(p) : NULL;    libInitialized = 1;    return 0;}/* *---------------------------------------------------------------------- * * FCGX_Accept -- * *      Accepts a new request from the HTTP server. * * Results: *	0 for successful call, -1 for error. * * Side effects: * *      Finishes the request accepted by (and frees any *      storage allocated by) the previous call to FCGX_Accept. *      Creates input, output, and error streams and *      assigns them to *in, *out, a

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -