Module mod_fastcgi

This module is contained in the mod_fastcgi.c file, and is not compiled into the server by default. To use mod_fastcgi you first copy src/mod_fastcgi.c from this kit into your Apache server's source directory. Then you add the following line to the server build Configuration file:
        Module fastcgi_module    mod_fastcgi.o

FastCGI provides a high-performance alternative to CGI for writing Web server applications in a variety of languages, including Perl, C, C++, Java, and Python. FastCGI gets its speed by having keeping application processes running between requests. So, unlike CGI, you do not have the overhead of starting up a new process and doing application initialization (e.g. connecting to a database) each time somebody requests a document.

FastCGI applications communicate with a Web server using a simple communications protocol. A single full-duplex connection communicates the environment variables and stdin data to the application, and stdout and stderr data to the Web server. An application can reside on a different machine from the Web server, allowing applications to scale beyond a single box and providing easier integration with existing systems.

For more information on FastCGI, including freely available FastCGI server modules and application libraries, go to the FastCGI website (http://www.fastcgi.com/).

Summary

In order to configure FastCGI applications, you need a combination of mod_fastcgi directives and other directives provided by the Apache server.

You use the AppClass directive to start the FastCGI applications that you want to be managed by this Web server. The applications are managed in the sense that the server (a) logs an error message when a managed process dies and (b) attempts to restart managed processes that die.

You use one or both of the AppClass and ExternalAppClass directives to define an association between a pathname and the connection information for a FastCGI application. Connection information is either the pathname of a Unix domain socket or the IP address and port number of a TCP port. The difference between the two directives is that a single AppClass directive both starts an application and sets up the association for communicating with it, while ExternalAppClass only defines the association. In the case of AppClass, the pathname used in the association is always the pathname of the application's executable; with ExternalAppClass the pathname is arbitrary.

In order for an HTTP request to be processed by mod_fastcgi the request's handler must be fastcgi-script or the request's MIME type must be application/x-httpd-fcgi. Apache provides several ways to set the handler and MIME type of a request:

Refer to the documentation for mod_mime for more information on these directives, and to the documentation of the Apache core features for information on Location and Directory sections.

mod_fastcgi handles requests as follows:

The configuration examples below show some valid ways to configure mod_fastcgi.

Directives


AppClass

Syntax: AppClass path-name [-processes N] [-listen-queue-depth N] [-restart-delay N] [-priority N] [-port N] [-socket sock-name] [-initial-env name=value]
Context: srm.conf
Module: mod_fastcgi

The AppClass directive starts one or more FastCGI application processes, using the executable file path-name. Should any of these processes die, mod_fastcgi will write an error log entry and restart the faulty process.

The optional parameters to the AppClass directive are as follows:

The -socket and -port options are mutually exclusive. path-name must not equal the path-name supplied to an earlier AppClass or ExternalAppClass directive. Other errors possible in the AppClass directive include syntax errors, arguments out of range, and the file path-name being non-existent or not executable.

ExternalAppClass

Syntax: ExternalAppClass path-name [-host host:port] [-socket sock-name]
Context: srm.conf
Module: mod_fastcgi

The ExternalAppClass directive provides a connection a FastCGI application process that is listening to a specified TCP port or a UNIX domain socket. ExternalAppClass is most commonly used to communicate with a FastCGI application running on a different machine. This directive implies nothing about how the FastCGI application is managed (started, restarted, etc.). path-name simply provides an identifier for the connection.

The optional parameters to the ExternalAppClass directive are as follows:

Exactly one of the port and socket parameters must be supplied. path-name must not equal the path-name supplied to an earlier AppClass or ExternalAppClass directive. Other errors possible in the ExternalAppClass directive include syntax errors and arguments out of range.

FastCgiIpcDir

Syntax: FastCgiIpcDir dir-path
Context: srm.conf
Module: mod_fastcgi

The FastCgiIpcDir directive controls where mod_fastcgi creates Unix-domain sockets for communicating with the applications it manages.

By default, mod_fastcgi creates the sockets in /tmp. The socket names have the form OM_WS_n.pid where n is a sequence number and pid is the process ID of the Apache parent process. If your system runs a periodic job to delete files from /tmp, and it deletes these files, your Web server won't be able to communicate with its FastCGI applications.

To avoid this problem place a FastCgiIpcDir directive before the AppClass directives in your server configuration. Specify a directory that's readable, writeable, and searchable by the account you use for your Web server, but otherwise not accessible to anyone.

Note 1 below describes platform-specific problems in moving the sockets out of /tmp; please read it.


Important notes

  1. On some platforms, Unix-domain sockets don't work when stored in non-local file systems. Digital UNIX 3.0 is known to have this problem with NFS (fixed in Digital UNIX 3.2); Solaris 2.5 is known to have this problem with AFS. If /tmp is part of a local file system you'll avoid this problem by leaving the listening sockets in /tmp rather than using the FastCgiIpcDir directive to put them somewhere else.

  2. Error logging by the mod_fastcgi process manager corrupts the error log on some platforms, due to a bug in the C library function fopen. For instance, SunOS 4.1.4 has the fopen bug and exhibits the error log corruption problem. A corrupted error log makes it difficult to debug problems on your Web server. You should apply the following patch to Apache 1.1.1 in order to eliminate the possibility of this problem:
    % diff -c alloc.c alloc.c.orig
    *** alloc.c     Mon Sep 23 17:45:34 1996
    --- alloc.c.orig        Mon Sep 23 17:43:16 1996
    ***************
    *** 765,784 ****
      
      FILE *pfopen(struct pool *a, char *name, char *mode)
      {
    !   FILE *fd = NULL;
      
        block_alarms();
    !   if (*mode == 'a') {
    !     /* Work around faulty implementations of fopen */
    !     int baseFlag = (*(mode+1) == '+') ? O_RDWR : O_WRONLY;
    !     int desc = open(name, baseFlag | O_APPEND | O_CREAT,
    !             S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    !     if (desc >= 0) {
    !       fd = fdopen(desc, mode);
    !     }
    !   } else {
    !     fd = fopen(name, mode);
    !   }
        if (fd != NULL) note_cleanups_for_file (a, fd);
        unblock_alarms();
        return fd;
    --- 765,774 ----
      
      FILE *pfopen(struct pool *a, char *name, char *mode)
      {
    !   FILE *fd;
      
        block_alarms();
    !   fd = fopen(name, mode);
        if (fd != NULL) note_cleanups_for_file (a, fd);
        unblock_alarms();
        return fd;
        
  3. The ScriptAlias directive takes priority over the AddType directive: A file located in a directory that is the target of ScriptAlias is always handled by the handler cgi-handler (mod_cgi.) So don't put FastCGI applications in a ScriptAlias directory -- the applications won't work properly!

  4. The optional module mod_env provides two directives (PassEnv and SetEnv) that are designed for passing environment variables to CGI scripts. These directives also work for passing per-request environment variables to FastCGI applications. To pass initial environment variables you must use the -initial-env option to AppClass.

  5. mod_fastcgi does not implement the Authorizer or Filter roles described in the FastCGI specification. However, you can approximate the Filter role using Apache's Action directive to route requests to a FastCGI Responder. See the documentation for mod_actions for information on the Action directive.

  6. See the README file for a complete list of known bugs in this version of mod_fastcgi.

    Notes on CGI response headers

    You may have noticed that mod_fastcgi makes no provision for non-parsed-header scripts. There's a good reason for this: mod_fastcgi does not restrict the functionality of parsed-header scripts in any way. A parsed-header script can do anything that an "nph" script can do, and some things that an "nph" script can't do.

    To exploit the power of parsed-header scripts you need to understand the three standard CGI/1.1 response headers:

    Only certain combinations of these headers make sense:

    The Location header specifies a redirect. There are two kinds. If the Location value is a full URL (e.g. http://www.fastcgi.com/servers/apache), the effect is to generate an HTTP 302 response. If the Location value is an absolute path (e.g. /servers/apache), the effect is to execute a recursive request for that path within the server, and return the response of that request.

    Location is optionally accompanied by Content-type. If the Location value is a full URL and no Content-type is specified, the Web server provides standardized content (of type text/html); if a Content-type is specified, the script provides the content. If the Location value is an absolute path then script-generated Content-type and content are ignored.

    mod_fastcgi performs buffering of script-provided content, but content is not allowed to linger in buffers for more than a fraction of a second. Therefore "server push" scripts work correctly.

    Configuration example

    What follows is a minimal httpd.conf for Apache 1.1.1 and FastCGI Developer's Kit 1.5. Use this configuration for initial testing with FastCGI. When you've verified that this configuration works, you can merge the FastCGI-specific aspects of this configuration with your own configuration.

    Directions:

    1. Change $APACHE to the path name of the directory containing your Apache 1.1.1 kit, i.e. the directory containing the Apache 1.1.1 README. For instance, you might change $APACHE to /udir/doe/apache_1.1.1.

      Change $FASTCGI to the path name of the directory containing your FastCGI Developer's Kit 1.5, i.e. the directory containing the FastCGI Developer's Kit 1.5 README. For instance, you might change $FASTCGI to /udir/doe/fcgi-devel-kit.

      Save the resulting file as $APACHE/conf/httpd.conf.

    2. Build Apache 1.1.1 with mod_fastcgi. This creates the httpd executable.

      Build the FastCGI Developer's Kit 1.5. This creates the echo executable that you are going to run as a FastCGI application.

    3. In a shell, cd to $APACHE and start httpd:
          % src/httpd -f $APACHE/conf/httpd.conf
          

    4. Use a browser to access the URL
          http://$YOUR_HOST:5556/examples/echo
          
      where $YOUR_HOST is the IP address of the host running httpd. Look for STATE=TEXAS in the initial environment that echo displays. The request counter should increment each time you reload the page.

    # httpd.conf -- minimal for mod_fastcgi
    #
    # One config file is plenty
    ResourceConfig /dev/null
    AccessConfig   /dev/null
    
    # Not starting httpd as root, so Port must be larger than 1023
    Port 5556
    
    # This is what you'd add to the config if the server is to be
    # started as root.  Don't do this until you've verified that the
    # server works when started as non-root!  Don't use user/group nobody;
    # define a new user and group specifically for running the server.
    # User httpd
    # Group httpd
    
    # Configure just one idle httpd child process, to simplify debugging
    StartServers    1
    MinSpareServers 1
    MaxSpareServers 1
    
    # Tell httpd where it should live, turn on access and error logging
    ServerRoot     $APACHE
    ErrorLog       logs/error.log
    TransferLog    logs/access.log
    ScoreBoardFile logs/httpd.scoreboard
    
    # Tell httpd where to get documents
    DocumentRoot $FASTCGI
    
    # This is how you'd place the Unix-domain socket files in the logs
    # directory (you'd probably want to create a subdirectory for them.)
    # Don't do this until you've verified that everything works with
    # the socket files stored locally, in /tmp!
    # FastCgiIpcDir $APACHE/logs
    
    # Start the echo app
    AppClass $FASTCGI/examples/echo -initial-env STATE=TEXAS
    
    # Have mod_fastcgi handle requests for the echo app
    # (otherwise the server will return the app's binary as a file!)
    <Location /examples/echo>
    SetHandler fastcgi-script
    </Location>
    
    # Start a FastCGI application that's accessible from other machines
    AppClass $FastCGI/examples/echo.fcg -port 8978
    <Location /examples/echo.fcg>
    SetHandler fastcgi-script
    </Location>
    
    # Connect to "remote" app started above.  Since the app is actually
    # local, communication will take place using TCP loopback.
    # To test true remote operation, start one copy of this
    # Web server on one machine, then start another copy with
    # "localhost" in the line below changed to the host name of the first machine.
    ExternalAppClass $FASTCGI/examples/remote-echo -host localhost:8978
    <Location /examples/remote-echo>
    SetHandler fastcgi-script
    </Location>
    
    # This is how you'd have mod_fastcgi handle any request for a file
    # whose name ends in .fcg:
    # AddHandler fastcgi-script fcg
    
    # End of httpd.conf