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/).
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:
SetHandler
(in the context of a Location
or Directory
section or .htaccess
file)
can associate the handler fastcgi-script
with a
specific file, or all the files in a directory.
AddHandler
can associate the handler fastcgi-script
with files based on file extension.
ForceType
(in the context of a Location
or Directory
section or .htaccess
file)
can associate the MIME type application/x-httpd-fcgi
with a specific file, or all the files in a directory.
AddType
can associate the MIME type application/x-httpd-fcgi
with files based on file extension.
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:
mod_fastcgi
retrieves the connection information
associated with the requested pathname.
404 Not Found
.
mod_fastcgi
connects to the FastCGI application
process.
500
Server Error
.
mod_fastcgi
transmits the request to the FastCGI
application process, which generates a response.
mod_fastcgi
receives the application's response
and transforms it into an HTTP response. The server sends this
response back to the client.
The configuration examples below show some valid ways to configure
mod_fastcgi
.
Syntax: AppClass path-name [-appConnTimeout
timeout] [-processes N] [-listen-queue-depth N] [-init-start-delay
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 ExternalAppClass
directive are as follows:
setpriority
system call. The default
value is zero, i.e. same priority as the HTTP server. Negative
values are not allowed.
port
option should be a number
between 1 and 65535.
FastCgiIpcDir
.
Using this option makes the application accessible to other Web
servers or applications (e.g. cgi-fcgi
) on the same
machine or via multiple pathnames on this Web server (using ExternalAppClass
.)
If neither the -socket
nor the -port
options are given, the Web server generates a Unix domain socket
name itself.
name=value
, with no whitespace allowed. You can
add several name-value pairs to the initial environment by using
this option several times. The default initial environment is
empty (no name-value pairs.)
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.
Syntax: ExternalAppClass path-name [-host
host:port] [-socket sock-name] [-appConnTimeout timeout]
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:
AppClass
directive with the -socket
option.
startDelay
attribute.
The default value is 15 seconds.
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.
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.
Syntax: FCGIConfig [-maxProcesses max-procs]
[-minProcesses min-procs] [-maxClassProcesses max-class-procs]
[-killInterval kill-time] [-updateInterval update-time] [-gainValue
gain] [-singleThreshhold thresh1] [-multiThreshhold threshN] [-startDelay
delay-time] [-appConnTimeout timeout] [-processSlack slack]
Context: srm.conf
Module: mod_fastcgi
The FCGIConfig
directive provides a set of configuration
parameters that are used in governing the execution of the dynamic
FastCGI applications. This includes limitations on process creation
and killing policy. Current implementation of the latter computes
a load factor for each dynamic FastCGI application and makes the
decision whether to kill it or not based on the threshhold parameters
specified above. This directive has no affect on the statically
configured (i.e. via AppClass) FastCGI applications.
The optional parameters to the FCGIConfig
directive
are as follows:
singleTHreshhold
is
used. The default value for this attribute is 50.
name=value
, with no whitespace
allowed. You can add several name-value pairs to the initial
environment by using this option several times. The default initial
environment is empty (no name-value pairs.)
startDelay
attribute.
The default value is 15 seconds.
processSlack
exceeds the value of maxProcesses
attribute, a process manager invokes the killing policy. This
measure is used to improve the performance at higher loads by
killing extra processes prior to achieving a highest possible
load. The value should reflect the value for maxProcesses
and provided as a default of 5.
If you supply two or more different values for the same attribute
of the FCGIConfig
directive, only the last value
will be in effect. Any attributes that have not been supplied
will take on the default values described above. Possible sources
of errors include syntax errors and invalid arguments.
/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.
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;
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!
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
.
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.
fcgi-suexec
patch provided by Brian
Grossman. This patch is available via http://www.SoftHome.net/pub/users/brian.
README
file for
a complete list of known bugs in this version of mod_fastcgi
.
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:
Status:
an HTTP status line, e.g. "206
Partial Content"
.
Location:
a URL or absolute path to content.
Content-type:
the media type of script-generated
response content.
Only certain combinations of these headers make sense:
Status
and Location
headers
are mutually exclusive, i.e. at most one may appear in a response.
If neither appears, the effect is as if Status: 200 OK
appeared, and a Content-type
header must appear.
Content-type
header means that the script
will generate response content (e.g. an HTML document), and the
absence of a Content-type
header means that the
script will not generate response content.
Location
header may only be generated in response
to a GET
or HEAD
request.
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.
What follows is a minimal httpd.conf for Apache 1.2 and FastCGI Developer's Kit 1.5 (or higher). 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:
$APACHE
to the path name of the directory
containing your Apache 1.2 kit, i.e. the directory containing
the Apache 1.2 README. For instance, you might change $APACHE
to /udir/doe/apache_1.2
.
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
.
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.
$APACHE
and start httpd: % src/httpd -f $APACHE/conf/httpd.conf
http://$YOUR_HOST:5556/examples/echowhere
$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