Document Version: 1.08
11 June 1996
FastCGI is designed to be layered on top of existing Web server APIs. For instance, the mod_fastcgi Apache module adds FastCGI support to the Apache server. FastCGI can also be used, with reduced functionality and reduced performance, on any Web server that supports CGI.
This FastCGI Developer's Kit is designed to make developing FastCGI applications easy. The kit currently supports FastCGI applications written in C/C++, Perl, Tcl, and Java.
This document:
The FastCGI Specification, doc/fcgi-spec.html, defines the interface between a FastCGI application and a Web server that supports FastCGI. The software in the kit implements the specification. You don't need to read the specification in order to write applications.
Additional information is provided in the FAQ document, which contains frequently asked questions about application development using FastCGI, as well as some general information.
Experience with CGI programming will be extremely valuable in writing FastCGI applications. If you don't have enough experience with CGI programming, you should read one of the popular books on the topic or study the NCSA CGI page. For a more formal treatment of CGI/1.1 see the Internet Draft CGI 1.1 Specification.
Open the kit's index page, fcgi-devel-kit/index.html, using the "Open File" command in your Web browser. The index page gives you an overview of the kit structure and helps you navigate the kit. The index page also contains links that run some example applications, but the applications won't work when index.html is opened using the "Open File" command because they aren't aren't being accessed through a Web server.
In order to use the kit in earnest you'll need a Web server that you control, a Web server running with your user ID. The Web server will be starting FastCGI applications that you will need to debug; this will be a lot more convenient for you if these processes run with your user ID. It is best to have a Web server that supports FastCGI. Section 4 discusses Web server issues.
If you can, keep the kit on a file system accessible from your personal workstation, do your builds on your workstation, and run your Web server on your workstation. If that's not possible, arrange a configuration such that the kit is accessible from the machine that's going to run your Web server, and build the kit and your applications on a machine that's configured exactly the same way (same processor architecture, operating system, etc.) as the machine that's going to run your Web server.
To build the kit you execute this sequence of commands in the fcgi-devel-kit directory:
% ./configure % makeWe've built and exercised the kit on these platforms (listed in alphabetical order):
To introduce the fcgi_stdio library we give a pair of examples: a tiny CGI program and the translation of this program to FastCGI. These two example programs are included in the kit.
The CGI program is examples/tiny-cgi.c:
#include <stdio.h> #include <stdlib.h> void main(void) { int count = 0; printf("Content-type: text/html\r\n" "\r\n" "<title>CGI Hello!</title>" "<h1>CGI Hello!</h1>" "Request number %d running on host <i>%s</i>\n", ++count, getenv("SERVER_NAME")); }The key features of this tiny CGI program are:
The corresponding FastCGI program is examples/tiny-fcgi.c:
#include "fcgi_stdio.h" #include <stdlib.h> void main(void) { int count = 0; while(FCGI_Accept() >= 0) printf("Content-type: text/html\r\n" "\r\n" "<title>FastCGI Hello!</title>" "<h1>FastCGI Hello!</h1>" "Request number %d running on host <i>%s</i>\n", ++count, getenv("SERVER_NAME")); }The key features of this tiny FastCGI program are:
You can use CGI to run application binaries built with the fcgi_stdio library. The FCGI_Accept function tests its environment to determine how the application was invoked. If it was invoked as a CGI program, the first call to FCGI_Accept is essentially a no-op and the second call returns -1. In effect, the request loop disappears.
Of course, when a FastCGI application is run using CGI it does not get the benefits of FastCGI. For instance, the application exits after servicing a single request, so it cannot maintain cached information.
Here are some consequences of this implementation technique:
#ifndef _STDIO_H #define _STDIO_HThe specific symbol used for multiple-include protection, _STDIO_H in this example, varies from platform to platform. As long as your platform protects stdio.h against multiple includes, you can forget about this issue.
gcc -include /usr/local/include/fcgi_stdio.h wonderlib.ccauses gcc to include fcgi_stdio.h before it even begins to read the module wonderlib.c.
FILE *myStream = fopen(path, "r"); answer = MungeStream(FCGI_ToFile(myStream));Here MungeStream is a library function that you can't recompile and FCGI_ToFile is a macro that converts from FCGI_FILE * to FILE *. The macro FCGI_ToFile is defined in fcgi_stdio.h.
Retained application state may be an issue. You must ensure that any application state created in processing one request has no unintended effects on later requests. FastCGI offers the possibility of significant application performance improvements, through caching; it is up to you to make the caches work correctly.
Storage leaks may be an issue. Many CGI programs don't worry about storage leaks because the programs don't run for long enough for bloating to be a problem. When converting to FastCGI, you can either use a tool such as Purify from Pure Software to discover and fix storage leaks, or you can run a C garbage collector such as Great Circle from Geodesic Systems.
FILE *myStream = fopen(path, "r"); count = fscanf(FCGI_ToFile(myStream), format, ...);
The FCGI_Finish (doc/FCGI_Finish.3), FCGI_SetExitStatus (doc/FCGI_SetExitStatus.3), and FCGI_StartFilterData (doc/FCGI_StartFilterData.3) manpages document capabilities of the fcgi-stdio library that are not illustrated above.
Applications built using the fcgiapp library cannot run as CGI programs; that feature is provided at the fcgi_stdio level.
Functions defined in fcgiapp are named using the prefix FCGX_ rather than FCGI_. For instance, FCGX_Accept is the fcgiapp version of FCGI_Accept.
Documentation of the fcgiapp library takes the form of extensive comments in the header file include/fcgiapp.h. The sample programs examples/tiny-fcgi2.c and examples/echo2.c illustrate how to use fcgiapp.
We have produced FastCGI-integrated Perl and Tcl interpreters. Doing so was easy, since Perl and Tcl are conventional C applications and fcgi_stdio was designed for converting conventional C applications. Essentially no source code changes were required in these programs; a small amount of code was added in order to make FCGI_Accept and other FastCGI primitives available in these languages. And because these interpreters were developed using fcgi_stdio, they run standard Perl and Tcl applications (e.g. CGI scripts) as well as FastCGI applications.
See the www.fastcgi.com/applibs Web page for downloadable Perl and Tcl binaries for selected platforms. Because many users of Perl and Tcl run extended versions of these languages, the kit includes separate companion documents describing how to build FastCGI-integrated Perl and how to build FastCGI-integrated Tcl.
Here are the Perl and Tcl versions of tiny-fcgi:
#!./perl use FCGI; $count = 0; while(FCGI::accept() >= 0) { print("Content-type: text/html\r\n\r\n", "<title>FastCGI Hello! (Perl)</title>\n", "<h1>FastCGI Hello! (Perl)</h1>\n"; "Request number ", ++$count, " running on host <i>";$env(SERVER_NAME)</i>"); }
#!./tclsh set count 0 while {[FCGI_Accept] >= 0 } { incr count puts -nonewline "Content-type: text/html\r\n\r\n" puts "<title>FastCGI Hello! (Tcl)</title>" puts "<h1>FastCGI Hello! (Tcl)</h1>" puts "Request number $count running on host <i>$env(SERVER_NAME)</i>" }Converting a Perl or Tcl CGI application to FastCGI is not fundamentally different from converting a C CGI application to FastCGI. You separate the portion of the application that performs one-time initialization from the portion that performs per-request processing. You put the per-request processing into a loop controlled by FCGI::accept (Perl) or FCGI_Accept (Tcl).
The FCGIInterface class provides facilities for Java applications analogous to what fcgi_stdio provides for C applications. Using this library your Java application can run using either CGI or FastCGI.
The kit includes separate companion document on using FastCGI with Java. The source code for FastCGI classes is contained in directory java/src and the compiled code in java/classes.
Here is the Java version of tiny-fcgi:
import FCGIInterface; class TinyFCGI { public static void main (String args[]) { int count = 0; while(new FCGIInterface().FCGIaccept()>= 0) { count ++; System.out.println("Content-type: text/html\r\n\r\n"); System.out.println( "<title>FastCGI Hello! (Java)</title>"); System.out.println("<h1>FastCGI Hello! (Java)</h1>"); System.out.println( "request number " + count + " running on host <i>" + System.getProperty("SERVER_NAME") + "</i>"); } } }
All of the Web servers that support FastCGI perform management of FastCGI applications. You don't need to start and stop FastCGI applications; the Web server takes care of this. If an application process should crash, the Web server restarts it.
Web servers support FastCGI via new configuration directives. Since these directives are server-specific, get more information from the documentation that accompanies each server.
The directory examples/conf contains config files designed to run the example programs included in the FastCGI Developer's Kit. Each config file contains specific installation instructions.
The more advanced example programs take advantage of special features of the Open Market Secure WebServer, such as anonymous ticketing and support for the Authorizer role. If you don't have this server, download a free evaluation copy to run the examples.
Here is how cgi-fcgi works. cgi-fcgi is a standard CGI program that uses Unix domain or TCP/IP sockets to communicate with a FastCGI application. cgi-fcgi takes the path name or host/port name of a listening socket as a parameter and connects to the FastCGI application listening on that socket. cgi-fcgi then forwards the CGI environment variables and stdin data to the FastCGI application, and forwards the stdout and stderr data from the FastCGI application to the Web server. When the FastCGI application signals the end of its response, cgi-fcgi flushes its buffers and exits.
Obviously, having cgi-fcgi is not as good as having a server with integrated FastCGI support:
The file examples/tiny-fcgi.cgi demonstrates a way to use cgi-fcgi to run a typical application, in this case the examples/tiny-fcgi application:
#!../cgi-fcgi/cgi-fcgi -f -connect sockets/tiny-fcgi tiny-fcgiOn most Unix platforms, executing this command-interpreter file runs cgi-fcgi with arguments -f and examples/tiny-fcgi.cgi. (Beware: On some Unix platforms, including HP-UX, the first line of a command-interpreter file cannot contain more than 32 characters, including the newline; you may need to install the cgi-fcgi application in a standard place like /usr/local/bin or create a symbolic link to the cgi-fcgi application in the directory containing your application.) The cgi-fcgi program reads the command-interpreter file and connects to the FastCGI application whose listening socket is examples/sockets/tiny-fcgi.
Continuing the example, if cgi-fcgi's connection attempt fails, it creates a new process running the program examples/tiny-fcgi and listening on socket examples/sockets/tiny-fcgi. Then cgi-fcgi retries the connection attempt, which now should succeed.
The cgi-fcgi program has two other modes of operation. In one mode it connects to applications but does not start them; in the other it starts applications but does not connect to them. These modes are required when using TCP/IP. The cgi-fcgi manpage, doc/cgi-fcgi.1, tells the full story.
To run the example applications using cgi-fcgi, start your Web server and give it the directory fcgi-devel-kit as the root of its URL space. If the machine running your server is called bowser and your server is running on port 8888, you'd then open the URL http://bowser:8888/index.html to reach the kit's index page. Now the links on the index page that run example applications via cgi-fcgi should be active.
On AIX there's a problem with shared listening sockets. The symptoms can include application core dumps and kernel panic. Work-around: Run a single FastCGI application server per listening socket.
Mail sent to this list is archived and available on the World-Wide Web at
http://www.fastcgi.com/mail/Open Market Secure WebServer customers get FastCGI support where they get server support.