Example #1
0
int FCGI_ferror(FCGI_FILE *fp)
{
    if(fp->stdio_stream) {
        return ferror(fp->stdio_stream);
    } else if(fp->fcgx_stream) {
        return FCGX_GetError(fp->fcgx_stream);
    }
    return -1;
}
Example #2
0
/* Returns the number of bytes read, or -1 on error. */
static int readContentData(HTTPRequest *req, void *buffer, int dataSize, int mustFill)
{
   WOLog (WO_INFO, "data size: %d", dataSize );
   //int n = fread(buffer, 1, dataSize, stdin);
   int n = FCGX_GetStr(buffer, dataSize, in);
   if (n != dataSize) {
      //int err = ferror(stdin);
	  int err = FCGX_GetError(in);
      if (err)
         WOLog(WO_ERR,"Error getting content data: %s (%d)", strerror(errno), err);
   }
/*	*((char*)buffer+dataSize) = '\0';
	 WOLog ( WO_INFO, "buffer: %s", (char *)buffer );*/
   return n == dataSize ? n : -1;
}
int
FastcgiRequest::write(const char *buf, int size) {
    int num = FCGX_PutStr(buf, size, fcgiRequest_.out);
    if (-1 == num) {
        std::stringstream str;
        int error = FCGX_GetError(fcgiRequest_.out);
        if (error > 0) {
            char buffer[256];
            str << "Cannot write data to fastcgi socket: " <<
                strerror_r(error, buffer, sizeof(buffer)) << ". ";
        }
        else {
            str << "FastCGI error. ";
        }
        generateRequestInfo(request_.get(), str);
        throw std::runtime_error(str.str());
    }
    return num;
}
Example #4
0
/*
 *----------------------------------------------------------------------
 *
 * 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);
}
Example #5
0
/*
 *----------------------------------------------------------------------
 *
 * ProcessManagementRecord --
 *
 *      Reads and responds to a management record.  The only type of
 *      management record this library understands is FCGI_GET_VALUES.
 *      The only variables that this library's FCGI_GET_VALUES
 *      understands are FCGI_MAX_CONNS, FCGI_MAX_REQS, and FCGI_MPXS_CONNS.
 *      Ignore other FCGI_GET_VALUES variables; respond to other
 *      management records with a FCGI_UNKNOWN_TYPE record.
 *
 *----------------------------------------------------------------------
 */
