如何在Windows上手动启动fastCGI应用程序?

时间:2009-12-22 09:49:23

标签: fastcgi

我已经将Web服务器配置为在命名管道上使用“远程”fastCGI应用程序(它实际上位于同一个Windows主机上)。我现在试图找出如何启动fastCGI应用程序来使用此管道,但我不确定应该如何完成。其他操作系统似乎有spawn-fcgi实用程序用于执行此操作,但似乎没有任何类似的Windows。

这是我的APP:

#include <stdio.h>
#include "fcgi_stdio.h"

int main(int argc, char ** argv)
{
  while (FCGI_Accept() >= 0) {
    printf("Content-type: text/html\r\n"
        "\r\n"
        "<title>Web Services Interface Module</title>"
        "<h1>Web Services Interface Module</h1>\n");
  }
  return(0);
}

出于兴趣,我正在使用Abyss Web Server,但我希望这与答案无关。

最好的问候

4 个答案:

答案 0 :(得分:2)

FCGI界面不允许您这样做,而是使用FCGX界面。 调用FCGX_Open_Socket来侦听特定端口,例如9345或命名管道。

FCGX_OpenSocket(":9345", 500);

然后你不需要像spawn_fcgi这样的实用程序来启动你的应用程序。

答案 1 :(得分:1)

 /*
 *----------------------------------------------------------------------
 *
 * FCGX_OpenSocket --
 *
 *  Create a FastCGI listen socket.
 *
 *  path is the Unix domain socket (named pipe for WinNT), or a colon
 *  followed by a port number.  e.g. "/tmp/fastcgi/mysocket", ":5000"
 *
 *  backlog is the listen queue depth used in the listen() call.
 *
 *  Returns the socket's file descriptor or -1 on error.
 *
 *----------------------------------------------------------------------
 */
 DLLAPI int FCGX_OpenSocket(const char *path, int backlog);

默认情况下,libfcgi从stdin读取。所以重新打开stdin句柄作为管道。

 dup2(FCGX_OpenSocket("pipe name", 5),0);

答案 2 :(得分:1)

更改fcgiapp.c中的FCGX_Init

int FCGX_Init(void)
{
    char *p;

    int listen_socket;

    if (libInitialized) {
        return 0;
    }

    if (OS_LibInit(NULL) == -1) {
        return OS_Errno ? OS_Errno : -9997;
    }   

    /*sureone socket*/
        /* 9010 is your listen port*/
    listen_socket = FCGX_OpenSocket(":9010", 400); 
    if(listen_socket < 0) exit(1);
    printf("FCGX_InitRequest...\n");
    FCGX_InitRequest(&the_request, listen_socket, 0);
    /*end sureone*/

    //FCGX_InitRequest(&the_request, FCGI_LISTENSOCK_FILENO, 0);



    p = getenv("FCGI_WEB_SERVER_ADDRS");
    webServerAddressList = p ? StringCopy(p) : NULL;

    libInitialized = 1;
    return 0;
}

答案 3 :(得分:0)

我想出了一个适用于Windows的代码:

int main ()
{
    char **initialEnv = environ; //Keep track of initial environment
    int count = 0;        
    int listenSocket;


    //It's ugly, but in Windows we need to initialize the 
    //socket library. We can do it by calling
    //libfcgi's OS_LibInit() function
    OS_LibInit(NULL);

    //Open a socket. Here, we use localhost:9000
    listenSocket = FCGX_OpenSocket("localhost:9000", 5);
    if (listenSocket < 0) {
      exit(1);
    }

    FCGX_Request request;
    FCGX_Init();
    FCGX_InitRequest(&request, listenSocket, 0);


    while (FCGX_Accept_r(&request) >= 0) {
        //Init I/O streams wrapper as well as set the new environment
        FCGI_stdin->stdio_stream = NULL;
        FCGI_stdin->fcgx_stream = request.in;
        FCGI_stdout->stdio_stream = NULL;
        FCGI_stdout->fcgx_stream = request.out;
        FCGI_stderr->stdio_stream = NULL;
        FCGI_stderr->fcgx_stream = request.err;
        environ = request.envp;

        //Funny stuff
        char *contentLength = getenv("CONTENT_LENGTH");
        int len;

        printf("Content-type: text/html\r\n"
               "\r\n"
               "<title>FastCGI echo</title>"
               "<h1>FastCGI echo</h1>\n"
               "Request number %d,  Process ID: %d<p>\n", ++count, getpid());

        if (contentLength != NULL) {
            len = strtol(contentLength, NULL, 10);
        } else {
            len = 0;
        }

        if (len <= 0) {
            printf("No data from standard input.<p>\n");
        }
        else {
            int i, ch;

            printf("Standard input:<br>\n<pre>\n");
            for (i = 0; i < len; i++) {
                if ((ch = getchar()) < 0) {
                    printf("Error: Not enough bytes received on standard input<p>\n");
                    break;
                }
                putchar(ch);
            }
            printf("\n</pre><p>\n");
        }

    } /* while */    

    return 0;
}