开发者

How can fastCGI applications be started manually on Windows?

开发者 https://www.devze.com 2022-12-14 11:28 出处:网络
I am have configured a Web Server to use开发者_开发知识库 a \'remote\' fastCGI application over a named pipe (it\'s actually on the same windows host). I am now trying to find out how to start the fas

I am have configured a Web Server to use开发者_开发知识库 a 'remote' fastCGI application over a named pipe (it's actually on the same windows host). I am now trying to find out how to start the fastCGI application to use this pipe but am unsure how this should be done. Other OS's seem to have spawn-fcgi utilities for doing this but there doesn't seem to be anything similar for Windows.

This is my 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);
}

Out of interest I am using Abyss Web Server though I hope that doesn't have a bearing on the answer.

Best Regards


The FCGI interface does not let you do this, instead use the FCGX interface. Call FCGX_Open_Socket to listen on a specific port e.g. 9345 or a named pipe.

FCGX_OpenSocket(":9345", 500);

Then you don't need to use a utility like spawn_fcgi to start your application at all.


 /*
 *----------------------------------------------------------------------
 *
 * 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);

By default libfcgi reads from stdin. So reopen stdin handle as pipe.

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


change FCGX_Init in the fcgiapp.c

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;
}


I've come up with a code that just works for me in 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;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消