How can fastCGI applications be started manually on Windows?
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;
}
精彩评论