static int ProcessManagementRecord(int type, FCGX_Stream * stream)
{
	FCGX_Stream_Data *data = (FCGX_Stream_Data *) stream->data;
	ParamsPtr paramsPtr = NewParams(3);
	char **pPtr;
	char response[64];	/* 64 = 8 + 3*(1+1+14+1)* + padding */
	char *responseP = &response[FCGI_HEADER_LEN];
	char *name, value = '\0';
	int len, paddedLen;
	if (type == FCGI_GET_VALUES) {
		ReadParams(paramsPtr, stream);
		if ((FCGX_GetError(stream) != 0) || (data->contentLen != 0)) {
			FreeParams(&paramsPtr);
			return FCGX_PROTOCOL_ERROR;
		}
		for (pPtr = paramsPtr->vec; pPtr < paramsPtr->cur; pPtr++) {
			name = *pPtr;
			*(strchr(name, '=')) = '\0';
			if (strcmp(name, FCGI_MAX_CONNS) == 0) {
				value = '1';
			} else if (strcmp(name, FCGI_MAX_REQS) == 0) {
				value = '1';
			} else if (strcmp(name, FCGI_MPXS_CONNS) == 0) {
				value = '0';
			} else {
				name = NULL;
			}
			if (name != NULL) {
#include <fmt.h>
				len = strlen(name);
				responseP[0] = (char)len;
				responseP[1] = (char)1;
				fmt_str(responseP + 2, name);
				responseP[2 + len] = value;
				responseP[3 + len] = '\0';
//                sprintf(responseP, "%c%c%s%c", len, 1, name, value);
				responseP += len + 3;
			}
		}
		len = responseP - &response[FCGI_HEADER_LEN];
		paddedLen = AlignInt8(len);
		*((FCGI_Header *) response)
			= MakeHeader(FCGI_GET_VALUES_RESULT,
			FCGI_NULL_REQUEST_ID, len, paddedLen - len);
		FreeParams(&paramsPtr);
	} else {
		paddedLen = len = sizeof(FCGI_UnknownTypeBody);
		((FCGI_UnknownTypeRecord *) response)->header
			= MakeHeader(FCGI_UNKNOWN_TYPE, FCGI_NULL_REQUEST_ID,
			len, 0);
		((FCGI_UnknownTypeRecord *) response)->body
			= MakeUnknownTypeBody(type);
	}
	if (write_it_all(data->reqDataPtr->ipcFd, response,
			FCGI_HEADER_LEN + paddedLen) < 0) {
		SetError(stream, OS_Errno);
		return -1;
	}

	return MGMT_RECORD;
}
Example #6
0
int main(int argc, char **argv, char **envp)
{
    int count;
    FCGX_Stream *paramsStream;
    fd_set readFdSet, writeFdSet;
    int numFDs, selectStatus;
    unsigned char headerBuff[8];
    int headerLen, valueLen;
    char *equalPtr;
    FCGI_BeginRequestRecord beginRecord;
    int	doBind, doStart, nServers;
    char appPath[MAXPATHLEN], bindPath[MAXPATHLEN];

    if(ParseArgs(argc, argv, &doBind, &doStart,
		   (char *) &bindPath, (char *) &appPath, &nServers)) {
	fprintf(stderr,
"Usage:\n"
"    cgi-fcgi -f <cmdPath> , or\n"
"    cgi-fcgi -connect <connName> <appPath> [<nServers>] , or\n"
"    cgi-fcgi -start -connect <connName> <appPath> [<nServers>] , or\n"
"    cgi-fcgi -bind -connect <connName> ,\n"
"where <connName> is either the pathname of a UNIX domain socket\n"
"or (if -bind is given) a hostName:portNumber specification\n"
"or (if -start is given) a :portNumber specification (uses local host).\n");
	exit(1);
    }
    if(doBind) {
        appServerSock = OS_FcgiConnect(bindPath);
    }
    if(doStart && (!doBind || appServerSock < 0)) {
        FCGI_Start(bindPath, appPath, nServers);
        if(!doBind) {
            exit(0);
        } else {
            appServerSock = OS_FcgiConnect(bindPath);
	}
    }
    if(appServerSock < 0) {
        fprintf(stderr, "Could not connect to %s\n", bindPath);
        exit(errno);
    }
    /*
     * Set an arbitrary non-null FCGI RequestId
     */
    requestId = 1;
    /*
     * XXX: Send FCGI_GET_VALUES
     */

    /*
     * XXX: Receive FCGI_GET_VALUES_RESULT
     */

    /*
     * Send FCGI_BEGIN_REQUEST (XXX: hack, separate write)
     */
    beginRecord.header = MakeHeader(FCGI_BEGIN_REQUEST, requestId,
            sizeof(beginRecord.body), 0);
    beginRecord.body = MakeBeginRequestBody(FCGI_RESPONDER, TRUE);
    count = write(appServerSock, &beginRecord, sizeof(beginRecord));
    if(count != sizeof(beginRecord)) {
        exit(errno);
    }
    /*
     * Send environment to the FCGI application server
     */
    paramsStream = CreateWriter(appServerSock, requestId, 8192, FCGI_PARAMS);
    for( ; *envp != NULL; envp++) {
        equalPtr = strchr(*envp, '=');
        if(equalPtr  == NULL) {
            exit(1000);
        }
        valueLen = strlen(equalPtr + 1);
        FCGIUtil_BuildNameValueHeader(
                equalPtr - *envp,
                valueLen,
                &headerBuff[0],
                &headerLen);
        if(FCGX_PutStr((char *) &headerBuff[0], headerLen, paramsStream) < 0
                || FCGX_PutStr(*envp, equalPtr - *envp, paramsStream) < 0
                || FCGX_PutStr(equalPtr + 1, valueLen, paramsStream) < 0) {
            exit(FCGX_GetError(paramsStream));
        }
    }
    FCGX_FClose(paramsStream);
    FreeStream(&paramsStream);
    /*
     * Perform the event loop until AppServerReadHander sees FCGI_END_REQUEST
     */
    fromWS.stop = fromWS.next = &fromWS.buff[0];
    webServerReadHandlerEOF = FALSE;
    FD_ZERO(&readFdSet);
    FD_ZERO(&writeFdSet);
    numFDs = max(appServerSock, STDIN_FILENO) + 1;
    SetFlags(appServerSock, O_NONBLOCK);
    for(;;) {
        if((fromWS.stop == fromWS.next) && !webServerReadHandlerEOF) {
            FD_SET(STDIN_FILENO, &readFdSet);
        } else {
            FD_CLR(STDIN_FILENO, &readFdSet);
        }
        if(fromWS.stop != fromWS.next) {
            FD_SET(appServerSock, &writeFdSet);
        } else {
            FD_CLR(appServerSock, &writeFdSet);
        }
        FD_SET(appServerSock, &readFdSet);
        selectStatus = select(numFDs, &readFdSet, &writeFdSet, NULL, NULL);
        if(selectStatus < 0) {
            exit(errno);
        }
        if(selectStatus == 0) {
            /*
             * Should not happen, no select timeout.
             */
            continue;
        }
        if(FD_ISSET(STDIN_FILENO, &readFdSet)) {
            WebServerReadHandler();
        }
        if(FD_ISSET(appServerSock, &writeFdSet)) {
            AppServerWriteHandler();
        }
        if(FD_ISSET(appServerSock, &readFdSet)) {
            AppServerReadHandler();
	}
        if(exitStatusSet) {
            exit(exitStatus);
	}
    } 
}