fix validation, organization, and links
robs [Tue, 27 Nov 2001 01:03:47 +0000 (01:03 +0000)]
doc/fcgi-devel-kit.htm
doc/fcgi-java.htm
doc/fcgi-perf.htm
doc/fcgi-perl.htm
doc/fcgi-spec.html
doc/fcgi-tcl.htm
doc/overview.html
doc/www5-api-workshop.html

index e1f5639..94e868c 100644 (file)
-<html>
-
-<head>
-<title>FastCGI Developer's Kit</title>
-</head>
-
-<body bgcolor="#FFFFFF" text="#000000" link="#cc0000" alink="#000011" vlink="#555555">
-<p align="center">
-
-<img border="0" src="../images/fcgi-hd.gif" alt="[[FastCGI]]"> <br
-clear="all">
-</p>
-
-<h3 align="center">FastCGI Developer's Kit</h3>
-<!--Copyright (c) 1996 Open Market, Inc.                                    -->
-<!--See the file "LICENSE.TERMS" for information on usage and redistribution-->
-<!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->
-
-<p align="center">Mark R. Brown<br>
-Open Market, Inc.<br>
-</p>
-
-<p align="center">Document Version: 1.08<br>
-11 June 1996<br>
-</p>
-
-<h5 align="center">Copyright © 1996 Open Market, Inc. 245 First Street, Cambridge, MA
-02142 U.S.A.<br>
-Tel: 617-621-9500 Fax: 617-621-1703 URL: <a href="http://www.openmarket.com/">http://www.openmarket.com/</a><br>
-$Id: fcgi-devel-kit.htm,v 1.3 2001/05/14 12:58:16 robs Exp $ <br>
-</h5>
-
-<hr>
-
-<ul type="square">
-  <li><a HREF="#S1">1. Introduction</a> </li>
-  <li><a HREF="#S2">2. Getting started</a> </li>
-  <li><a HREF="#S3">3. Writing applications</a> <ul type="square">
-      <li><a HREF="#S3.1">3.1 Using the <tt>fcgi_stdio</tt> library</a> </li>
-      <li><a HREF="#S3.2">3.2 Using the <tt>fcgiapp</tt> library</a> </li>
-      <li><a HREF="#S3.3">3.3 Using Perl and Tcl</a> </li>
-      <li><a HREF="#S3.4">3.4 Using Java</a> </li>
-    </ul>
-  </li>
-  <li><a HREF="#S4">4. Running applications</a> <ul type="square">
-      <li><a HREF="#S4.1">4.1 Using a Web server that supports FastCGI</a> </li>
-      <li><a HREF="#S4.2">4.2 Using <tt>cgi-fcgi</tt> with any Web server</a> </li>
-    </ul>
-  </li>
-  <li><a HREF="#S5">5. Known problems</a> </li>
-  <li><a HREF="#S6">6. Getting support</a> </li>
-</ul>
-
-<hr>
-
-<h3><a NAME="S1">1. Introduction</a></h3>
-
-<p>FastCGI is an open extension to CGI that provides high performance for all Internet
-applications without the penalties of Web server APIs.</p>
-
-<p>FastCGI is designed to be layered on top of existing Web server APIs. For instance, the
-<tt>mod_fastcgi</tt> 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.</p>
-
-<p>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.</p>
-
-<p>This document: 
-
-<ul type="square">
-  <li>Describes how to configure and build the kit for your development platform. </li>
-  <li>Tells how to write applications using the libraries in the kit. </li>
-  <li>Tells how to run applications using Web servers that support FastCGI or using any Web
-    server and <tt>cgi-fcgi</tt>. </li>
-</ul>
-
-<p>The kit includes a <a href="fastcgi-whitepaper/fastcgi.htm">technical white paper</a>, <tt>doc/fastcgi-whitepaper/fastcgi.htm</tt>.
-You should read at least the first three sections of the technical white paper before
-starting to write FastCGI applications. The <a href="fcgi-perf.htm">performance paper</a>
-will help you understand how application design affects performance with FastCGI.</p>
-
-<p>The <a href="fcgi-spec.html">FastCGI Specification</a>, <tt>doc/fcgi-spec.html</tt>,
-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.</p>
-
-<p>Additional information is provided in the <a
-href="http://fastcgi.com/docs/FAQ.html">FAQ</a> document, which contains frequently
-asked questions about application development using FastCGI, as well as some general
-information.</p>
-
-<p>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 <a
-href="http://hoohoo.ncsa.uiuc.edu/cgi/">NCSA CGI page</a>. For a more formal treatment of
-CGI/1.1 see the <a
-href="http://ds.internic.net/internet-drafts/draft-robinson-www-interface-01.txt">Internet
-Draft CGI 1.1 Specification</a>.</p>
-
-<h3><a NAME="S2">2. Getting started</a></h3>
-
-<p>The kit is a compressed tar (tar.Z) file, distributed via the <a
-href="http://fastcgi.com/">fastcgi.com</a> Web page. Unpacking the
-tar file creates a new directory <tt>fcgi-devel-kit</tt>.</p>
-
-<p>Open the kit's index page, <tt>fcgi-devel-kit/index.html</tt>, using the &quot;Open
-File&quot; 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
-&quot;Open File&quot; command because they aren't aren't being accessed through a Web
-server.</p>
-
-<p>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. <a
-href="#S4">Section 4</a> discusses Web server issues.</p>
-
-<p>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.</p>
-
-<p>To build the kit you execute this sequence of commands in the <tt>fcgi-devel-kit</tt>
-directory:</p>
-
-<pre>
-    % ./configure
-    % make
-</pre>
-
-<p>We've built and exercised the kit on these platforms (listed in alphabetical order):
-
-<ul type="square">
-  <li>BSD/OS 1.1 (Intel Pentium), gcc </li>
-  <li>Digital UNIX V3.2 148 (Alpha), gcc/cc </li>
-  <li>Hewlett-Packard HP-UX A.09.05 C and B.10.01 A (PA-RISC), gcc/cc </li>
-  <li>IBM AIX 1 4 (RS/6000), gcc </li>
-  <li>Silicon Graphics IRIX 5.3 11091812 (MIPS), gcc </li>
-  <li>Sun Solaris 2.4 and 2.5 (SPARC), gcc/cc </li>
-  <li>Sun SunOS 4.1.4 (SPARC), gcc </li>
-</ul>
-
-<p>Once you've built the kit, follow the directions in <a href="#S4">Section 4</a> to
-bring up your Web server and run the example applications.</p>
-
-<h3><a NAME="S3">3. Writing applications</a></h3>
-
-<h4><a NAME="S3.1">3.1 Using the <tt>fcgi_stdio</tt> library</a> </h4>
-
-<p>The <tt>fcgi_stdio</tt> library provides the easiest transition for C CGI programs and
-C CGI programmers to FastCGI. Using this library your application can run using either CGI
-or FastCGI, with the same binary for both situations.</p>
-
-<p>To introduce the <tt>fcgi_stdio</tt> 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.</p>
-
-<p>The CGI program is <tt>examples/tiny-cgi.c</tt>:</p>
-
-<pre>
-    #include &lt;stdio.h&gt;
-    #include &lt;stdlib.h&gt;
-
-    void main(void)
-    {
-        int count = 0;
-        printf(&quot;Content-type: text/html\r\n&quot;
-               &quot;\r\n&quot;
-               &quot;&lt;title&gt;CGI Hello!&lt;/title&gt;&quot;
-               &quot;&lt;h1&gt;CGI Hello!&lt;/h1&gt;&quot;
-               &quot;Request number %d running on host &lt;i&gt;%s&lt;/i&gt;\n&quot;,
-               ++count, getenv(&quot;SERVER_NAME&quot;));
-    }
-</pre>
-
-<p>The key features of this tiny CGI program are:
-
-<ul type="square">
-  <li>The program sends data to the Web server by writing to <tt>stdout</tt>, using <tt>printf</tt>
-    in this example. The CGI program first sends a <tt>Content-type</tt> header, then a small
-    HTML document. The program includes <tt>stdio.h</tt> in order to get access to the <tt>printf</tt>
-    function.</li>
-  <li>The program obtains parameters provided by the Web server by reading environment
-    variables. The CGI program reads the <tt>SERVER_NAME</tt> variable using <tt>getenv</tt>
-    and includes the value in the HTML document. The program includes <tt>stdlib.h</tt> in
-    order to get access to the <tt>getenv</tt> function.</li>
-</ul>
-
-<p>The <tt>count</tt> variable is degenerate in this example; the CGI program runs a
-single request, so the request number is always one. This variable will be more
-interesting in the FastCGI example.</p>
-
-<p><a NAME="S3.1.1">The</a> corresponding FastCGI program is <tt>examples/tiny-fcgi.c</tt>:</p>
-
-<pre>
-    #include &quot;fcgi_stdio.h&quot;
-    #include &lt;stdlib.h&gt;
-
-    void main(void)
-    {
-        int count = 0;
-        while(FCGI_Accept() &gt;= 0)
-            printf(&quot;Content-type: text/html\r\n&quot;
-                   &quot;\r\n&quot;
-                   &quot;&lt;title&gt;FastCGI Hello!&lt;/title&gt;&quot;
-                   &quot;&lt;h1&gt;FastCGI Hello!&lt;/h1&gt;&quot;
-                   &quot;Request number %d running on host &lt;i&gt;%s&lt;/i&gt;\n&quot;,
-                    ++count, getenv(&quot;SERVER_NAME&quot;));
-    }
-</pre>
-
-<p>The key features of this tiny FastCGI program are:
-
-<ul type="square">
-  <li>The program is structured as a loop that begins by calling the function <tt>FCGI_Accept</tt>.
-    The <tt>FCGI_Accept</tt> function blocks until a new request arrives for the program to
-    execute. The program includes <tt>fcgi_stdio.h</tt> in order to get access to the <tt>FCGI_Accept</tt>
-    function.</li>
-  <li>Within the loop, <tt>FCGI_Accept</tt> creates a CGI-compatible world. <tt>printf</tt>
-    and <tt>getenv</tt> operate just as in the CGI program. <tt>stdin</tt> and <tt>stderr</tt>,
-    not used by this tiny program, also operate just as in a CGI program.</li>
-</ul>
-
-<p>The <tt>count</tt> variable increments each time through the loop, so the program
-displays a new request number each time. You can use the reload button in your browser to
-demonstrate this, once you've got the program built and running.</p>
-
-<h4>Building the program</h4>
-
-<p>If you can build <tt>examples/tiny-cgi.c</tt>, it will be straightforward for you to
-build <tt>examples/tiny-fcgi.c</tt>. You need to:
-
-<ul type="square">
-  <li>Add the directory containing the <tt>fcgi_stdio.h</tt> header to the compiler's include
-    search path. The kit calls this directory <tt>include</tt>.</li>
-  <li>Add the library <tt>libfcgi.a</tt> to the linker's command line so that it will be
-    searched when linking. The <tt>libfcgi.a</tt> library implements the functions defined in <tt>fcgi_stdio.h</tt>.
-    The kit calls the directory containing this library <tt>libfcgi</tt>.</li>
-  <li>Determine whether or not the linker on your platform searches the Berkeley socket
-    library by default, and if not, add linker directives to force this search.</li>
-</ul>
-
-<p>See <tt>examples/Makefile</tt> (created by <tt>configure</tt>) for a Makefile that
-builds both programs. Autoconf handles the platform-dependent linking issues; to see how,
-examine <tt>configure.in</tt> and <tt>examples/Makefile.in</tt>.</p>
-
-<h4>Running the program</h4>
-<p>
-
-<a href="#S4">Section 4</a> is all about how to run FastCGI applications.</p>
-
-<p>You can use CGI to run application binaries built with the <tt>fcgi_stdio</tt> library.
-The <tt>FCGI_Accept</tt> 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 <tt>-1</tt>. In effect, the request loop
-disappears.</p>
-
-<p>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.</p>
-
-<h4>Implementation details</h4>
-<p>
-
-<tt>fcgi_stdio.h</tt> works by first including <tt>stdio.h</tt>, then defining macros to
-replace essentially all of the types and procedures defined in <tt>stdio.h</tt>. (<tt>stdio.h</tt>
-defines a few procedures that have nothing to do with <tt>FILE *</tt>, such as <tt>sprintf</tt>
-and <tt>sscanf</tt>; <tt>fcgi_stdio.h</tt> doesn't replace these.) For instance, <tt>FILE</tt>
-becomes <tt>FCGI_FILE</tt> and <tt>printf</tt> becomes <tt>FCGI_printf</tt>. You'll only
-see these new names if you read <tt>fcgi_stdio.h</tt> or examine your C source code after
-preprocessing.</p>
-
-<p>Here are some consequences of this implementation technique:
-
-<ul type="square">
-  <li>On some platforms the implementation will break if you include <tt>stdio.h</tt> after
-    including <tt>fcgi_stdio.h</tt>, because <tt>stdio.h</tt> often defines macros for
-    functions such as <tt>getc</tt> and <tt>putc</tt>. Fortunately, on most platforms <tt>stdio.h</tt>
-    is protected against multiple includes by lines near the top of the file that look like <pre>
-    #ifndef _STDIO_H
-    #define _STDIO_H
-    </pre>
-    <p>The specific symbol used for multiple-include protection, <tt>_STDIO_H</tt> in this
-    example, varies from platform to platform. As long as your platform protects <tt>stdio.h</tt>
-    against multiple includes, you can forget about this issue.</p>
-  </li>
-  <li>If your application passes <tt>FILE *</tt> to functions implemented in libraries for
-    which you have source code, then you'll want to recompile these libraries with <tt>fcgi_stdio.h</tt>
-    included. Most C compilers provide a command-line option for including headers in a
-    program being compiled; using such a compiler feature allows you to rebuild your libraries
-    without making source changes. For instance the gcc command line <pre>
-    gcc -include /usr/local/include/fcgi_stdio.h wonderlib.c
-    </pre>
-    <p>causes gcc to include <tt>fcgi_stdio.h</tt> before it even begins to read the module <tt>wonderlib.c</tt>.</p>
-  </li>
-  <li>If your application passes <tt>FILE *</tt> to functions implemented in libraries for
-    which you do not have source code, then you'll need to include the headers for these
-    libraries <i>before</i> you include <tt>fcgi_stdio.h</tt>. You can't pass the <tt>stdin</tt>,
-    <tt>stdout</tt>, or <tt>stderr</tt> streams produced by <tt>FCGI_Accept</tt> to any
-    functions implemented by these libraries. You can pass a stream on a Unix file to a
-    library function by following this pattern: <pre>
-    FILE *myStream = fopen(path, &quot;r&quot;);
-    answer = MungeStream(FCGI_ToFile(myStream));
-    </pre>
-    <p>Here <tt>MungeStream</tt> is a library function that you can't recompile and <tt>FCGI_ToFile</tt>
-    is a macro that converts from <tt>FCGI_FILE *</tt> to <tt>FILE *</tt>. The macro <tt>FCGI_ToFile</tt>
-    is defined in <tt>fcgi_stdio.h</tt>.</p>
-  </li>
-</ul>
-
-<h4>Converting CGI programs</h4>
-
-<p>The main task in converting a CGI program into a FastCGI program is separating the code
-that needs to execute once, initializing the program, from the code that needs to run for
-each request. In our tiny example, initializing the <tt>count</tt> variable is outside the
-loop, while incrementing the <tt>count</tt> variable goes inside.</p>
-
-<p>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.</p>
-
-<p>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 <a href="http://www.pure.com/"><i>Purify</i></a>
-from Pure Software to discover and fix storage leaks, or you can run a C garbage collector
-such as <a href="http://www.geodesic.com/"><i>Great Circle</i></a> from Geodesic Systems.</p>
-
-<h4>Limitations</h4>
-
-<p>Currently there are some limits to the compatibility provided by the <tt>fcgi_stdio</tt>
-library:
-
-<ul type="square">
-  <li>The library does not provide FastCGI versions of the functions <tt>fscanf</tt> and <tt>scanf</tt>.
-    If you wish to apply <tt>fscanf</tt> or <tt>scanf</tt> to <tt>stdin</tt> of a FastCGI
-    program, the workaround is to read lines or other natural units into memory and then call <tt>sscanf</tt>.
-    If you wish to apply <tt>fscanf</tt> to a stream on a Unix file, the workaround is to
-    follow the pattern: <pre>
-    FILE *myStream = fopen(path, &quot;r&quot;);
-    count = fscanf(FCGI_ToFile(myStream), format, ...);
-    </pre>
-  </li>
-</ul>
-
-<h4>Reference documentation</h4>
-
-<p>The <a href="FCGI_Accept.3"><tt>FCGI_Accept</tt> manpage</a>, <tt>doc/FCGI_Accept.3</tt>,
-describes the function in the traditional format.</p>
-
-<p>The <a href="FCGI_Finish.3"><tt>FCGI_Finish</tt></a> (<tt>doc/FCGI_Finish.3</tt>), <a
-href="FCGI_SetExitStatus.3"><tt>FCGI_SetExitStatus</tt></a> (<tt>doc/FCGI_SetExitStatus.3</tt>),
-and <a href="FCGI_StartFilterData.3"><tt>FCGI_StartFilterData</tt></a> (<tt>doc/FCGI_StartFilterData.3</tt>)
-manpages document capabilities of the <tt>fcgi-stdio</tt> library that are not illustrated
-above.</p>
-
-<h4><a NAME="S3.2">3.2 Using the <tt>fcgiapp</tt> library</a></h4>
-
-<p>The <tt>fcgiapp</tt> library is a second C library for FastCGI. It does not provide the
-high degree of source code compatibility provided by <tt>fcgi_stdio</tt>; in return, it
-does not make such heavy use of <tt>#define</tt>. <tt>fcgi_stdio</tt> is implemented as a
-thin layer on top of <tt>fcgiapp</tt>.</p>
-
-<p>Applications built using the <tt>fcgiapp</tt> library cannot run as CGI programs; that
-feature is provided at the <tt>fcgi_stdio</tt> level.</p>
-
-<p>Functions defined in <tt>fcgiapp</tt> are named using the prefix <tt>FCGX_</tt> rather
-than <tt>FCGI_</tt>. For instance, <tt>FCGX_Accept</tt> is the <tt>fcgiapp</tt> version of
-<tt>FCGI_Accept</tt>.</p>
-
-<p>Documentation of the <tt>fcgiapp</tt> library takes the form of extensive comments in
-the header file <tt>include/fcgiapp.h</tt>. The sample programs <tt>examples/tiny-fcgi2.c</tt>
-and <tt>examples/echo2.c</tt> illustrate how to use <tt>fcgiapp</tt>.</p>
-
-<h4><a NAME="S3.3">3.3 Using Perl and Tcl</a></h4>
-
-<p>A major advantage of the FastCGI approach to high-performance Web applications is its
-language-neutrality. CGI scripts written in popular languages such as Perl and Tcl can be
-evolved into high-performance FastCGI applications.</p>
-
-<p>We have produced FastCGI-integrated Perl and Tcl interpreters. Doing so was easy, since
-Perl and Tcl are conventional C applications and <tt>fcgi_stdio</tt> 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 <tt>FCGI_Accept</tt>
-and other FastCGI primitives available in these languages. And because these interpreters
-were developed using <tt>fcgi_stdio</tt>, they run standard Perl and Tcl applications
-(e.g. CGI scripts) as well as FastCGI applications.</p>
-
-<p>See the <a href="http://fastcgi.com">fastcgi.com</a> Web page for more information 
-  about the Perl and Tcl libraries.</p>
-
-<p>Here are the Perl and Tcl versions of <tt>tiny-fcgi</tt>:</p>
-
-<pre>
-#!./perl
-use FCGI;
-$count = 0;
-while(FCGI::accept() &gt;= 0) {
-    print(&quot;Content-type: text/html\r\n\r\n&quot;,
-          &quot;&lt;title&gt;FastCGI Hello! (Perl)&lt;/title&gt;\n&quot;,
-          &quot;&lt;h1&gt;FastCGI Hello! (Perl)&lt;/h1&gt;\n&quot;;
-          &quot;Request number &quot;,  ++$count,
-          &quot; running on host &lt;i&gt;&quot;;$env(SERVER_NAME)&lt;/i&gt;&quot;);
-}
-</pre>
-
-<pre>
-#!./tclsh
-set count 0 
-while {[FCGI_Accept] &gt;= 0 } {
-    incr count
-    puts -nonewline &quot;Content-type: text/html\r\n\r\n&quot;
-    puts &quot;&lt;title&gt;FastCGI Hello! (Tcl)&lt;/title&gt;&quot;
-    puts &quot;&lt;h1&gt;FastCGI Hello! (Tcl)&lt;/h1&gt;&quot;
-    puts &quot;Request number $count running on host &lt;i&gt;$env(SERVER_NAME)&lt;/i&gt;&quot;
-}
-</pre>
-
-<p>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 <tt>FCGI::accept</tt>
-(Perl) or <tt>FCGI_Accept</tt> (Tcl). </p>
-
-<h4><a NAME="S3.4">3.4 Using Java</a></h4>
-
-<p>Java is not just for browser-based applets. It is already suitable for writing some Web
-server applications, and its range of applicability will only grow as Java compilers and
-other Java tools improve. Java's modules, garbage collection, and threads are especially
-valuable for writing long-lived application servers.</p>
-
-<p>The <tt>FCGIInterface</tt> class provides facilities for Java applications analogous to
-what <tt>fcgi_stdio</tt> provides for C applications. Using this library your Java
-application can run using either CGI or FastCGI.</p>
-
-<p>The kit includes separate companion document on <a href="fcgi-java.htm">using FastCGI
-with Java</a>. The source code for FastCGI classes is contained in directory <tt>java/src</tt>
-and the compiled code in <tt>java/classes</tt>.</p>
-
-<p>Here is the Java version of <tt>tiny-fcgi</tt>:</p>
-
-<pre>
-import FCGIInterface;
-
-class TinyFCGI {       
-    public static void main (String args[]) {          
-        int count = 0;
-        while(new FCGIInterface().FCGIaccept()&gt;= 0) {
-            count ++;
-            System.out.println(&quot;Content-type: text/html\r\n\r\n&quot;);
-            System.out.println(
-                    &quot;&lt;title&gt;FastCGI Hello! (Java)&lt;/title&gt;&quot;);
-            System.out.println(&quot;&lt;h1&gt;FastCGI Hello! (Java)&lt;/h1&gt;&quot;);
-            System.out.println(
-                    &quot;request number &quot; + count + &quot; running on host &lt;i&gt;&quot; +
-                    System.getProperty(&quot;SERVER_NAME&quot;) + &quot;&lt;/i&gt;&quot;);
-        }
-    }
-}
-</pre>
-
-<h3><a NAME="S4">4. Running applications</a></h3>
-
-<h3><a NAME="S4.1">4.1 Using a Web server that supports FastCGI</a></h3>
-
-<p>For a current listing of Web servers that support FastCGI, see the <a
-HREF="http://fastcgi.com">fastcgi.com</a> Web page.</p>
-
-<p>Some 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.</p>
-
-<p>Web servers support FastCGI via new configuration directives. Since these directives 
-  are server-specific, get more information from the documentation that accompanies 
-  each server.</p>
-
-<h3><a NAME="S4.2">4.2 Using <tt>cgi-fcgi</tt> with any Web server</a></h3>
-
-<p>The program <tt>cgi-fcgi</tt> allows you to run FastCGI applications using any Web
-server that supports CGI.</p>
-
-<p>Here is how <tt>cgi-fcgi</tt> works. <tt>cgi-fcgi</tt> is a standard CGI program that
-uses Unix domain or TCP/IP sockets to communicate with a FastCGI application. <tt>cgi-fcgi</tt>
-takes the path name or host/port name of a listening socket as a parameter and <tt>connect</tt>s
-to the FastCGI application listening on that socket. <tt>cgi-fcgi</tt> then forwards the
-CGI environment variables and <tt>stdin</tt> data to the FastCGI application, and forwards
-the <tt>stdout</tt> and <tt>stderr</tt> data from the FastCGI application to the Web
-server. When the FastCGI application signals the end of its response, <tt>cgi-fcgi</tt>
-flushes its buffers and exits.</p>
-
-<p>Obviously, having <tt>cgi-fcgi</tt> is not as good as having a server with integrated
-FastCGI support:
-
-<ul>
-  <li>Communication is slower than with a Web server that avoids the fork/exec overhead on
-    every FastCGI request. </li>
-  <li><tt>cgi-fcgi</tt> does not perform application management, so you need to provide this
-    yourself. </li>
-  <li><tt>cgi-fcgi</tt> supports only the Responder role. </li>
-</ul>
-
-<p>But <tt>cgi-fcgi</tt> does allow you to develop applications that retain state in
-memory between connections, which often provides a major performance boost over normal
-CGI. And all the applications you develop using <tt>cgi-fcgi</tt> will work with Web
-servers that have integrated support for FastCGI.</p>
-
-<p>The file <tt>examples/tiny-fcgi.cgi</tt> demonstrates a way to use <tt>cgi-fcgi</tt> to
-run a typical application, in this case the <tt>examples/tiny-fcgi</tt> application: </p>
-
-<pre>
-    #!../cgi-fcgi/cgi-fcgi -f
-    -connect sockets/tiny-fcgi tiny-fcgi
-</pre>
-
-<p>On most Unix platforms, executing this command-interpreter file runs <tt>cgi-fcgi</tt>
-with arguments <tt>-f</tt> and <tt>examples/tiny-fcgi.cgi</tt>. (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 <tt>cgi-fcgi</tt>
-application in a standard place like <tt>/usr/local/bin</tt> or create a symbolic link to
-the <tt>cgi-fcgi</tt> application in the directory containing your application.) The <tt>cgi-fcgi</tt>
-program reads the command-interpreter file and connects to the FastCGI application whose
-listening socket is <tt>examples/sockets/tiny-fcgi</tt>.</p>
-
-<p>Continuing the example, if <tt>cgi-fcgi</tt>'s connection attempt fails, it creates a
-new process running the program <tt>examples/tiny-fcgi</tt> and listening on socket <tt>examples/sockets/tiny-fcgi</tt>.
-Then <tt>cgi-fcgi</tt> retries the connection attempt, which now should succeed.</p>
-
-<p>The <tt>cgi-fcgi</tt> 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 <a href="cgi-fcgi.1"><tt>cgi-fcgi</tt>
-manpage</a>, <tt>doc/cgi-fcgi.1</tt>, tells the full story.</p>
-
-<p>To run the example applications using <tt>cgi-fcgi</tt>, start your Web server and give
-it the directory <tt>fcgi-devel-kit</tt> as the root of its URL space. If the machine
-running your server is called <tt>bowser</tt> and your server is running on port <tt>8888</tt>,
-you'd then open the URL <tt>http://bowser:8888/index.html</tt> to reach the kit's index
-page. Now the links on the index page that run example applications via <tt>cgi-fcgi</tt>
-should be active.</p>
-
-<h3><a NAME="S5">5. Known problems</a></h3>
-
-<p>On Digital UNIX 3.0 there's a problem with Unix domain listening sockets on NFS file
-systems. The symptom when using cgi-fcgi is an exit status of 38 (<tt>ENOTSOCK</tt>:
-socket operation on non-socket), but cgi-fcgi may dump core in this case when compiled
-optimized. Work-around: Store your Unix domain listening sockets on a non NFS file system,
-upgrade to Digital UNIX 3.2, or use TCP sockets.</p>
-
-<p>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.</p>
-
-<h3><a NAME="S6">6. Getting support</a></h3>
-
-<p>The mailing list <tt>fastcgi-developers@idle.com</tt> is used for discussions of issues
-in developing FastCGI applications. Topics include announcement of FastCGI-capable Web
-servers or changes to such servers, announcement of new application libraries or changes
-to such libraries, announcement of known bugs, discussion of design trade-offs in FastCGI
-application programming, and discussion of development plans and experiences. To join the
-list, send a message to <a href="mailto:fastcgi-developers-request@openmarket.com">fastcgi-developers-request@idle.com</a>
-with a message body consisting of the word &quot;subscribe&quot; (leaving off the quotes).</p>
-
-<p>A link to a mail archive can be found on the FastCGI home page, <a
-href="http://www.fastcgi.com">http://www.fastcgi.com</a></p>
-
-<hr>
-
-<address>
-  © 1996, Open Market, Inc. / mbrown@openmarket.com 
-</address>
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r
+<HTML>\r
+   <HEAD>\r
+      <TITLE>\r
+         FastCGI Developer&#39;s Kit\r
+      </TITLE>\r
+<STYLE TYPE="text/css">\r
+ body {\r
+  background-color: #FFFFFF;\r
+  color: #000000;\r
+ }\r
+ :link { color: #cc0000 }\r
+ :visited { color: #555555 }\r
+ :active { color: #000011 }\r
+ h5.c3 {text-align: center}\r
+ h3.c2 {text-align: center}\r
+ p.c1 {text-align: center}\r
+</STYLE>\r
+   </HEAD>\r
+   <BODY>\r
+      <P CLASS="c1">\r
+         <IMG BORDER="0" SRC="../images/fcgi-hd.gif" ALT="[[FastCGI]]"><BR CLEAR="all">\r
+      </P>\r
+      <H3 CLASS="c2">\r
+         FastCGI Developer&#39;s Kit\r
+      </H3>\r
+      <!--Copyright (c) 1996 Open Market, Inc.                                    -->\r
+      <!--See the file "LICENSE.TERMS" for information on usage and redistribution-->\r
+      <!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->\r
+      <P CLASS="c1">\r
+         Mark R. Brown<BR>\r
+          Open Market, Inc.<BR>\r
+      </P>\r
+      <P CLASS="c1">\r
+         Document Version: 1.08<BR>\r
+          11 June 1996<BR>\r
+      </P>\r
+      <H5 CLASS="c3">\r
+         Copyright &copy; 1996 Open Market, Inc. 245 First Street, Cambridge, MA 02142 U.S.A.<BR>\r
+          Tel: 617-621-9500 Fax: 617-621-1703 URL: <A HREF=\r
+         "http://www.openmarket.com/">http://www.openmarket.com/</A><BR>\r
+          $Id: fcgi-devel-kit.htm,v 1.4 2001/11/27 01:03:47 robs Exp $<BR>\r
+      </H5>\r
+      <HR>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            <A HREF="#S1">1. Introduction</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S2">2. Getting started</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S3">3. Writing applications</A> \r
+            <UL TYPE="square">\r
+               <LI>\r
+                  <A HREF="#S3.1">3.1 Using the <TT>fcgi_stdio</TT> library</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S3.2">3.2 Using the <TT>fcgiapp</TT> library</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S3.3">3.3 Using Perl and Tcl</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S3.4">3.4 Using Java</A>\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S4">4. Running applications</A> \r
+            <UL TYPE="square">\r
+               <LI>\r
+                  <A HREF="#S4.1">4.1 Using a Web server that supports FastCGI</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S4.2">4.2 Using <TT>cgi-fcgi</TT> with any Web server</A>\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S5">5. Known problems</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S6">6. Getting support</A>\r
+         </LI>\r
+      </UL>\r
+      <HR>\r
+      <H3>\r
+         <A NAME="S1">1. Introduction</A>\r
+      </H3>\r
+      <P>\r
+         FastCGI is an open extension to CGI that provides high performance for all Internet applications without the\r
+         penalties of Web server APIs.\r
+      </P>\r
+      <P>\r
+         FastCGI is designed to be layered on top of existing Web server APIs. For instance, the <TT>mod_fastcgi</TT>\r
+         Apache module adds FastCGI support to the Apache server. FastCGI can also be used, with reduced functionality\r
+         and reduced performance, on any Web server that supports CGI.\r
+      </P>\r
+      <P>\r
+         This FastCGI Developer&#39;s Kit is designed to make developing FastCGI applications easy. The kit currently\r
+         supports FastCGI applications written in C/C++, Perl, Tcl, and Java.\r
+      </P>\r
+      <P>\r
+         This document:\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            Describes how to configure and build the kit for your development platform.\r
+         </LI>\r
+         <LI>\r
+            Tells how to write applications using the libraries in the kit.\r
+         </LI>\r
+         <LI>\r
+            Tells how to run applications using Web servers that support FastCGI or using any Web server and\r
+            <TT>cgi-fcgi</TT>.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         The kit includes a <A HREF="fastcgi-whitepaper/fastcgi.htm">technical white paper</A>,\r
+         <TT>doc/fastcgi-whitepaper/fastcgi.htm</TT>. You should read at least the first three sections of the\r
+         technical white paper before starting to write FastCGI applications. The <A HREF="fcgi-perf.htm">performance\r
+         paper</A> will help you understand how application design affects performance with FastCGI.\r
+      </P>\r
+      <P>\r
+         The <A HREF="fcgi-spec.html">FastCGI Specification</A>, <TT>doc/fcgi-spec.html</TT>, defines the interface\r
+         between a FastCGI application and a Web server that supports FastCGI. The software in the kit implements the\r
+         specification. You don&#39;t need to read the specification in order to write applications.\r
+      </P>\r
+      <P>\r
+         Additional information is provided in the <A HREF="http://fastcgi.com/docs/faq.html">FAQ</A> document, which\r
+         contains frequently asked questions about application development using FastCGI, as well as some general\r
+         information.\r
+      </P>\r
+      <P>\r
+         Experience with CGI programming will be extremely valuable in writing FastCGI applications. If you don&#39;t\r
+         have enough experience with CGI programming, you should read one of the popular books on the topic or study\r
+         the <A HREF="http://hoohoo.ncsa.uiuc.edu/cgi/">NCSA CGI page</A>. For a more formal treatment of CGI/1.1 see\r
+         the <A HREF="http://cgi-spec.golux.com/">Internet Draft CGI 1.1 Specification</A>.\r
+      </P>\r
+      <H3>\r
+         <A NAME="S2">2. Getting started</A>\r
+      </H3>\r
+      <P>\r
+         The kit is a compressed tar (tar.Z) file, distributed via the <A HREF="http://fastcgi.com/">fastcgi.com</A>\r
+         Web page. Unpacking the tar file creates a new directory <TT>fcgi-devel-kit</TT>.\r
+      </P>\r
+      <P>\r
+         Open the kit&#39;s index page, <TT>fcgi-devel-kit/index.html</TT>, using the &quot;Open File&quot; command in\r
+         your Web browser. The index page gives you an overview of the kit structure and helps you navigate the kit.\r
+         The index page also contains links that run some example applications, but the applications won&#39;t work\r
+         when index.html is opened using the &quot;Open File&quot; command because they aren&#39;t aren&#39;t being\r
+         accessed through a Web server.\r
+      </P>\r
+      <P>\r
+         In order to use the kit in earnest you&#39;ll need a Web server that you control, a Web server running with\r
+         your user ID. The Web server will be starting FastCGI applications that you will need to debug; this will be a\r
+         lot more convenient for you if these processes run with your user ID. It is best to have a Web server that\r
+         supports FastCGI. <A HREF="#S4">Section 4</A> discusses Web server issues.\r
+      </P>\r
+      <P>\r
+         If you can, keep the kit on a file system accessible from your personal workstation, do your builds on your\r
+         workstation, and run your Web server on your workstation. If that&#39;s not possible, arrange a configuration\r
+         such that the kit is accessible from the machine that&#39;s going to run your Web server, and build the kit\r
+         and your applications on a machine that&#39;s configured exactly the same way (same processor architecture,\r
+         operating system, etc.) as the machine that&#39;s going to run your Web server.\r
+      </P>\r
+      <P>\r
+         To build the kit you execute this sequence of commands in the <TT>fcgi-devel-kit</TT> directory:\r
+      </P>\r
+<PRE>\r
+    % ./configure\r
+    % make\r
+</PRE>\r
+      <P>\r
+         We&#39;ve built and exercised the kit on these platforms (listed in alphabetical order):\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            BSD/OS 1.1 (Intel Pentium), gcc\r
+         </LI>\r
+         <LI>\r
+            Digital UNIX V3.2 148 (Alpha), gcc/cc\r
+         </LI>\r
+         <LI>\r
+            Hewlett-Packard HP-UX A.09.05 C and B.10.01 A (PA-RISC), gcc/cc\r
+         </LI>\r
+         <LI>\r
+            IBM AIX 1 4 (RS/6000), gcc\r
+         </LI>\r
+         <LI>\r
+            Silicon Graphics IRIX 5.3 11091812 (MIPS), gcc\r
+         </LI>\r
+         <LI>\r
+            Sun Solaris 2.4 and 2.5 (SPARC), gcc/cc\r
+         </LI>\r
+         <LI>\r
+            Sun SunOS 4.1.4 (SPARC), gcc\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         Once you&#39;ve built the kit, follow the directions in <A HREF="#S4">Section 4</A> to bring up your Web\r
+         server and run the example applications.\r
+      </P>\r
+      <H3>\r
+         <A NAME="S3">3. Writing applications</A>\r
+      </H3>\r
+      <H4>\r
+         <A NAME="S3.1">3.1 Using the <TT>fcgi_stdio</TT> library</A>\r
+      </H4>\r
+      <P>\r
+         The <TT>fcgi_stdio</TT> library provides the easiest transition for C CGI programs and C CGI programmers to\r
+         FastCGI. Using this library your application can run using either CGI or FastCGI, with the same binary for\r
+         both situations.\r
+      </P>\r
+      <P>\r
+         To introduce the <TT>fcgi_stdio</TT> library we give a pair of examples: a tiny CGI program and the\r
+         translation of this program to FastCGI. These two example programs are included in the kit.\r
+      </P>\r
+      <P>\r
+         The CGI program is <TT>examples/tiny-cgi.c</TT>:\r
+      </P>\r
+<PRE>\r
+    #include &lt;stdio.h&gt;\r
+    #include &lt;stdlib.h&gt;\r
+\r
+    void main(void)\r
+    {\r
+        int count = 0;\r
+        printf(&quot;Content-type: text/html\r\n&quot;\r
+               &quot;\r\n&quot;\r
+               &quot;&lt;title&gt;CGI Hello!&lt;/title&gt;&quot;\r
+               &quot;&lt;h1&gt;CGI Hello!&lt;/h1&gt;&quot;\r
+               &quot;Request number %d running on host &lt;i&gt;%s&lt;/i&gt;\n&quot;,\r
+               ++count, getenv(&quot;SERVER_NAME&quot;));\r
+    }\r
+</PRE>\r
+      <P>\r
+         The key features of this tiny CGI program are:\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            The program sends data to the Web server by writing to <TT>stdout</TT>, using <TT>printf</TT> in this\r
+            example. The CGI program first sends a <TT>Content-type</TT> header, then a small HTML document. The\r
+            program includes <TT>stdio.h</TT> in order to get access to the <TT>printf</TT> function.\r
+         </LI>\r
+         <LI>\r
+            The program obtains parameters provided by the Web server by reading environment variables. The CGI program\r
+            reads the <TT>SERVER_NAME</TT> variable using <TT>getenv</TT> and includes the value in the HTML document.\r
+            The program includes <TT>stdlib.h</TT> in order to get access to the <TT>getenv</TT> function.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         The <TT>count</TT> variable is degenerate in this example; the CGI program runs a single request, so the\r
+         request number is always one. This variable will be more interesting in the FastCGI example.\r
+      </P>\r
+      <P>\r
+         <A NAME="S3.1.1">The</A> corresponding FastCGI program is <TT>examples/tiny-fcgi.c</TT>:\r
+      </P>\r
+<PRE>\r
+    #include &quot;fcgi_stdio.h&quot;\r
+    #include &lt;stdlib.h&gt;\r
+\r
+    void main(void)\r
+    {\r
+        int count = 0;\r
+        while(FCGI_Accept() &gt;= 0)\r
+            printf(&quot;Content-type: text/html\r\n&quot;\r
+                   &quot;\r\n&quot;\r
+                   &quot;&lt;title&gt;FastCGI Hello!&lt;/title&gt;&quot;\r
+                   &quot;&lt;h1&gt;FastCGI Hello!&lt;/h1&gt;&quot;\r
+                   &quot;Request number %d running on host &lt;i&gt;%s&lt;/i&gt;\n&quot;,\r
+                    ++count, getenv(&quot;SERVER_NAME&quot;));\r
+    }\r
+</PRE>\r
+      <P>\r
+         The key features of this tiny FastCGI program are:\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            The program is structured as a loop that begins by calling the function <TT>FCGI_Accept</TT>. The\r
+            <TT>FCGI_Accept</TT> function blocks until a new request arrives for the program to execute. The program\r
+            includes <TT>fcgi_stdio.h</TT> in order to get access to the <TT>FCGI_Accept</TT> function.\r
+         </LI>\r
+         <LI>\r
+            Within the loop, <TT>FCGI_Accept</TT> creates a CGI-compatible world. <TT>printf</TT> and <TT>getenv</TT>\r
+            operate just as in the CGI program. <TT>stdin</TT> and <TT>stderr</TT>, not used by this tiny program, also\r
+            operate just as in a CGI program.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         The <TT>count</TT> variable increments each time through the loop, so the program displays a new request\r
+         number each time. You can use the reload button in your browser to demonstrate this, once you&#39;ve got the\r
+         program built and running.\r
+      </P>\r
+      <H4>\r
+         Building the program\r
+      </H4>\r
+      <P>\r
+         If you can build <TT>examples/tiny-cgi.c</TT>, it will be straightforward for you to build\r
+         <TT>examples/tiny-fcgi.c</TT>. You need to:\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            Add the directory containing the <TT>fcgi_stdio.h</TT> header to the compiler&#39;s include search path.\r
+            The kit calls this directory <TT>include</TT>.\r
+         </LI>\r
+         <LI>\r
+            Add the library <TT>libfcgi.a</TT> to the linker&#39;s command line so that it will be searched when\r
+            linking. The <TT>libfcgi.a</TT> library implements the functions defined in <TT>fcgi_stdio.h</TT>. The kit\r
+            calls the directory containing this library <TT>libfcgi</TT>.\r
+         </LI>\r
+         <LI>\r
+            Determine whether or not the linker on your platform searches the Berkeley socket library by default, and\r
+            if not, add linker directives to force this search.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         See <TT>examples/Makefile</TT> (created by <TT>configure</TT>) for a Makefile that builds both programs.\r
+         Autoconf handles the platform-dependent linking issues; to see how, examine <TT>configure.in</TT> and\r
+         <TT>examples/Makefile.in</TT>.\r
+      </P>\r
+      <H4>\r
+         Running the program\r
+      </H4>\r
+      <P>\r
+         <A HREF="#S4">Section 4</A> is all about how to run FastCGI applications.\r
+      </P>\r
+      <P>\r
+         You can use CGI to run application binaries built with the <TT>fcgi_stdio</TT> library. The\r
+         <TT>FCGI_Accept</TT> function tests its environment to determine how the application was invoked. If it was\r
+         invoked as a CGI program, the first call to FCGI_Accept is essentially a no-op and the second call returns\r
+         <TT>-1</TT>. In effect, the request loop disappears.\r
+      </P>\r
+      <P>\r
+         Of course, when a FastCGI application is run using CGI it does not get the benefits of FastCGI. For instance,\r
+         the application exits after servicing a single request, so it cannot maintain cached information.\r
+      </P>\r
+      <H4>\r
+         Implementation details\r
+      </H4>\r
+      <P>\r
+         <TT>fcgi_stdio.h</TT> works by first including <TT>stdio.h</TT>, then defining macros to replace essentially\r
+         all of the types and procedures defined in <TT>stdio.h</TT>. (<TT>stdio.h</TT> defines a few procedures that\r
+         have nothing to do with <TT>FILE *</TT>, such as <TT>sprintf</TT> and <TT>sscanf</TT>; <TT>fcgi_stdio.h</TT>\r
+         doesn&#39;t replace these.) For instance, <TT>FILE</TT> becomes <TT>FCGI_FILE</TT> and <TT>printf</TT> becomes\r
+         <TT>FCGI_printf</TT>. You&#39;ll only see these new names if you read <TT>fcgi_stdio.h</TT> or examine your C\r
+         source code after preprocessing.\r
+      </P>\r
+      <P>\r
+         Here are some consequences of this implementation technique:\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            On some platforms the implementation will break if you include <TT>stdio.h</TT> after including\r
+            <TT>fcgi_stdio.h</TT>, because <TT>stdio.h</TT> often defines macros for functions such as <TT>getc</TT>\r
+            and <TT>putc</TT>. Fortunately, on most platforms <TT>stdio.h</TT> is protected against multiple includes\r
+            by lines near the top of the file that look like \r
+<PRE>\r
+    #ifndef _STDIO_H\r
+    #define _STDIO_H\r
+   \r
+</PRE>\r
+            <P>\r
+               The specific symbol used for multiple-include protection, <TT>_STDIO_H</TT> in this example, varies from\r
+               platform to platform. As long as your platform protects <TT>stdio.h</TT> against multiple includes, you\r
+               can forget about this issue.\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            If your application passes <TT>FILE *</TT> to functions implemented in libraries for which you have source\r
+            code, then you&#39;ll want to recompile these libraries with <TT>fcgi_stdio.h</TT> included. Most C\r
+            compilers provide a command-line option for including headers in a program being compiled; using such a\r
+            compiler feature allows you to rebuild your libraries without making source changes. For instance the gcc\r
+            command line \r
+<PRE>\r
+    gcc -include /usr/local/include/fcgi_stdio.h wonderlib.c\r
+   \r
+</PRE>\r
+            <P>\r
+               causes gcc to include <TT>fcgi_stdio.h</TT> before it even begins to read the module\r
+               <TT>wonderlib.c</TT>.\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            If your application passes <TT>FILE *</TT> to functions implemented in libraries for which you do not have\r
+            source code, then you&#39;ll need to include the headers for these libraries <I>before</I> you include\r
+            <TT>fcgi_stdio.h</TT>. You can&#39;t pass the <TT>stdin</TT>, <TT>stdout</TT>, or <TT>stderr</TT> streams\r
+            produced by <TT>FCGI_Accept</TT> to any functions implemented by these libraries. You can pass a stream on\r
+            a Unix file to a library function by following this pattern: \r
+<PRE>\r
+    FILE *myStream = fopen(path, &quot;r&quot;);\r
+    answer = MungeStream(FCGI_ToFile(myStream));\r
+   \r
+</PRE>\r
+            <P>\r
+               Here <TT>MungeStream</TT> is a library function that you can&#39;t recompile and <TT>FCGI_ToFile</TT> is\r
+               a macro that converts from <TT>FCGI_FILE *</TT> to <TT>FILE *</TT>. The macro <TT>FCGI_ToFile</TT> is\r
+               defined in <TT>fcgi_stdio.h</TT>.\r
+            </P>\r
+         </LI>\r
+      </UL>\r
+      <H4>\r
+         Converting CGI programs\r
+      </H4>\r
+      <P>\r
+         The main task in converting a CGI program into a FastCGI program is separating the code that needs to execute\r
+         once, initializing the program, from the code that needs to run for each request. In our tiny example,\r
+         initializing the <TT>count</TT> variable is outside the loop, while incrementing the <TT>count</TT> variable\r
+         goes inside.\r
+      </P>\r
+      <P>\r
+         Retained application state may be an issue. You must ensure that any application state created in processing\r
+         one request has no unintended effects on later requests. FastCGI offers the possibility of significant\r
+         application performance improvements, through caching; it is up to you to make the caches work correctly.\r
+      </P>\r
+      <P>\r
+         Storage leaks may be an issue. Many CGI programs don&#39;t worry about storage leaks because the programs\r
+         don&#39;t run for long enough for bloating to be a problem. When converting to FastCGI, you can either use a\r
+         tool such as <A HREF="http://www.pure.com/"><I>Purify</I></A> from Pure Software to discover and fix storage\r
+         leaks, or you can run a C garbage collector such as <A HREF="http://www.geodesic.com/"><I>Great Circle</I></A>\r
+         from Geodesic Systems.\r
+      </P>\r
+      <H4>\r
+         Limitations\r
+      </H4>\r
+      <P>\r
+         Currently there are some limits to the compatibility provided by the <TT>fcgi_stdio</TT> library:\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            The library does not provide FastCGI versions of the functions <TT>fscanf</TT> and <TT>scanf</TT>. If you\r
+            wish to apply <TT>fscanf</TT> or <TT>scanf</TT> to <TT>stdin</TT> of a FastCGI program, the workaround is\r
+            to read lines or other natural units into memory and then call <TT>sscanf</TT>. If you wish to apply\r
+            <TT>fscanf</TT> to a stream on a Unix file, the workaround is to follow the pattern: \r
+<PRE>\r
+    FILE *myStream = fopen(path, &quot;r&quot;);\r
+    count = fscanf(FCGI_ToFile(myStream), format, ...);\r
+   \r
+</PRE>\r
+         </LI>\r
+      </UL>\r
+      <H4>\r
+         Reference documentation\r
+      </H4>\r
+      <P>\r
+         The <A HREF="FCGI_Accept.3"><TT>FCGI_Accept</TT> manpage</A>, <TT>doc/FCGI_Accept.3</TT>, describes the\r
+         function in the traditional format.\r
+      </P>\r
+      <P>\r
+         The <A HREF="FCGI_Finish.3"><TT>FCGI_Finish</TT></A> (<TT>doc/FCGI_Finish.3</TT>), <A HREF=\r
+         "FCGI_SetExitStatus.3"><TT>FCGI_SetExitStatus</TT></A> (<TT>doc/FCGI_SetExitStatus.3</TT>), and <A HREF=\r
+         "FCGI_StartFilterData.3"><TT>FCGI_StartFilterData</TT></A> (<TT>doc/FCGI_StartFilterData.3</TT>) manpages\r
+         document capabilities of the <TT>fcgi-stdio</TT> library that are not illustrated above.\r
+      </P>\r
+      <H4>\r
+         <A NAME="S3.2">3.2 Using the <TT>fcgiapp</TT> library</A>\r
+      </H4>\r
+      <P>\r
+         The <TT>fcgiapp</TT> library is a second C library for FastCGI. It does not provide the high degree of source\r
+         code compatibility provided by <TT>fcgi_stdio</TT>; in return, it does not make such heavy use of\r
+         <TT>#define</TT>. <TT>fcgi_stdio</TT> is implemented as a thin layer on top of <TT>fcgiapp</TT>.\r
+      </P>\r
+      <P>\r
+         Applications built using the <TT>fcgiapp</TT> library cannot run as CGI programs; that feature is provided at\r
+         the <TT>fcgi_stdio</TT> level.\r
+      </P>\r
+      <P>\r
+         Functions defined in <TT>fcgiapp</TT> are named using the prefix <TT>FCGX_</TT> rather than <TT>FCGI_</TT>.\r
+         For instance, <TT>FCGX_Accept</TT> is the <TT>fcgiapp</TT> version of <TT>FCGI_Accept</TT>.\r
+      </P>\r
+      <P>\r
+         Documentation of the <TT>fcgiapp</TT> library takes the form of extensive comments in the header file\r
+         <TT>include/fcgiapp.h</TT>. The sample programs <TT>examples/tiny-fcgi2.c</TT> and <TT>examples/echo2.c</TT>\r
+         illustrate how to use <TT>fcgiapp</TT>.\r
+      </P>\r
+      <H4>\r
+         <A NAME="S3.3">3.3 Using Perl and Tcl</A>\r
+      </H4>\r
+      <P>\r
+         A major advantage of the FastCGI approach to high-performance Web applications is its language-neutrality. CGI\r
+         scripts written in popular languages such as Perl and Tcl can be evolved into high-performance FastCGI\r
+         applications.\r
+      </P>\r
+      <P>\r
+         We have produced FastCGI-integrated Perl and Tcl interpreters. Doing so was easy, since Perl and Tcl are\r
+         conventional C applications and <TT>fcgi_stdio</TT> was designed for converting conventional C applications.\r
+         Essentially no source code changes were required in these programs; a small amount of code was added in order\r
+         to make <TT>FCGI_Accept</TT> and other FastCGI primitives available in these languages. And because these\r
+         interpreters were developed using <TT>fcgi_stdio</TT>, they run standard Perl and Tcl applications (e.g. CGI\r
+         scripts) as well as FastCGI applications.\r
+      </P>\r
+      <P>\r
+         See the <A HREF="http://fastcgi.com">fastcgi.com</A> Web page for more information about the Perl and Tcl\r
+         libraries.\r
+      </P>\r
+      <P>\r
+         Here are the Perl and Tcl versions of <TT>tiny-fcgi</TT>:\r
+      </P>\r
+<PRE>\r
+#!./perl\r
+use FCGI;\r
+$count = 0;\r
+while(FCGI::accept() &gt;= 0) {\r
+    print(&quot;Content-type: text/html\r\n\r\n&quot;,\r
+          &quot;&lt;title&gt;FastCGI Hello! (Perl)&lt;/title&gt;\n&quot;,\r
+          &quot;&lt;h1&gt;FastCGI Hello! (Perl)&lt;/h1&gt;\n&quot;;\r
+          &quot;Request number &quot;,  ++$count,\r
+          &quot; running on host &lt;i&gt;&quot;;$env(SERVER_NAME)&lt;/i&gt;&quot;);\r
+}\r
+</PRE>\r
+<PRE>\r
+#!./tclsh\r
+set count 0 \r
+while {[FCGI_Accept] &gt;= 0 } {\r
+    incr count\r
+    puts -nonewline &quot;Content-type: text/html\r\n\r\n&quot;\r
+    puts &quot;&lt;title&gt;FastCGI Hello! (Tcl)&lt;/title&gt;&quot;\r
+    puts &quot;&lt;h1&gt;FastCGI Hello! (Tcl)&lt;/h1&gt;&quot;\r
+    puts &quot;Request number $count running on host &lt;i&gt;$env(SERVER_NAME)&lt;/i&gt;&quot;\r
+}\r
+</PRE>\r
+      <P>\r
+         Converting a Perl or Tcl CGI application to FastCGI is not fundamentally different from converting a C CGI\r
+         application to FastCGI. You separate the portion of the application that performs one-time initialization from\r
+         the portion that performs per-request processing. You put the per-request processing into a loop controlled by\r
+         <TT>FCGI::accept</TT> (Perl) or <TT>FCGI_Accept</TT> (Tcl).\r
+      </P>\r
+      <H4>\r
+         <A NAME="S3.4">3.4 Using Java</A>\r
+      </H4>\r
+      <P>\r
+         Java is not just for browser-based applets. It is already suitable for writing some Web server applications,\r
+         and its range of applicability will only grow as Java compilers and other Java tools improve. Java&#39;s\r
+         modules, garbage collection, and threads are especially valuable for writing long-lived application servers.\r
+      </P>\r
+      <P>\r
+         The <TT>FCGIInterface</TT> class provides facilities for Java applications analogous to what\r
+         <TT>fcgi_stdio</TT> provides for C applications. Using this library your Java application can run using either\r
+         CGI or FastCGI.\r
+      </P>\r
+      <P>\r
+         The kit includes separate companion document on <A HREF="fcgi-java.htm">using FastCGI with Java</A>. The\r
+         source code for FastCGI classes is contained in directory <TT>java/src</TT> and the compiled code in\r
+         <TT>java/classes</TT>.\r
+      </P>\r
+      <P>\r
+         Here is the Java version of <TT>tiny-fcgi</TT>:\r
+      </P>\r
+<PRE>\r
+import FCGIInterface;\r
+\r
+class TinyFCGI { \r
+    public static void main (String args[]) {  \r
+        int count = 0;\r
+        while(new FCGIInterface().FCGIaccept()&gt;= 0) {\r
+            count ++;\r
+            System.out.println(&quot;Content-type: text/html\r\n\r\n&quot;);\r
+            System.out.println(\r
+                    &quot;&lt;title&gt;FastCGI Hello! (Java)&lt;/title&gt;&quot;);\r
+            System.out.println(&quot;&lt;h1&gt;FastCGI Hello! (Java)&lt;/h1&gt;&quot;);\r
+            System.out.println(\r
+                    &quot;request number &quot; + count + &quot; running on host &lt;i&gt;&quot; +\r
+                    System.getProperty(&quot;SERVER_NAME&quot;) + &quot;&lt;/i&gt;&quot;);\r
+        }\r
+    }\r
+}\r
+</PRE>\r
+      <H3>\r
+         <A NAME="S4">4. Running applications</A>\r
+      </H3>\r
+      <H3>\r
+         <A NAME="S4.1">4.1 Using a Web server that supports FastCGI</A>\r
+      </H3>\r
+      <P>\r
+         For a current listing of Web servers that support FastCGI, see the <A HREF=\r
+         "http://fastcgi.com">fastcgi.com</A> Web page.\r
+      </P>\r
+      <P>\r
+         Some of the Web servers that support FastCGI perform management of FastCGI applications. You don&#39;t need to\r
+         start and stop FastCGI applications; the Web server takes care of this. If an application process should\r
+         crash, the Web server restarts it.\r
+      </P>\r
+      <P>\r
+         Web servers support FastCGI via new configuration directives. Since these directives are server-specific, get\r
+         more information from the documentation that accompanies each server.\r
+      </P>\r
+      <H3>\r
+         <A NAME="S4.2">4.2 Using <TT>cgi-fcgi</TT> with any Web server</A>\r
+      </H3>\r
+      <P>\r
+         The program <TT>cgi-fcgi</TT> allows you to run FastCGI applications using any Web server that supports CGI.\r
+      </P>\r
+      <P>\r
+         Here is how <TT>cgi-fcgi</TT> works. <TT>cgi-fcgi</TT> is a standard CGI program that uses Unix domain or\r
+         TCP/IP sockets to communicate with a FastCGI application. <TT>cgi-fcgi</TT> takes the path name or host/port\r
+         name of a listening socket as a parameter and <TT>connect</TT>s to the FastCGI application listening on that\r
+         socket. <TT>cgi-fcgi</TT> then forwards the CGI environment variables and <TT>stdin</TT> data to the FastCGI\r
+         application, and forwards the <TT>stdout</TT> and <TT>stderr</TT> data from the FastCGI application to the Web\r
+         server. When the FastCGI application signals the end of its response, <TT>cgi-fcgi</TT> flushes its buffers\r
+         and exits.\r
+      </P>\r
+      <P>\r
+         Obviously, having <TT>cgi-fcgi</TT> is not as good as having a server with integrated FastCGI support:\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            Communication is slower than with a Web server that avoids the fork/exec overhead on every FastCGI request.\r
+         </LI>\r
+         <LI>\r
+            <TT>cgi-fcgi</TT> does not perform application management, so you need to provide this yourself.\r
+         </LI>\r
+         <LI>\r
+            <TT>cgi-fcgi</TT> supports only the Responder role.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         But <TT>cgi-fcgi</TT> does allow you to develop applications that retain state in memory between connections,\r
+         which often provides a major performance boost over normal CGI. And all the applications you develop using\r
+         <TT>cgi-fcgi</TT> will work with Web servers that have integrated support for FastCGI.\r
+      </P>\r
+      <P>\r
+         The file <TT>examples/tiny-fcgi.cgi</TT> demonstrates a way to use <TT>cgi-fcgi</TT> to run a typical\r
+         application, in this case the <TT>examples/tiny-fcgi</TT> application:\r
+      </P>\r
+<PRE>\r
+    #!../cgi-fcgi/cgi-fcgi -f\r
+    -connect sockets/tiny-fcgi tiny-fcgi\r
+</PRE>\r
+      <P>\r
+         On most Unix platforms, executing this command-interpreter file runs <TT>cgi-fcgi</TT> with arguments\r
+         <TT>-f</TT> and <TT>examples/tiny-fcgi.cgi</TT>. (Beware: On some Unix platforms, including HP-UX, the first\r
+         line of a command-interpreter file cannot contain more than 32 characters, including the newline; you may need\r
+         to install the <TT>cgi-fcgi</TT> application in a standard place like <TT>/usr/local/bin</TT> or create a\r
+         symbolic link to the <TT>cgi-fcgi</TT> application in the directory containing your application.) The\r
+         <TT>cgi-fcgi</TT> program reads the command-interpreter file and connects to the FastCGI application whose\r
+         listening socket is <TT>examples/sockets/tiny-fcgi</TT>.\r
+      </P>\r
+      <P>\r
+         Continuing the example, if <TT>cgi-fcgi</TT>&#39;s connection attempt fails, it creates a new process running\r
+         the program <TT>examples/tiny-fcgi</TT> and listening on socket <TT>examples/sockets/tiny-fcgi</TT>. Then\r
+         <TT>cgi-fcgi</TT> retries the connection attempt, which now should succeed.\r
+      </P>\r
+      <P>\r
+         The <TT>cgi-fcgi</TT> program has two other modes of operation. In one mode it connects to applications but\r
+         does not start them; in the other it starts applications but does not connect to them. These modes are\r
+         required when using TCP/IP. The <A HREF="cgi-fcgi.1"><TT>cgi-fcgi</TT> manpage</A>, <TT>doc/cgi-fcgi.1</TT>,\r
+         tells the full story.\r
+      </P>\r
+      <P>\r
+         To run the example applications using <TT>cgi-fcgi</TT>, start your Web server and give it the directory\r
+         <TT>fcgi-devel-kit</TT> as the root of its URL space. If the machine running your server is called\r
+         <TT>bowser</TT> and your server is running on port <TT>8888</TT>, you&#39;d then open the URL\r
+         <TT>http://bowser:8888/index.html</TT> to reach the kit&#39;s index page. Now the links on the index page that\r
+         run example applications via <TT>cgi-fcgi</TT> should be active.\r
+      </P>\r
+      <H3>\r
+         <A NAME="S5">5. Known problems</A>\r
+      </H3>\r
+      <P>\r
+         On Digital UNIX 3.0 there&#39;s a problem with Unix domain listening sockets on NFS file systems. The symptom\r
+         when using cgi-fcgi is an exit status of 38 (<TT>ENOTSOCK</TT>: socket operation on non-socket), but cgi-fcgi\r
+         may dump core in this case when compiled optimized. Work-around: Store your Unix domain listening sockets on a\r
+         non NFS file system, upgrade to Digital UNIX 3.2, or use TCP sockets.\r
+      </P>\r
+      <P>\r
+         On AIX there&#39;s a problem with shared listening sockets. The symptoms can include application core dumps\r
+         and kernel panic. Work-around: Run a single FastCGI application server per listening socket.\r
+      </P>\r
+      <H3>\r
+         <A NAME="S6">6. Getting support</A>\r
+      </H3>\r
+      <P>\r
+         The mailing list <TT>fastcgi-developers@idle.com</TT> is used for discussions of issues in developing FastCGI\r
+         applications. Topics include announcement of FastCGI-capable Web servers or changes to such servers,\r
+         announcement of new application libraries or changes to such libraries, announcement of known bugs, discussion\r
+         of design trade-offs in FastCGI application programming, and discussion of development plans and experiences.\r
+         To join the list, send a message to <A HREF=\r
+         "mailto:fastcgi-developers-request@openmarket.com">fastcgi-developers-request@idle.com</A> with a message body\r
+         consisting of the word &quot;subscribe&quot; (leaving off the quotes).\r
+      </P>\r
+      <P>\r
+         A link to a mail archive can be found on the FastCGI home page, <A HREF=\r
+         "http://www.fastcgi.com">http://www.fastcgi.com</A>\r
+      </P>\r
+      <HR>\r
+      <ADDRESS>\r
+         &copy; 1996, Open Market, Inc. / mbrown@openmarket.com\r
+      </ADDRESS>\r
+   </BODY>\r
+</HTML>\r
+\r
index f4a1882..88d3a9b 100644 (file)
-<html>
-<head><title>Integrating FastCGI with Java</title>
-</head>
-
-<body bgcolor="#FFFFFF" text="#000000" link="#cc0000" alink="#000011" 
-vlink="#555555">
-
-<center>
-<a href="http://fastcgi.com">
-    <img border=0 src="../images/fcgi-hd.gif" alt="[[FastCGI]]"></a>
-</center>
-<br clear=all>
-<h3><center>Integrating FastCGI with Java</center></h3>
-
-<!--Copyright (c) 1996 Open Market, Inc.                                    -->
-<!--See the file "LICENSE.TERMS" for information on usage and redistribution-->
-<!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->
-<!-- $Id: fcgi-java.htm,v 1.2 2001/05/14 12:59:51 robs Exp $ -->
-
-<P ALIGN=CENTER>
-Steve Harris
-<BR>
-Open Market, Inc.
-<BR>
-<EM>7 May 1996</EM>
-</P>
-
-<h5 align=center>
-Copyright &copy; 1996 Open Market, Inc.  245 First Street, Cambridge,
-  MA 02142 U.S.A.<br>
-Tel: 617-621-9500 Fax: 617-621-1703 URL:
-  <a href="http://www.openmarket.com/">http://www.openmarket.com/</a><br>
-</h5>
-<hr>
-
-<H3><A NAME = "S1"> 1. Introduction</A></H3>
-Java is an object-oriented programming language developed by Sun
-Microsystems.  The Java Depvelopers Kit (JDK), which contains the basic
-Java class packages, is available from Sun in both source and binary
-forms at Sun's
-<a href="http://java.sun.com/java.sun.com/JDK-1.0/index.html">JavaSoft</a>
-site.  This document assumes that you have some familiarity with the
-basics of compiling and running Java programs. 
-<p>
-There are two kinds of applications built using Java.
-<ul>
-  <li> <i>Java Applets</i> are graphical components which are run off
-       HTML pages via the <tt>&lt;APPLET&gt;</tt> HTML extention tag.<br><br>
-       
-  <li> <i>Java Applications (Apps) </i> are stand-alone programs
-       that are run by invoking the Java interpreter directly. Like
-       C programs, they have a <tt>main()</tt> method which the interpreter
-       uses as an entry point.
-</ul>
-The initial emphasis on using Java for client side applets should not
-obscure the fact that Java is a full strength programming language
-which can be used to develop server side stand alone applications,
-including CGI and now FastCGI applications.
-<p>
-The remainder of this document explains how to write and run FastCGI Java
-applications. It also illustrates the conversion of a sample Java CGI program
-to a FastCGI program.
-
-
-
-<H3><A NAME = "S2"> 2. Writing FastCGI applications in Java</A></H3>
-
-Writing a FastCGI application in Java is as simple as writing one in C.
-
-<ol>
-  <li> Import the <tt>FCGIInterface</tt> class.
-  <li> Perform one-time initialization at the top of the
-       <tt>main()</tt> method.
-  <li> Create a new <tt>FCGIInterface</tt> object and send it an
-       <tt>FCGIaccept()</tt> message in a loop.
-  <li> Put the per-request application code inside that loop.
-</ol>
-
-On return from <tt>FCGIaccept()</tt> you can access the request's environment
-variables using <tt>System.getProperty</tt> and perform request-related
-I/O through the standard variables <tt>System.in</tt>,
-<tt>System.out</tt>, and <tt>System.err</tt>.<p>
-
-To illustrate these points, the kit includes <tt>examples/TinyCGI</tt>,
-a CGI Java application, and <tt>examples/TinyFCGI</tt>, the FastCGI
-version of TinyCGI.  These programs perform the same
-functions as the C programs <tt>examples/tiny-cgi.c</tt> and
-<tt>examples/tiny-fcgi.c</tt> that are used as examples in the
-<A HREF="fcgi-devel-kit.htm#S3.1.1">FastCGI Developer's Kit document</A>.
-
-
-<h4>A. TinyCGI</h4>
-<PRE> 
-class TinyCGI {        
-       public static void main (String args[]) {               
-               int count = 0;
-                ++count;
-               System.out.println("Content-type: text/html\n\n");
-               System.out.println("&lt;html&gt;");
-               System.out.println(
-                       "&lt;head&gt;&lt;TITLE&gt;CGI Hello&lt;/TITLE&gt;&lt;/head&gt;");
-               System.out.println("&lt;body&gt;");
-               System.out.println("&lt;H3&gt;CGI-Hello&lt;/H3&gt;");
-               System.out.println("request number " + count + 
-                                       " running on host " 
-                               + System.getProperty&lt;"SERVER_NAME"));
-               System.out.println("&lt;/body&gt;");
-               System.out.println("&lt;/html&gt;"); 
-               }
-       }
-
-</PRE>
-<h4>B. TinyFCGI</h4>
-<PRE> 
-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\n\n");
-                       System.out.println("&lt;html&gt;");
-                       System.out.println(
-                         "&lt;head&gt;&lt;TITLE&gt;FastCGI-Hello Java stdio&lt;/TITLE&gt;&lt;/head&gt;");
-                       System.out.println("&lt;body&gt;");
-                       System.out.println("&lt;H3&gt;FastCGI-HelloJava stdio&lt;/H3&gt;");
-                       System.out.println("request number " + count + 
-                                       " running on host " 
-                               + System.getProperty&lt;"SERVER_NAME"));
-                       System.out.println("&lt;/body&gt;");
-                       System.out.println("&lt;/html&gt;"); 
-                       }
-               }
-       }
-
-</PRE>
-<h4>C. Running these Examples</h4>
-
-We assume that you have downloaded the JDK and the FastCGI Developer's
-Kit, and that you have a Web server running that can access the
-<tt>fcgi-devel-kit/examples</tt> directory. In all cases where we
-specify paths, we are using relative paths within
-<tt>fcgi-devel-kit</tt> or the JDK which will need to be enlarged to a
-full path by the user.
-
-<h5>Configuring</h5>
-<ol>
-  <li> Add your JDK's <tt>java/bin</tt> directory to your Unix <tt>PATH</tt>
-       if it isn't there already.<br><br>
-       
-  <li> Add the directories <tt>fcgi-devel-kit/examples</tt> and
-       <tt>fcgi-devel-kit/java/classes</tt> to your Java
-       <tt>CLASSPATH</tt>.<br><br>
-       
-  <li>In your Open Market Secure WebServer configuration file,
-      <tt>httpd.config</tt>, add the following two lines:<br><br>
-       
-       <tt>ExternalAppClass TinyFCGI -host </tt><i>hostName:portNum</i><br>
-       <tt>Responder TinyFCGI fcgi-devel-kit/examples/TinyFCGI</tt><br><br>
-              
-       <ul>
-       <li><i>hostName</i> is the name of your host machine.<br>
-       <li><i>portNum</i> is the port that you've selected for
-            communication between the Web server and the Java application.<br>
-       </ul><br>
-
-       On other servers you can use <tt>cgi-fcgi</tt> to get a
-       similar effect.
-       
-  <li> Create a soft link <tt>examples/javexe</tt> to the
-       <tt>java/bin</tt> directory in your JDK.
-       This link is required only to run the
-       CGI scripts <tt>examples/TinyCGI.cgi</tt> and
-       <tt>examples/TinyFCGI.cgi</tt>, which use it to
-       invoke the Java interpreter <tt>java/bin/java</tt>.
-       It is not used by FastCGI applications.
-
-   <li> You might have to modify <tt>examples/TinyFCGI.cgi</tt> to use a
-       Unix shell for which your CLASSPATH is defined.
-</ol>
-
-<h5> Running </h5>
-
-<ul>
-  <li> To run TinyFCGI as FastCGI, you invoke the Java interpreter
-       with the -D option, giving it the <tt>FCGI_PORT</tt> environment
-       variable
-       and the same <i>portNum</i> that was used in the Web server
-       configuration. The command is:
-       <br><br>
-       <tt>java -DFCGI_PORT=portNum TinyFCGI</tt>
-       <br><br>
-       Then point your browser at <tt>fcgi-devel-kit/examples/TinyFCGI</tt>.
-       Notice that each time you reload, the count increments.<br><br>
-       
-  <li> To run TinyCGI, point your browser at
-       <tt>fcgi-devel-kit/examples/TinyCGI.cgi</tt> on your host machine.
-       Notice that the count does not increment.<br><br>
-
-  <li> Finally, you can run TinyFCGI as a straight CGI program by pointing
-       your browser at <tt>fcgi-devel-kit/examplesi/TinyFCGI.cgi.</tt> The results
-       are exactly the same as when you ran TinyCGI. Invoking a FastCGI
-       program without an <tt>FCGI_PORT</tt> parameter tells the
-       FastCGI interface
-       to leave the normal CGI environment in place.
-</ul>
-<p>
-Due to gaps in the Java interpreter's support for listening
-sockets, Java FastCGI applications are currently limited to
-being started as external applications.  They can't be started and
-managed by the Web server because they are incapable of using
-a listening socket that the Web server creates.
-
-
-
-<H3><A NAME = "S3"> 3. Standard I/O and Application Libraries</A></H3>
-
-As we have seen above, FastCGI for Java offers a redefinition
-of standard I/O corresponding to the the <i>fcgi_stdio</i> functionality.
-It also offers a set of directly callable I/O methods corresponding to
-the <i>fcgiapp</i> C library. To understand where these methods occur
-we need to look briefly at the FastCGI redefinition of standard I/O.<p>
-
-Java defines standard I/O in the <i>java.System</i> class as follows:<p>
-
-public static InputStream in = new BufferedInputStream(new FileInputStream(FileDescriptor.in), 128);<br>
-public static PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out), 128), true);<br>
-public static PrintStream err = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err), 128), true);<p>
-
-The File Descriptors <i>in</i>, <i>out</i>, <i>err</i> are constants set to 0, 1 and 2 respectively.<p>
-
-The FastCGI interface redefines <i>java.System in, out</i>, and <i>err</i>
-by replacing the File streams with Socket streams and inserting streams
-which know how to manage the FastCGI protocol between the Socket streams
-and the Buffered streams in the above definitions.
-<p>
-For those cases where the FCGI application needs to bypass the standard I/O
-streams, it can directly access the methods of the FCGI input and output
-streams which roughly correspond to the functions in the C <i>fcgiapp</i>
-library. These streams can be accessed via the <i>request</i> class variable
-in FCGIInterface. Each Request object has instance variables that refer to an
-FCGIInputStream, and to two FCGIOutputStreams associated with that request.
-
-<H3><A NAME = "S4"> 4. Environment Variables</A></H3>
-
-Java does not use the  C <i>environ</i> list. Nor is there a <i>getenv</i>
-command that reads system environment variables. This is intentional for
-reasons of portability and security. Java has an internal dictionary of
-properties which belongs to the System class. These System properties
-are <i>name/value</i> associations that constitute the Java environment.
-When a Java application starts up, it reads in a file with default properties.
-As we have seen, additional System properties may be inserted by using
-the -D <i>Java</i> command argument.<p>
-
-For CGI, where the Java application is invoked from a .cgi script that,
-in turn, invokes the Java interpreter, this script could read the environment
-and pass the variables to the Java application either by writing a file
-or by creating -D options on the fly. Both of these methods are somewhat
-awkward.<p>
-
-For FastCGI Java applications, the environment variables are obtained from
-the FastCGI web server via <tt>FCGI_PARAMS</tt> records that are sent to the
-application at the start of each request. The FastCGI interface stores the
-original startup properties, combines these with the properties obtained
-from the server, and puts the new set of properties in the System properties
-dictionary. The only parameter that has to be specifically added at startup
-time is the FCGI_PORT parameter for the Socket creation.  In the future, we
-expect that even this parameter won't be needed, since its use is due to an
-acknowledged rigidity in the JDK's implementation of sockets.<p>
-
-<H3><A NAME = "S4"> 5. Further examples: EchoFCGI and Echo2FCGI</A></H3>
-
-The next two examples illustrate the points made in the last two sections.
-EchoFCGI and Echo2FCGI both echo user input and display the application's
-environment variables. EchoFCGI reads the user input from System.in, while
-Echo2FCGI reads the user input directly from the intermediate FastCGI input
-stream.
-
-<h4>A. EchoFCGI</h4>
-<pre>
-import FCGIInterface;
-import FCGIGlobalDefs;
-import java.io.*;
-
-class EchoFCGI {
-       
-       public static void main (String args[]) {
-               int status = 0;
-               while(new FCGIInterface().FCGIaccept()>= 0) {
-               System.out.println("Content-type: text/html\n\n");
-                       System.out.println("&lt;html&gt;");
-                       System.out.println(
-                               "&lt;head%gt;&lt;TITLE&gt;FastCGI echo
-                                      &lt;/TITLE&gt;&lt;/head&gt;");
-                       System.out.println("&lt;body&gt;");     
-                       System.out.println(
-                                         "&lt;H2&gt;FastCGI echo&lt;/H2&gt;");
-                       System.out.println("&lt;H3&gt;STDIN&lt;/H3&gt;");
-                       for ( int c = 0; c != -1; ) {
-                               try {
-                                       c = System.in.read();
-                               } catch(IOException e) {
-                                       System.out.println(
-                                       "&lt;br&gt;&lt;b&gt;SYSTEM EXCEPTION");
-                                       Runtime rt = Runtime.getRuntime();
-                                       rt.exit(status);
-                                       }
-                               if (c != -1) {  
-                                       System.out.print((char)c);
-                                       }
-                               }
-                       System.out.println(
-                               "&lt;H3&gt;Environment Variables:&lt;/H3&gt;");
-       
-                       System.getProperties().list(System.out);
-                       System.out.println("&lt;/body&gt;");
-                       System.out.println("&lt;/html&gt;");
-                       }
-               }
-       }
-</pre>
-<h4>B. Echo2FCGI</h4>
-<pre>
-import FCGIInterface;
-import FCGIGlobalDefs;
-import FCGIInputStream;
-import FCGIOutputStream;
-import FCGIMessage;
-import FCGIRequest;
-import java.io.*;
-
-class Echo2FCGI {
-
-       public static void main (String args[]) {
-               int status = 0;
-                FCGIInterface intf = new FCGIInterface();
-               while(intf.FCGIaccept()>= 0) {
-               System.out.println("Content-type: text/html\n\n");
-                       System.out.println("&lt;html&gt;");
-                       System.out.println(
-                               "&lt;head&gt;&lt;TITLE&gt;FastCGI echo
-                                    &lt;/TITLE&gt;&lt;/head&gt;");
-                       System.out.println("&lt;body&gt;");                     
-                       System.out.println("&lt;H2&gt;FastCGI echo&lt;/H2&gt;");
-                       System.out.println("&lt;H3&gt;STDIN:&lt;/H3"&gt;);
-                       for ( int c = 0; c != -1; ) {
-                               try {
-                                       c = intf.request.inStream.read();
-                               } catch(IOException e) {
-                                       System.out.println(
-                                       "&lt;br&gt;&lt;b&gt;SYSTEM EXCEPTION");
-                                       Runtime rt = Runtime.getRuntime();
-                                       rt.exit(status);
-                                       }
-                               if (c != -1) {  
-                                       System.out.print((char)c);
-                                       }
-                               }
-                       System.out.println(
-                               "&lt;H3&gt;Environment Variables:&lt;/H3&gt;");
-       
-                       System.getProperties().list(System.out);
-                       System.out.println(&lt;"/body&gt;");
-                       System.out.println("&lt;/html&gt;");
-                       }
-               }
-       }
-</pre>
-<h4>C. Running these Examples</h4>
-
-<h5>Configuring</h5>
-
-As with TinyFCGI, you need to configure the web server to recognize these
-two FastCGI applications. Your configuration now looks like this:<p> 
-<pre>
-ExternalAppClass java1 -host hostname:portNum
-Responder java1 fcgi-devel-kit/examples/TinyFCGI
-ExternalAppClass java2 -host hostname:portNumA
-Responder java2 fcgi-devel-kit/examples/EchoFCGI
-ExternalAppClass java3 -host hostname:porNumB
-Responder java3 fcgi-devel-kit/examples/Echo2FCGI
-</pre>
-<p>
-Note that the application classes and port numbers are different for each
-application.
-
-<h5>Running</h5>
-
-As with TinyFCGI, you need to run these programs with the -D option
-using FCGI_PORT and the appropriate port number.
-
-To get some data for standard input we have created two html pages with
-forms that use a POST method. These are echo.html and echo2.html. You must
-edit these .html files to expand the path to <i>fcgi-devel-kit/examples</i>
-to a full path. Once the appropriate Java program is running, point your browser at the corresponding HTML page, enter some data and select the <i>go_find</i> button.
-
-
-<H3><A NAME = "S6"> 6. FastCGI Java Classes</A></H3>
-
-The Java FastCGI classes are included in both source and byte code format in
-<i>fcgi-devel-kit/java/src</i> and :<i>fcgi-devel-kit/java/classes</i>
-respectively. The following is a brief description of these classes:<p>
-
-<dl>
-<dt><i>FCGIInterface</i><dd> This class contains the FCGIaccept method called
-     by the FastCGI user application. This method sets up the appropriate
-     FastCGI environment for communication with the web server and manages
-     FastCGI requests.<br>
-     
- <dt><i>FCGIInputStream</i><dd> This input stream manages FastCGI
-      internal buffers to ensure that the user gets all of the FastCGI
-      messages associated with a request. It uses FCGIMessage objects
-      to interpret these incoming messages.<br>
-      
-  <dt><i>FCGIOutputStream</i><dd> This output stream manages FastCGI
-       internal buffers to send user data back to the web server
-       and to notify the server of various FCGI protocol conditions.
-       It uses FCGIMessage objects to format outgoing FastCGI messages.<br>
-      
-<dt><i>FCGIMessage</i><dd> This is the only class that understands the
-     actual structure of the FastCGI messages. It interprets incoming
-     FastCGI records and constructs outgoing ones..<br>
-     
-<dt><i>FCGIRequest</i><dd>This class currently contains data fields
-     used by FastCGI to manage user requests.  In a multi-threaded
-     version of FastCGI, the role of this class will be expanded.<br>
-
-<dt><i>FCGIGlobalDefs</i><dd>This class contains definitions of FastCGI
-     constants.
-</dl>
-<HR>
-<ADDRESS><A HREF="mailto:harris@openmarket.com">Steve Harris // harris@openmarket.com</A></ADDRESS>
-</i></i></body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
+<HTML>\r
+   <HEAD>\r
+      <TITLE>\r
+         Integrating FastCGI with Java\r
+      </TITLE>\r
+<STYLE TYPE="text/css">\r
+ body {\r
+  background-color: #FFFFFF;\r
+  color: #000000;\r
+ }\r
+ :link { color: #cc0000 }\r
+ :visited { color: #555555 }\r
+ :active { color: #000011 }\r
+ dt.c4 {font-style: italic}\r
+ h5.c3 {text-align: center}\r
+ p.c2 {text-align: center}\r
+ div.c1 {text-align: center}\r
+</STYLE>\r
+   </HEAD>\r
+   <BODY>\r
+      <DIV CLASS="c1">\r
+         <A HREF="http://fastcgi.com"><IMG BORDER="0" SRC="../images/fcgi-hd.gif" ALT="[[FastCGI]]"></A>\r
+      </DIV>\r
+      <BR CLEAR="all">\r
+      <DIV CLASS="c1">\r
+         <H3>\r
+            Integrating FastCGI with Java\r
+         </H3>\r
+      </DIV>\r
+      <!--Copyright (c) 1996 Open Market, Inc.                                    -->\r
+      <!--See the file "LICENSE.TERMS" for information on usage and redistribution-->\r
+      <!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->\r
+      <!-- $Id: fcgi-java.htm,v 1.3 2001/11/27 01:03:47 robs Exp $ -->\r
+      <P CLASS="c2">\r
+         Steve Harris<BR>\r
+         Open Market, Inc.<BR>\r
+         <EM>7 May 1996</EM>\r
+      </P>\r
+      <H5 CLASS="c3">\r
+         Copyright &copy; 1996 Open Market, Inc. 245 First Street, Cambridge, MA 02142 U.S.A.<BR>\r
+         Tel: 617-621-9500 Fax: 617-621-1703 URL: <A HREF=\r
+         "http://www.openmarket.com/">http://www.openmarket.com/</A><BR>\r
+      </H5>\r
+      <HR>\r
+      <H3>\r
+         <A NAME="S1">1. Introduction</A>\r
+      </H3>\r
+      <P>\r
+         Java is an object-oriented programming language developed by Sun Microsystems. The Java Depvelopers Kit (JDK),\r
+         which contains the basic Java class packages, is available from Sun in both source and binary forms at\r
+         Sun&#39;s <A HREF="http://java.sun.com/java.sun.com/JDK-1.0/index.html">JavaSoft</A> site. This document\r
+         assumes that you have some familiarity with the basics of compiling and running Java programs.\r
+      </P>\r
+      <P>\r
+         There are two kinds of applications built using Java.\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            <I>Java Applets</I> are graphical components which are run off HTML pages via the <TT>&lt;APPLET&gt;</TT>\r
+            HTML extention tag.<BR>\r
+            <BR>\r
+         </LI>\r
+         <LI>\r
+            <I>Java Applications (Apps)</I> are stand-alone programs that are run by invoking the Java interpreter\r
+            directly. Like C programs, they have a <TT>main()</TT> method which the interpreter uses as an entry point.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         The initial emphasis on using Java for client side applets should not obscure the fact that Java is a full\r
+         strength programming language which can be used to develop server side stand alone applications, including CGI\r
+         and now FastCGI applications.\r
+      </P>\r
+      <P>\r
+         The remainder of this document explains how to write and run FastCGI Java applications. It also illustrates\r
+         the conversion of a sample Java CGI program to a FastCGI program.\r
+      </P>\r
+      <H3>\r
+         <A NAME="S2">2. Writing FastCGI applications in Java</A>\r
+      </H3>\r
+      <P>\r
+         Writing a FastCGI application in Java is as simple as writing one in C.\r
+      </P>\r
+      <OL>\r
+         <LI>\r
+            Import the <TT>FCGIInterface</TT> class.\r
+         </LI>\r
+         <LI>\r
+            Perform one-time initialization at the top of the <TT>main()</TT> method.\r
+         </LI>\r
+         <LI>\r
+            Create a new <TT>FCGIInterface</TT> object and send it an <TT>FCGIaccept()</TT> message in a loop.\r
+         </LI>\r
+         <LI>\r
+            Put the per-request application code inside that loop.\r
+         </LI>\r
+      </OL>\r
+      <P>\r
+         On return from <TT>FCGIaccept()</TT> you can access the request&#39;s environment variables using\r
+         <TT>System.getProperty</TT> and perform request-related I/O through the standard variables <TT>System.in</TT>,\r
+         <TT>System.out</TT>, and <TT>System.err</TT>.\r
+      </P>\r
+      <P>\r
+         To illustrate these points, the kit includes <TT>examples/TinyCGI</TT>, a CGI Java application, and\r
+         <TT>examples/TinyFCGI</TT>, the FastCGI version of TinyCGI. These programs perform the same functions as the C\r
+         programs <TT>examples/tiny-cgi.c</TT> and <TT>examples/tiny-fcgi.c</TT> that are used as examples in the <A\r
+         HREF="fcgi-devel-kit.htm#S3.1.1">FastCGI Developer&#39;s Kit document</A>.\r
+      </P>\r
+      <H4>\r
+         A. TinyCGI\r
+      </H4>\r
+<PRE>\r
\r
+class TinyCGI { \r
+ public static void main (String args[]) {  \r
+  int count = 0;\r
+                ++count;\r
+  System.out.println(&quot;Content-type: text/html\n\n&quot;);\r
+  System.out.println(&quot;&lt;html&gt;&quot;);\r
+  System.out.println(\r
+                 &quot;&lt;head&gt;&lt;TITLE&gt;CGI Hello&lt;/TITLE&gt;&lt;/head&gt;&quot;);\r
+  System.out.println(&quot;&lt;body&gt;&quot;);\r
+  System.out.println(&quot;&lt;H3&gt;CGI-Hello&lt;/H3&gt;&quot;);\r
+  System.out.println(&quot;request number &quot; + count + \r
+     &quot; running on host &quot; \r
+    + System.getProperty&lt;&quot;SERVER_NAME&quot;));\r
+  System.out.println(&quot;&lt;/body&gt;&quot;);\r
+  System.out.println(&quot;&lt;/html&gt;&quot;); \r
+  }\r
+ }\r
+\r
+</PRE>\r
+      <H4>\r
+         B. TinyFCGI\r
+      </H4>\r
+<PRE>\r
\r
+import FCGIInterface;\r
+\r
+class TinyFCGI { \r
+ public static void main (String args[]) {  \r
+  int count = 0;\r
+   while(new FCGIInterface().FCGIaccept()&gt;= 0) {\r
+   count ++;\r
+   System.out.println(&quot;Content-type: text/html\n\n&quot;);\r
+   System.out.println(&quot;&lt;html&gt;&quot;);\r
+   System.out.println(\r
+     &quot;&lt;head&gt;&lt;TITLE&gt;FastCGI-Hello Java stdio&lt;/TITLE&gt;&lt;/head&gt;&quot;);\r
+   System.out.println(&quot;&lt;body&gt;&quot;);\r
+   System.out.println(&quot;&lt;H3&gt;FastCGI-HelloJava stdio&lt;/H3&gt;&quot;);\r
+   System.out.println(&quot;request number &quot; + count + \r
+     &quot; running on host &quot; \r
+    + System.getProperty&lt;&quot;SERVER_NAME&quot;));\r
+   System.out.println(&quot;&lt;/body&gt;&quot;);\r
+   System.out.println(&quot;&lt;/html&gt;&quot;); \r
+   }\r
+  }\r
+ }\r
+\r
+</PRE>\r
+      <H4>\r
+         C. Running these Examples\r
+      </H4>\r
+      <P>\r
+         We assume that you have downloaded the JDK and the FastCGI Developer&#39;s Kit, and that you have a Web server\r
+         running that can access the <TT>fcgi-devel-kit/examples</TT> directory. In all cases where we specify paths,\r
+         we are using relative paths within <TT>fcgi-devel-kit</TT> or the JDK which will need to be enlarged to a full\r
+         path by the user.\r
+      </P>\r
+      <H5>\r
+         Configuring\r
+      </H5>\r
+      <OL>\r
+         <LI>\r
+            Add your JDK&#39;s <TT>java/bin</TT> directory to your Unix <TT>PATH</TT> if it isn&#39;t there\r
+            already.<BR>\r
+            <BR>\r
+         </LI>\r
+         <LI>\r
+            Add the directories <TT>fcgi-devel-kit/examples</TT> and <TT>fcgi-devel-kit/java/classes</TT> to your Java\r
+            <TT>CLASSPATH</TT>.<BR>\r
+            <BR>\r
+         </LI>\r
+         <LI>\r
+            In your Open Market Secure WebServer configuration file, <TT>httpd.config</TT>, add the following two\r
+            lines:<BR>\r
+            <BR>\r
+             <TT>ExternalAppClass TinyFCGI -host</TT> <I>hostName:portNum</I><BR>\r
+             <TT>Responder TinyFCGI fcgi-devel-kit/examples/TinyFCGI</TT><BR>\r
+            <BR>\r
+             \r
+            <UL>\r
+               <LI>\r
+                  <I>hostName</I> is the name of your host machine.<BR>\r
+               </LI>\r
+               <LI>\r
+                  <I>portNum</I> is the port that you&#39;ve selected for communication between the Web server and the\r
+                  Java application.<BR>\r
+               </LI>\r
+            </UL>\r
+            <BR>\r
+             On other servers you can use <TT>cgi-fcgi</TT> to get a similar effect.\r
+         </LI>\r
+         <LI>\r
+            Create a soft link <TT>examples/javexe</TT> to the <TT>java/bin</TT> directory in your JDK. This link is\r
+            required only to run the CGI scripts <TT>examples/TinyCGI.cgi</TT> and <TT>examples/TinyFCGI.cgi</TT>,\r
+            which use it to invoke the Java interpreter <TT>java/bin/java</TT>. It is not used by FastCGI applications.\r
+         </LI>\r
+         <LI>\r
+            You might have to modify <TT>examples/TinyFCGI.cgi</TT> to use a Unix shell for which your CLASSPATH is\r
+            defined.\r
+         </LI>\r
+      </OL>\r
+      <H5>\r
+         Running\r
+      </H5>\r
+      <UL>\r
+         <LI>\r
+            To run TinyFCGI as FastCGI, you invoke the Java interpreter with the -D option, giving it the\r
+            <TT>FCGI_PORT</TT> environment variable and the same <I>portNum</I> that was used in the Web server\r
+            configuration. The command is:<BR>\r
+            <BR>\r
+             <TT>java -DFCGI_PORT=portNum TinyFCGI</TT><BR>\r
+            <BR>\r
+             Then point your browser at <TT>fcgi-devel-kit/examples/TinyFCGI</TT>. Notice that each time you reload,\r
+            the count increments.<BR>\r
+            <BR>\r
+         </LI>\r
+         <LI>\r
+            To run TinyCGI, point your browser at <TT>fcgi-devel-kit/examples/TinyCGI.cgi</TT> on your host machine.\r
+            Notice that the count does not increment.<BR>\r
+            <BR>\r
+         </LI>\r
+         <LI>\r
+            Finally, you can run TinyFCGI as a straight CGI program by pointing your browser at\r
+            <TT>fcgi-devel-kit/examplesi/TinyFCGI.cgi.</TT> The results are exactly the same as when you ran TinyCGI.\r
+            Invoking a FastCGI program without an <TT>FCGI_PORT</TT> parameter tells the FastCGI interface to leave the\r
+            normal CGI environment in place.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         Due to gaps in the Java interpreter&#39;s support for listening sockets, Java FastCGI applications are\r
+         currently limited to being started as external applications. They can&#39;t be started and managed by the Web\r
+         server because they are incapable of using a listening socket that the Web server creates.\r
+      </P>\r
+      <H3>\r
+         <A NAME="S3">3. Standard I/O and Application Libraries</A>\r
+      </H3>\r
+      <P>\r
+         As we have seen above, FastCGI for Java offers a redefinition of standard I/O corresponding to the the\r
+         <I>fcgi_stdio</I> functionality. It also offers a set of directly callable I/O methods corresponding to the\r
+         <I>fcgiapp</I> C library. To understand where these methods occur we need to look briefly at the FastCGI\r
+         redefinition of standard I/O.\r
+      </P>\r
+      <P>\r
+         Java defines standard I/O in the <I>java.System</I> class as follows:\r
+      </P>\r
+      <P>\r
+         public static InputStream in = new BufferedInputStream(new FileInputStream(FileDescriptor.in), 128);<BR>\r
+         public static PrintStream out = new PrintStream(new BufferedOutputStream(new\r
+         FileOutputStream(FileDescriptor.out), 128), true);<BR>\r
+         public static PrintStream err = new PrintStream(new BufferedOutputStream(new\r
+         FileOutputStream(FileDescriptor.err), 128), true);\r
+      </P>\r
+      <P>\r
+         The File Descriptors <I>in</I>, <I>out</I>, <I>err</I> are constants set to 0, 1 and 2 respectively.\r
+      </P>\r
+      <P>\r
+         The FastCGI interface redefines <I>java.System in, out</I>, and <I>err</I> by replacing the File streams with\r
+         Socket streams and inserting streams which know how to manage the FastCGI protocol between the Socket streams\r
+         and the Buffered streams in the above definitions.\r
+      </P>\r
+      <P>\r
+         For those cases where the FCGI application needs to bypass the standard I/O streams, it can directly access\r
+         the methods of the FCGI input and output streams which roughly correspond to the functions in the C\r
+         <I>fcgiapp</I> library. These streams can be accessed via the <I>request</I> class variable in FCGIInterface.\r
+         Each Request object has instance variables that refer to an FCGIInputStream, and to two FCGIOutputStreams\r
+         associated with that request.\r
+      </P>\r
+      <H3>\r
+         <A NAME="S4">4. Environment Variables</A>\r
+      </H3>\r
+      <P>\r
+         Java does not use the C <I>environ</I> list. Nor is there a <I>getenv</I> command that reads system\r
+         environment variables. This is intentional for reasons of portability and security. Java has an internal\r
+         dictionary of properties which belongs to the System class. These System properties are <I>name/value</I>\r
+         associations that constitute the Java environment. When a Java application starts up, it reads in a file with\r
+         default properties. As we have seen, additional System properties may be inserted by using the -D <I>Java</I>\r
+         command argument.\r
+      </P>\r
+      <P>\r
+         For CGI, where the Java application is invoked from a .cgi script that, in turn, invokes the Java interpreter,\r
+         this script could read the environment and pass the variables to the Java application either by writing a file\r
+         or by creating -D options on the fly. Both of these methods are somewhat awkward.\r
+      </P>\r
+      <P>\r
+         For FastCGI Java applications, the environment variables are obtained from the FastCGI web server via\r
+         <TT>FCGI_PARAMS</TT> records that are sent to the application at the start of each request. The FastCGI\r
+         interface stores the original startup properties, combines these with the properties obtained from the server,\r
+         and puts the new set of properties in the System properties dictionary. The only parameter that has to be\r
+         specifically added at startup time is the FCGI_PORT parameter for the Socket creation. In the future, we\r
+         expect that even this parameter won&#39;t be needed, since its use is due to an acknowledged rigidity in the\r
+         JDK&#39;s implementation of sockets.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S4">5. Further examples: EchoFCGI and Echo2FCGI</A>\r
+      </H3>\r
+      <P>\r
+         The next two examples illustrate the points made in the last two sections. EchoFCGI and Echo2FCGI both echo\r
+         user input and display the application&#39;s environment variables. EchoFCGI reads the user input from\r
+         System.in, while Echo2FCGI reads the user input directly from the intermediate FastCGI input stream.\r
+      </P>\r
+      <H4>\r
+         A. EchoFCGI\r
+      </H4>\r
+<PRE>\r
+import FCGIInterface;\r
+import FCGIGlobalDefs;\r
+import java.io.*;\r
+\r
+class EchoFCGI {\r
\r
+ public static void main (String args[]) {\r
+  int status = 0;\r
+   while(new FCGIInterface().FCGIaccept()&gt;= 0) {\r
+  System.out.println(&quot;Content-type: text/html\n\n&quot;);\r
+   System.out.println(&quot;&lt;html&gt;&quot;);\r
+   System.out.println(\r
+    &quot;&lt;head%gt;&lt;TITLE&gt;FastCGI echo\r
+                                      &lt;/TITLE&gt;&lt;/head&gt;&quot;);\r
+   System.out.println(&quot;&lt;body&gt;&quot;); \r
+   System.out.println(\r
+                                         &quot;&lt;H2&gt;FastCGI echo&lt;/H2&gt;&quot;);\r
+   System.out.println(&quot;&lt;H3&gt;STDIN&lt;/H3&gt;&quot;);\r
+   for ( int c = 0; c != -1; ) {\r
+    try {\r
+     c = System.in.read();\r
+    } catch(IOException e) {\r
+     System.out.println(\r
+     &quot;&lt;br&gt;&lt;b&gt;SYSTEM EXCEPTION&quot;);\r
+     Runtime rt = Runtime.getRuntime();\r
+     rt.exit(status);\r
+     }\r
+    if (c != -1) { \r
+     System.out.print((char)c);\r
+     }\r
+    }\r
+   System.out.println(\r
+    &quot;&lt;H3&gt;Environment Variables:&lt;/H3&gt;&quot;);\r
\r
+   System.getProperties().list(System.out);\r
+   System.out.println(&quot;&lt;/body&gt;&quot;);\r
+   System.out.println(&quot;&lt;/html&gt;&quot;);\r
+      }\r
+  }\r
+   }\r
+</PRE>\r
+      <H4>\r
+         B. Echo2FCGI\r
+      </H4>\r
+<PRE>\r
+import FCGIInterface;\r
+import FCGIGlobalDefs;\r
+import FCGIInputStream;\r
+import FCGIOutputStream;\r
+import FCGIMessage;\r
+import FCGIRequest;\r
+import java.io.*;\r
+\r
+class Echo2FCGI {\r
+\r
+ public static void main (String args[]) {\r
+  int status = 0;\r
+                FCGIInterface intf = new FCGIInterface();\r
+   while(intf.FCGIaccept()&gt;= 0) {\r
+  System.out.println(&quot;Content-type: text/html\n\n&quot;);\r
+   System.out.println(&quot;&lt;html&gt;&quot;);\r
+   System.out.println(\r
+    &quot;&lt;head&gt;&lt;TITLE&gt;FastCGI echo\r
+                                    &lt;/TITLE&gt;&lt;/head&gt;&quot;);\r
+   System.out.println(&quot;&lt;body&gt;&quot;);   \r
+   System.out.println(&quot;&lt;H2&gt;FastCGI echo&lt;/H2&gt;&quot;);\r
+   System.out.println(&quot;&lt;H3&gt;STDIN:&lt;/H3&quot;&gt;);\r
+   for ( int c = 0; c != -1; ) {\r
+    try {\r
+     c = intf.request.inStream.read();\r
+    } catch(IOException e) {\r
+     System.out.println(\r
+     &quot;&lt;br&gt;&lt;b&gt;SYSTEM EXCEPTION&quot;);\r
+     Runtime rt = Runtime.getRuntime();\r
+     rt.exit(status);\r
+     }\r
+    if (c != -1) { \r
+     System.out.print((char)c);\r
+     }\r
+    }\r
+   System.out.println(\r
+    &quot;&lt;H3&gt;Environment Variables:&lt;/H3&gt;&quot;);\r
\r
+   System.getProperties().list(System.out);\r
+   System.out.println(&lt;&quot;/body&gt;&quot;);\r
+   System.out.println(&quot;&lt;/html&gt;&quot;);\r
+      }\r
+  }\r
+   }\r
+</PRE>\r
+      <H4>\r
+         C. Running these Examples\r
+      </H4>\r
+      <H5>\r
+         Configuring\r
+      </H5>\r
+      <P>\r
+         As with TinyFCGI, you need to configure the web server to recognize these two FastCGI applications. Your\r
+         configuration now looks like this:\r
+      </P>\r
+      <P>\r
+      </P>\r
+<PRE>\r
+ExternalAppClass java1 -host hostname:portNum\r
+Responder java1 fcgi-devel-kit/examples/TinyFCGI\r
+ExternalAppClass java2 -host hostname:portNumA\r
+Responder java2 fcgi-devel-kit/examples/EchoFCGI\r
+ExternalAppClass java3 -host hostname:porNumB\r
+Responder java3 fcgi-devel-kit/examples/Echo2FCGI\r
+</PRE>\r
+      <P>\r
+         Note that the application classes and port numbers are different for each application.\r
+      </P>\r
+      <H5>\r
+         Running\r
+      </H5>\r
+      <P>\r
+         As with TinyFCGI, you need to run these programs with the -D option using FCGI_PORT and the appropriate port\r
+         number. To get some data for standard input we have created two html pages with forms that use a POST method.\r
+         These are echo.html and echo2.html. You must edit these .html files to expand the path to\r
+         <I>fcgi-devel-kit/examples</I> to a full path. Once the appropriate Java program is running, point your\r
+         browser at the corresponding HTML page, enter some data and select the <I>go_find</I> button.\r
+      </P>\r
+      <H3>\r
+         <A NAME="S6">6. FastCGI Java Classes</A>\r
+      </H3>\r
+      <P>\r
+         The Java FastCGI classes are included in both source and byte code format in <I>fcgi-devel-kit/java/src</I>\r
+         and :<I>fcgi-devel-kit/java/classes</I> respectively. The following is a brief description of these classes:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <DL>\r
+         <DT CLASS="c4">\r
+            FCGIInterface\r
+         </DT>\r
+         <DD>\r
+            This class contains the FCGIaccept method called by the FastCGI user application. This method sets up the\r
+            appropriate FastCGI environment for communication with the web server and manages FastCGI requests.<BR>\r
+         </DD>\r
+         <DT CLASS="c4">\r
+            FCGIInputStream\r
+         </DT>\r
+         <DD>\r
+            This input stream manages FastCGI internal buffers to ensure that the user gets all of the FastCGI messages\r
+            associated with a request. It uses FCGIMessage objects to interpret these incoming messages.<BR>\r
+         </DD>\r
+         <DT CLASS="c4">\r
+            FCGIOutputStream\r
+         </DT>\r
+         <DD>\r
+            This output stream manages FastCGI internal buffers to send user data back to the web server and to notify\r
+            the server of various FCGI protocol conditions. It uses FCGIMessage objects to format outgoing FastCGI\r
+            messages.<BR>\r
+         </DD>\r
+         <DT CLASS="c4">\r
+            FCGIMessage\r
+         </DT>\r
+         <DD>\r
+            This is the only class that understands the actual structure of the FastCGI messages. It interprets\r
+            incoming FastCGI records and constructs outgoing ones..<BR>\r
+         </DD>\r
+         <DT CLASS="c4">\r
+            FCGIRequest\r
+         </DT>\r
+         <DD>\r
+            This class currently contains data fields used by FastCGI to manage user requests. In a multi-threaded\r
+            version of FastCGI, the role of this class will be expanded.<BR>\r
+         </DD>\r
+         <DT CLASS="c4">\r
+            FCGIGlobalDefs\r
+         </DT>\r
+         <DD>\r
+            This class contains definitions of FastCGI constants.\r
+         </DD>\r
+      </DL>\r
+      <HR>\r
+      <ADDRESS>\r
+         <A HREF="mailto:harris@openmarket.com">Steve Harris // harris@openmarket.com</A>\r
+      </ADDRESS>\r
+   </BODY>\r
+</HTML>\r
+\r
index 0e2b5f6..329ce28 100644 (file)
-<html>
-<head><title>Understanding FastCGI Application Performance</title>
-</head>
-
-<body bgcolor="#FFFFFF" text="#000000" link="#cc0000" alink="#000011" 
-vlink="#555555">
-
-<center>
-<a href="http://fastcgi.com">
-    <img border=0 src="../images/fcgi-hd.gif" alt="[[FastCGI]]"></a>
-</center>
-<br clear=all>
-<h3><center>Understanding FastCGI Application Performance</center></h3>
-
-<!--Copyright (c) 1996 Open Market, Inc.                                    -->
-<!--See the file "LICENSE.TERMS" for information on usage and redistribution-->
-<!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->
-
-<center>
-Mark R. Brown<br>
-Open Market, Inc.<br>
-<p>
-
-10 June 1996<br>
-</center>
-<p>
-
-<h5 align=center>
-Copyright &copy; 1996 Open Market, Inc.  245 First Street, Cambridge,
-  MA 02142 U.S.A.<br>
-Tel: 617-621-9500 Fax: 617-621-1703 URL:
-  <a href="http://www.openmarket.com/">http://www.openmarket.com/</a><br>
-$Id: fcgi-perf.htm,v 1.2 2001/05/14 13:01:38 robs Exp $ <br>
-</h5>
-<hr>
-
-<ul type=square>
-    <li><a HREF = "#S1">1. Introduction</a>
-    <li><a HREF = "#S2">2. Performance Basics</a>
-    <li><a HREF = "#S3">3. Caching</a>
-    <li><a HREF = "#S4">4. Database Access</a>
-    <li><a HREF = "#S5">5. A Performance Test</a>
-    <ul type=square>
-        <li><a HREF = "#S5.1">5.1 Application Scenario</a>
-        <li><a HREF = "#S5.2">5.2 Application Design</a>
-        <li><a HREF = "#S5.3">5.3 Test Conditions</a>
-        <li><a HREF = "#S5.4">5.4 Test Results and Discussion</a>
-    </ul>
-    <li><a HREF = "#S6">6. Multi-threaded APIs</a>
-    <li><a HREF = "#S7">7. Conclusion</a>
-</ul>
-<p>
-
-<hr>
-
-
-<h3><a name = "S1">1. Introduction</a></h3>
-
-
-Just how fast is FastCGI?  How does the performance of a FastCGI
-application compare with the performance of the same
-application implemented using a Web server API?<p>
-
-Of course, the answer is that it depends upon the application.
-A more complete answer is that FastCGI often wins by a significant
-margin, and seldom loses by very much.<p>
-
-Papers on computer system performance can be laden with complex graphs
-showing how this varies with that.  Seldom do the graphs shed much
-light on <i>why</i> one system is faster than another.  Advertising copy is
-often even less informative.  An ad from one large Web server vendor
-says that its server "executes web applications up to five times
-faster than all other servers," but the ad gives little clue where the
-number "five" came from.<p>
-
-This paper is meant to convey an understanding of the primary factors
-that influence the performance of Web server applications and to show
-that architectural differences between FastCGI and server APIs often
-give an "unfair" performance advantage to FastCGI applications.  We
-run a test that shows a FastCGI application running three times faster
-than the corresponding Web server API application.  Under different
-conditions this factor might be larger or smaller.  We show you what
-you'd need to measure to figure that out for the situation you face,
-rather than just saying "we're three times faster" and moving on.<p>
-
-This paper makes no attempt to prove that FastCGI is better than Web
-server APIs for every application.  Web server APIs enable lightweight
-protocol extensions, such as Open Market's SecureLink extension, to be
-added to Web servers, as well as allowing other forms of server
-customization.  But APIs are not well matched to mainstream applications
-such as personalized content or access to corporate databases, because
-of API drawbacks including high complexity, low security, and
-limited scalability.  FastCGI shines when used for the vast
-majority of Web applications.<p>
-
-
-
-<h3><a name = "S2">2. Performance Basics</a></h3>
-
-
-Since this paper is about performance we need to be clear on
-what "performance" is.<p>
-
-The standard way to measure performance in a request-response system
-like the Web is to measure peak request throughput subject to a
-response time constriaint.  For instance, a Web server application
-might be capable of performing 20 requests per second while responding
-to 90% of the requests in less than 2 seconds.<p>
-
-Response time is a thorny thing to measure on the Web because client
-communications links to the Internet have widely varying bandwidth.
-If the client is slow to read the server's response, response time at
-both the client and the server will go up, and there's nothing the
-server can do about it.  For the purposes of making repeatable
-measurements the client should have a high-bandwidth communications
-link to the server.<p>
-
-[Footnote: When designing a Web server application that will be
-accessed over slow (e.g. 14.4 or even 28.8 kilobit/second modem)
-channels, pay attention to the simultaneous connections bottleneck.
-Some servers are limited by design to only 100 or 200 simultaneous
-connections.  If your application sends 50 kilobytes of data to a
-typical client that can read 2 kilobytes per second, then a request
-takes 25 seconds to complete.  If your server is limited to 100
-simultaneous connections, throughput is limited to just 4 requests per
-second.]<p>
-
-Response time is seldom an issue when load is light, but response
-times rise quickly as the system approaches a bottleneck on some
-limited resource.  The three resources that typical systems run out of
-are network I/O, disk I/O, and processor time.  If short response time
-is a goal, it is a good idea to stay at or below 50% load on each of
-these resources.  For instance, if your disk subsystem is capable of
-delivering 200 I/Os per second, then try to run your application at
-100 I/Os per second to avoid having the disk subsystem contribute to
-slow response times.  Through careful management it is possible to
-succeed in running closer to the edge, but careful management is both
-difficult and expensive so few systems get it.<p>
-
-If a Web server application is local to the Web server machine, then
-its internal design has no impact on network I/O.  Application design
-can have a big impact on usage of disk I/O and processor time.<p>
-
-
-
-<h3><a name = "S3">3. Caching</a></h3>
-
-
-It is a rare Web server application that doesn't run fast when all the
-information it needs is available in its memory.  And if the
-application doesn't run fast under those conditions, the possible
-solutions are evident: Tune the processor-hungry parts of the
-application, install a faster processor, or change the application's
-functional specification so it doesn't need to do so much work.<p>
-
-The way to make information available in memory is by caching.  A
-cache is an in-memory data structure that contains information that's
-been read from its permanent home on disk.  When the application needs
-information, it consults the cache, and uses the information if it is
-there.  Otherwise is reads the information from disk and places a copy
-in the cache.  If the cache is full, the application discards some old
-information before adding the new.  When the application needs to
-change cached information, it changes both the cache entry and the
-information on disk.  That way, if the application crashes, no
-information is lost; the application just runs more slowly for awhile
-after restarting, because the cache doesn't improve performance
-when it is empty.<p>
-
-Caching can reduce both disk I/O and processor time, because reading
-information from disk uses more processor time than reading it from
-the cache.  Because caching addresses both of the potential
-bottlenecks, it is the focal point of high-performance Web server
-application design.  CGI applications couldn't perform in-memory
-caching, because they exited after processing just one request.  Web
-server APIs promised to solve this problem.  But how effective is the
-solution?<p>
-
-Today's most widely deployed Web server APIs are based on a
-pool-of-processes server model.  The Web server consists of a parent
-process and a pool of child processes.  Processes do not share memory.
-An incoming request is assigned to an idle child at random.  The child
-runs the request to completion before accepting a new request.  A
-typical server has 32 child processes, a large server has 100 or 200.<p>
-
-In-memory caching works very poorly in this server model because
-processes do not share memory and incoming requests are assigned to
-processes at random.  For instance, to keep a frequently-used file
-available in memory the server must keep a file copy per child, which
-wastes memory.  When the file is modified all the children need to be
-notified, which is complex (the APIs don't provide a way to do it).<p>
-
-FastCGI is designed to allow effective in-memory caching.  Requests
-are routed from any child process to a FastCGI application server.
-The FastCGI application process maintains an in-memory cache.<p>
-
-In some cases a single FastCGI application server won't
-provide enough performance.  FastCGI provides two solutions:
-session affinity and multi-threading.<p>
-
-With session affinity you run a pool of application processes and the
-Web server routes requests to individual processes based on any
-information contained in the request.  For instance, the server can
-route according to the area of content that's been requested, or
-according to the user.  The user might be identified by an
-application-specific session identifier, by the user ID contained in
-an Open Market Secure Link ticket, by the Basic Authentication user
-name, or whatever.  Each process maintains its own cache, and session
-affinity ensures that each incoming request has access to the cache
-that will speed up processing the most.<p>
-
-With multi-threading you run an application process that is designed
-to handle several requests at the same time.  The threads handling
-concurrent requests share process memory, so they all have access to
-the same cache.  Multi-threaded programming is complex -- concurrency
-makes programs difficult to test and debug -- but with FastCGI you can
-write single threaded <i>or</i> multithreaded applications.<p>
-
-
-
-<h3><a name = "S4">4. Database Access</a></h3>
-
-
-Many Web server applications perform database access.  Existing
-databases contain a lot of valuable information; Web server
-applications allow companies to give wider access to the information.<p>
-
-Access to database management systems, even within a single machine,
-is via connection-oriented protocols.  An application "logs in" to a
-database, creating a connection, then performs one or more accesses.
-Frequently, the cost of creating the database connection is several
-times the cost of accessing data over an established connection.<p>
-
-To a first approximation database connections are just another type of
-state to be cached in memory by an application, so the discussion of
-caching above applies to caching database connections.<p>
-
-But database connections are special in one respect: They are often
-the basis for database licensing.  You pay the database vendor
-according to the number of concurrent connections the database system
-can sustain.  A 100-connection license costs much more than a
-5-connection license.  It follows that caching a database connection
-per Web server child process is not just wasteful of system's hardware
-resources, it could break your software budget.<p>
-
-
-
-<h3><a name = "S5">5. A Performance Test</a></h3>
-
-
-We designed a test application to illustrate performance issues.  The
-application represents a class of applications that deliver
-personalized content.  The test application is quite a bit simpler
-than any real application would be, but still illustrates the main
-performance issues.  We implemented the application using both FastCGI
-and a current Web server API, and measured the performance of each.<p>
-
-<h4><a name = "S5.1">5.1 Application Scenario</a></h4>
-
-The application is based on a user database and a set of
-content files.  When a user requests a content file, the application
-performs substitutions in the file using information from the
-user database.  The application then returns the modified
-content to the user.<p>
-
-Each request accomplishes the following:<p>
-
-<ol>
-    <li>authentication check: The user id is used to retrieve and
-        check the password.<p>
-
-    <li>attribute retrieval: The user id is used to retrieve all
-        of the user's attribute values.<p>
-
-    <li>file retrieval and filtering: The request identifies a
-        content file. This file is read and all occurrences of variable
-        names are replaced with the user's corresponding attribute values.
-        The modified HTML is returned to the user.<p>
-</ol>
-
-Of course, it is fair game to perform caching to shortcut
-any of these steps.<p>
-
-Each user's database record (including password and attribute
-values) is approximately 100 bytes long.  Each content file is 3,000
-bytes long.  Both database and content files are stored
-on disks attached to the server platform.<p>
-
-A typical user makes 10 file accesses with realistic think times
-(30-60 seconds) between accesses, then disappears for a long time.<p>
-
-
-<h4><a name = "S5.2">5.2 Application Design</a></h4>
-
-The FastCGI application maintains a cache of recently-accessed
-attribute values from the database.  When the cache misses
-the application reads from the database.  Because only a small
-number of FastCGI application processes are needed, each process
-opens a database connection on startup and keeps it open.<p>
-
-The FastCGI application is configured as multiple application
-processes.  This is desirable in order to get concurrent application
-processing during database reads and file reads.  Requests are routed
-to these application processes using FastCGI session affinity keyed on
-the user id.  This way all a user's requests after the first hit in
-the application's cache.<p>
-
-The API application does not maintain a cache; the API application has
-no way to share the cache among its processes, so the cache hit rate
-would be too low to make caching pay.  The API application opens and
-closes a database connection on every request; keeping database
-connections open between requests would result in an unrealistically
-large number of database connections open at the same time, and very
-low utilization of each connection.<p>
-
-
-<h4><a name = "S5.3">5.3 Test Conditions</a></h4>
-
-The test load is generated by 10 HTTP client processes.  The processes
-represent disjoint sets of users.  A process makes a request for a
-user, then a request for a different user, and so on until it is time
-for the first user to make another request.<p>
-
-For simplicity the 10 client processes run on the same machine
-as the Web server.  This avoids the possibility that a network
-bottleneck will obscure the test results.  The database system
-also runs on this machine, as specified in the application scenario.<p>
-
-Response time is not an issue under the test conditions.  We just
-measure throughput.<p>
-
-The API Web server is in these tests is Netscape 1.1.<p>
-
-
-<h4><a name = "S5.4">5.4 Test Results and Discussion</a></h4>
-
-Here are the test results:<p>
-
-<ul>
-<pre>
-    FastCGI  12.0 msec per request = 83 requests per second
-    API      36.6 msec per request = 27 requests per second
-</pre>
-</ul>
-
-Given the big architectural advantage that the FastCGI application
-enjoys over the API application, it is not surprising that the
-FastCGI application runs a lot faster.  To gain a deeper
-understanding of these results we measured two more conditions:<p>
-
-<ul>
-    <li>API with sustained database connections.  If you could
-        afford the extra licensing cost, how much faster would
-        your API application run?<p>
-
-<pre>
-    API      16.0 msec per request = 61 requests per second
-</pre>
-
-        Answer: Still not as fast as the FastCGI application.<p>
-
-    <li>FastCGI with cache disabled.  How much benefit does the
-        FastCGI application get from its cache?<p>
-
-<pre>
-    FastCGI  20.1 msec per request = 50 requests per second
-</pre>
-
-        Answer: A very substantial benefit, even though the database
-        access is quite simple.<p>
-</ul>
-
-What these two extra experiments show is that if the API and FastCGI
-applications are implemented in exactly the same way -- caching
-database connections but not caching user profile data -- the API
-application is slightly faster.  This is what you'd expect, since the
-FastCGI application has to pay the cost of inter-process
-communication not present in the API application.<p>
-
-In the real world the two applications would not be implemented in the
-same way.  FastCGI's architectural advantage results in much higher
-performance -- a factor of 3 in this test.  With a remote database
-or more expensive database access the factor would be higher.
-With more substantial processing of the content files the factor
-would be smaller.<p>
-
-
-
-<h3><a name = "S6">6. Multi-threaded APIs</a></h3>
-
-
-Web servers with a multi-threaded internal structure (and APIs to
-match) are now starting to become more common.  These servers don't
-have all of the disadvantages described in Section 3.  Does this mean
-that FastCGI's performance advantages will disappear?<p>
-
-A superficial analysis says yes.  An API-based application in a
-single-process, multi-threaded server can maintain caches and database
-connections the same way a FastCGI application can.  The API-based
-application does not pay for inter-process communication, so the
-API-based application will be slightly faster than the FastCGI
-application.<p>
-
-A deeper analysis says no.  Multi-threaded programming is complex,
-because concurrency makes programs much more difficult to test and
-debug.  In the case of multi-threaded programming to Web server APIs,
-the normal problems with multi-threading are compounded by the lack of
-isolation between different applications and between the applications
-and the Web server.  With FastCGI you can write programs in the
-familiar single-threaded style, get all the reliability and
-maintainability of process isolation, and still get very high
-performance.  If you truly need multi-threading, you can write
-multi-threaded FastCGI and still isolate your multi-threaded
-application from other applications and from the server.  In short,
-multi-threading makes Web server APIs unusable for practially all
-applications, reducing the choice to FastCGI versus CGI.  The
-performance winner in that contest is obviously FastCGI.<p>
-
-
-
-<h3><a name = "S7">7. Conclusion</a></h3>
-
-
-Just how fast is FastCGI?  The answer: very fast indeed.  Not because
-it has some specially-greased path through the operating system, but
-because its design is well matched to the needs of most applications.
-We invite you to make FastCGI the fast, open foundation for your Web
-server applications.<p>
-
-
-
-<hr>
-<a href="http://www.openmarket.com/"><IMG SRC="omi-logo.gif" ALT="OMI Home Page"></a>
-
-<address>
-&#169 1995, Open Market, Inc. / mbrown@openmarket.com
-</address>
-
-</body>
-</html>
-
-
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
+<HTML>\r
+   <HEAD>\r
+      <TITLE>\r
+         Understanding FastCGI Application Performance\r
+      </TITLE>\r
+<STYLE TYPE="text/css">\r
+ body {\r
+  background-color: #FFFFFF;\r
+  color: #000000;\r
+ }\r
+ :link { color: #cc0000 }\r
+ :visited { color: #555555 }\r
+ :active { color: #000011 }\r
+ div.c3 {margin-left: 2em}\r
+ h5.c2 {text-align: center}\r
+ div.c1 {text-align: center}\r
+</STYLE>\r
+   </HEAD>\r
+   <BODY>\r
+      <DIV CLASS="c1">\r
+         <A HREF="http://fastcgi.com"><IMG BORDER="0" SRC="../images/fcgi-hd.gif" ALT="[[FastCGI]]"></A>\r
+      </DIV>\r
+      <BR CLEAR="all">\r
+      <DIV CLASS="c1">\r
+         <H3>\r
+            Understanding FastCGI Application Performance\r
+         </H3>\r
+      </DIV>\r
+      <!--Copyright (c) 1996 Open Market, Inc.                                    -->\r
+      <!--See the file "LICENSE.TERMS" for information on usage and redistribution-->\r
+      <!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->\r
+      <DIV CLASS="c1">\r
+         Mark R. Brown<BR>\r
+         Open Market, Inc.<BR>\r
+         <P>\r
+            10 June 1996<BR>\r
+         </P>\r
+      </DIV>\r
+      <P>\r
+      </P>\r
+      <H5 CLASS="c2">\r
+         Copyright &copy; 1996 Open Market, Inc. 245 First Street, Cambridge, MA 02142 U.S.A.<BR>\r
+         Tel: 617-621-9500 Fax: 617-621-1703 URL: <A HREF=\r
+         "http://www.openmarket.com/">http://www.openmarket.com/</A><BR>\r
+         $Id: fcgi-perf.htm,v 1.3 2001/11/27 01:03:47 robs Exp $<BR>\r
+      </H5>\r
+      <HR>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            <A HREF="#S1">1. Introduction</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S2">2. Performance Basics</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S3">3. Caching</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S4">4. Database Access</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S5">5. A Performance Test</A> \r
+            <UL TYPE="square">\r
+               <LI>\r
+                  <A HREF="#S5.1">5.1 Application Scenario</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S5.2">5.2 Application Design</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S5.3">5.3 Test Conditions</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S5.4">5.4 Test Results and Discussion</A>\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S6">6. Multi-threaded APIs</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S7">7. Conclusion</A>\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+      </P>\r
+      <HR>\r
+      <H3>\r
+         <A NAME="S1">1. Introduction</A>\r
+      </H3>\r
+      <P>\r
+         Just how fast is FastCGI? How does the performance of a FastCGI application compare with the performance of\r
+         the same application implemented using a Web server API?\r
+      </P>\r
+      <P>\r
+         Of course, the answer is that it depends upon the application. A more complete answer is that FastCGI often\r
+         wins by a significant margin, and seldom loses by very much.\r
+      </P>\r
+      <P>\r
+         Papers on computer system performance can be laden with complex graphs showing how this varies with that.\r
+         Seldom do the graphs shed much light on <I>why</I> one system is faster than another. Advertising copy is\r
+         often even less informative. An ad from one large Web server vendor says that its server &quot;executes web\r
+         applications up to five times faster than all other servers,&quot; but the ad gives little clue where the\r
+         number &quot;five&quot; came from.\r
+      </P>\r
+      <P>\r
+         This paper is meant to convey an understanding of the primary factors that influence the performance of Web\r
+         server applications and to show that architectural differences between FastCGI and server APIs often give an\r
+         &quot;unfair&quot; performance advantage to FastCGI applications. We run a test that shows a FastCGI\r
+         application running three times faster than the corresponding Web server API application. Under different\r
+         conditions this factor might be larger or smaller. We show you what you&#39;d need to measure to figure that\r
+         out for the situation you face, rather than just saying &quot;we&#39;re three times faster&quot; and moving\r
+         on.\r
+      </P>\r
+      <P>\r
+         This paper makes no attempt to prove that FastCGI is better than Web server APIs for every application. Web\r
+         server APIs enable lightweight protocol extensions, such as Open Market&#39;s SecureLink extension, to be\r
+         added to Web servers, as well as allowing other forms of server customization. But APIs are not well matched\r
+         to mainstream applications such as personalized content or access to corporate databases, because of API\r
+         drawbacks including high complexity, low security, and limited scalability. FastCGI shines when used for the\r
+         vast majority of Web applications.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S2">2. Performance Basics</A>\r
+      </H3>\r
+      <P>\r
+         Since this paper is about performance we need to be clear on what &quot;performance&quot; is.\r
+      </P>\r
+      <P>\r
+         The standard way to measure performance in a request-response system like the Web is to measure peak request\r
+         throughput subject to a response time constriaint. For instance, a Web server application might be capable of\r
+         performing 20 requests per second while responding to 90% of the requests in less than 2 seconds.\r
+      </P>\r
+      <P>\r
+         Response time is a thorny thing to measure on the Web because client communications links to the Internet have\r
+         widely varying bandwidth. If the client is slow to read the server&#39;s response, response time at both the\r
+         client and the server will go up, and there&#39;s nothing the server can do about it. For the purposes of\r
+         making repeatable measurements the client should have a high-bandwidth communications link to the server.\r
+      </P>\r
+      <P>\r
+         [Footnote: When designing a Web server application that will be accessed over slow (e.g. 14.4 or even 28.8\r
+         kilobit/second modem) channels, pay attention to the simultaneous connections bottleneck. Some servers are\r
+         limited by design to only 100 or 200 simultaneous connections. If your application sends 50 kilobytes of data\r
+         to a typical client that can read 2 kilobytes per second, then a request takes 25 seconds to complete. If your\r
+         server is limited to 100 simultaneous connections, throughput is limited to just 4 requests per second.]\r
+      </P>\r
+      <P>\r
+         Response time is seldom an issue when load is light, but response times rise quickly as the system approaches\r
+         a bottleneck on some limited resource. The three resources that typical systems run out of are network I/O,\r
+         disk I/O, and processor time. If short response time is a goal, it is a good idea to stay at or below 50% load\r
+         on each of these resources. For instance, if your disk subsystem is capable of delivering 200 I/Os per second,\r
+         then try to run your application at 100 I/Os per second to avoid having the disk subsystem contribute to slow\r
+         response times. Through careful management it is possible to succeed in running closer to the edge, but\r
+         careful management is both difficult and expensive so few systems get it.\r
+      </P>\r
+      <P>\r
+         If a Web server application is local to the Web server machine, then its internal design has no impact on\r
+         network I/O. Application design can have a big impact on usage of disk I/O and processor time.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S3">3. Caching</A>\r
+      </H3>\r
+      <P>\r
+         It is a rare Web server application that doesn&#39;t run fast when all the information it needs is available\r
+         in its memory. And if the application doesn&#39;t run fast under those conditions, the possible solutions are\r
+         evident: Tune the processor-hungry parts of the application, install a faster processor, or change the\r
+         application&#39;s functional specification so it doesn&#39;t need to do so much work.\r
+      </P>\r
+      <P>\r
+         The way to make information available in memory is by caching. A cache is an in-memory data structure that\r
+         contains information that&#39;s been read from its permanent home on disk. When the application needs\r
+         information, it consults the cache, and uses the information if it is there. Otherwise is reads the\r
+         information from disk and places a copy in the cache. If the cache is full, the application discards some old\r
+         information before adding the new. When the application needs to change cached information, it changes both\r
+         the cache entry and the information on disk. That way, if the application crashes, no information is lost; the\r
+         application just runs more slowly for awhile after restarting, because the cache doesn&#39;t improve\r
+         performance when it is empty.\r
+      </P>\r
+      <P>\r
+         Caching can reduce both disk I/O and processor time, because reading information from disk uses more processor\r
+         time than reading it from the cache. Because caching addresses both of the potential bottlenecks, it is the\r
+         focal point of high-performance Web server application design. CGI applications couldn&#39;t perform in-memory\r
+         caching, because they exited after processing just one request. Web server APIs promised to solve this\r
+         problem. But how effective is the solution?\r
+      </P>\r
+      <P>\r
+         Today&#39;s most widely deployed Web server APIs are based on a pool-of-processes server model. The Web server\r
+         consists of a parent process and a pool of child processes. Processes do not share memory. An incoming request\r
+         is assigned to an idle child at random. The child runs the request to completion before accepting a new\r
+         request. A typical server has 32 child processes, a large server has 100 or 200.\r
+      </P>\r
+      <P>\r
+         In-memory caching works very poorly in this server model because processes do not share memory and incoming\r
+         requests are assigned to processes at random. For instance, to keep a frequently-used file available in memory\r
+         the server must keep a file copy per child, which wastes memory. When the file is modified all the children\r
+         need to be notified, which is complex (the APIs don&#39;t provide a way to do it).\r
+      </P>\r
+      <P>\r
+         FastCGI is designed to allow effective in-memory caching. Requests are routed from any child process to a\r
+         FastCGI application server. The FastCGI application process maintains an in-memory cache.\r
+      </P>\r
+      <P>\r
+         In some cases a single FastCGI application server won&#39;t provide enough performance. FastCGI provides two\r
+         solutions: session affinity and multi-threading.\r
+      </P>\r
+      <P>\r
+         With session affinity you run a pool of application processes and the Web server routes requests to individual\r
+         processes based on any information contained in the request. For instance, the server can route according to\r
+         the area of content that&#39;s been requested, or according to the user. The user might be identified by an\r
+         application-specific session identifier, by the user ID contained in an Open Market Secure Link ticket, by the\r
+         Basic Authentication user name, or whatever. Each process maintains its own cache, and session affinity\r
+         ensures that each incoming request has access to the cache that will speed up processing the most.\r
+      </P>\r
+      <P>\r
+         With multi-threading you run an application process that is designed to handle several requests at the same\r
+         time. The threads handling concurrent requests share process memory, so they all have access to the same\r
+         cache. Multi-threaded programming is complex -- concurrency makes programs difficult to test and debug -- but\r
+         with FastCGI you can write single threaded <I>or</I> multithreaded applications.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S4">4. Database Access</A>\r
+      </H3>\r
+      <P>\r
+         Many Web server applications perform database access. Existing databases contain a lot of valuable\r
+         information; Web server applications allow companies to give wider access to the information.\r
+      </P>\r
+      <P>\r
+         Access to database management systems, even within a single machine, is via connection-oriented protocols. An\r
+         application &quot;logs in&quot; to a database, creating a connection, then performs one or more accesses.\r
+         Frequently, the cost of creating the database connection is several times the cost of accessing data over an\r
+         established connection.\r
+      </P>\r
+      <P>\r
+         To a first approximation database connections are just another type of state to be cached in memory by an\r
+         application, so the discussion of caching above applies to caching database connections.\r
+      </P>\r
+      <P>\r
+         But database connections are special in one respect: They are often the basis for database licensing. You pay\r
+         the database vendor according to the number of concurrent connections the database system can sustain. A\r
+         100-connection license costs much more than a 5-connection license. It follows that caching a database\r
+         connection per Web server child process is not just wasteful of system&#39;s hardware resources, it could\r
+         break your software budget.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S5">5. A Performance Test</A>\r
+      </H3>\r
+      <P>\r
+         We designed a test application to illustrate performance issues. The application represents a class of\r
+         applications that deliver personalized content. The test application is quite a bit simpler than any real\r
+         application would be, but still illustrates the main performance issues. We implemented the application using\r
+         both FastCGI and a current Web server API, and measured the performance of each.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S5.1">5.1 Application Scenario</A>\r
+      </H4>\r
+      <P>\r
+         The application is based on a user database and a set of content files. When a user requests a content file,\r
+         the application performs substitutions in the file using information from the user database. The application\r
+         then returns the modified content to the user.\r
+      </P>\r
+      <P>\r
+         Each request accomplishes the following:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <OL>\r
+         <LI>\r
+            authentication check: The user id is used to retrieve and check the password.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            attribute retrieval: The user id is used to retrieve all of the user&#39;s attribute values.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            file retrieval and filtering: The request identifies a content file. This file is read and all occurrences\r
+            of variable names are replaced with the user&#39;s corresponding attribute values. The modified HTML is\r
+            returned to the user.<BR>\r
+            <BR>\r
+         </LI>\r
+      </OL>\r
+      <P>\r
+         Of course, it is fair game to perform caching to shortcut any of these steps.\r
+      </P>\r
+      <P>\r
+         Each user&#39;s database record (including password and attribute values) is approximately 100 bytes long.\r
+         Each content file is 3,000 bytes long. Both database and content files are stored on disks attached to the\r
+         server platform.\r
+      </P>\r
+      <P>\r
+         A typical user makes 10 file accesses with realistic think times (30-60 seconds) between accesses, then\r
+         disappears for a long time.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S5.2">5.2 Application Design</A>\r
+      </H4>\r
+      <P>\r
+         The FastCGI application maintains a cache of recently-accessed attribute values from the database. When the\r
+         cache misses the application reads from the database. Because only a small number of FastCGI application\r
+         processes are needed, each process opens a database connection on startup and keeps it open.\r
+      </P>\r
+      <P>\r
+         The FastCGI application is configured as multiple application processes. This is desirable in order to get\r
+         concurrent application processing during database reads and file reads. Requests are routed to these\r
+         application processes using FastCGI session affinity keyed on the user id. This way all a user&#39;s requests\r
+         after the first hit in the application&#39;s cache.\r
+      </P>\r
+      <P>\r
+         The API application does not maintain a cache; the API application has no way to share the cache among its\r
+         processes, so the cache hit rate would be too low to make caching pay. The API application opens and closes a\r
+         database connection on every request; keeping database connections open between requests would result in an\r
+         unrealistically large number of database connections open at the same time, and very low utilization of each\r
+         connection.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S5.3">5.3 Test Conditions</A>\r
+      </H4>\r
+      <P>\r
+         The test load is generated by 10 HTTP client processes. The processes represent disjoint sets of users. A\r
+         process makes a request for a user, then a request for a different user, and so on until it is time for the\r
+         first user to make another request.\r
+      </P>\r
+      <P>\r
+         For simplicity the 10 client processes run on the same machine as the Web server. This avoids the possibility\r
+         that a network bottleneck will obscure the test results. The database system also runs on this machine, as\r
+         specified in the application scenario.\r
+      </P>\r
+      <P>\r
+         Response time is not an issue under the test conditions. We just measure throughput.\r
+      </P>\r
+      <P>\r
+         The API Web server is in these tests is Netscape 1.1.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S5.4">5.4 Test Results and Discussion</A>\r
+      </H4>\r
+      <P>\r
+         Here are the test results:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <DIV CLASS="c3">\r
+<PRE>\r
+    FastCGI  12.0 msec per request = 83 requests per second\r
+    API      36.6 msec per request = 27 requests per second\r
+</PRE>\r
+      </DIV>\r
+      <P>\r
+         Given the big architectural advantage that the FastCGI application enjoys over the API application, it is not\r
+         surprising that the FastCGI application runs a lot faster. To gain a deeper understanding of these results we\r
+         measured two more conditions:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            API with sustained database connections. If you could afford the extra licensing cost, how much faster\r
+            would your API application run?\r
+            <P>\r
+            </P>\r
+<PRE>\r
+    API      16.0 msec per request = 61 requests per second\r
+</PRE>\r
+            Answer: Still not as fast as the FastCGI application.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            FastCGI with cache disabled. How much benefit does the FastCGI application get from its cache?\r
+            <P>\r
+            </P>\r
+<PRE>\r
+    FastCGI  20.1 msec per request = 50 requests per second\r
+</PRE>\r
+            Answer: A very substantial benefit, even though the database access is quite simple.<BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         What these two extra experiments show is that if the API and FastCGI applications are implemented in exactly\r
+         the same way -- caching database connections but not caching user profile data -- the API application is\r
+         slightly faster. This is what you&#39;d expect, since the FastCGI application has to pay the cost of\r
+         inter-process communication not present in the API application.\r
+      </P>\r
+      <P>\r
+         In the real world the two applications would not be implemented in the same way. FastCGI&#39;s architectural\r
+         advantage results in much higher performance -- a factor of 3 in this test. With a remote database or more\r
+         expensive database access the factor would be higher. With more substantial processing of the content files\r
+         the factor would be smaller.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S6">6. Multi-threaded APIs</A>\r
+      </H3>\r
+      <P>\r
+         Web servers with a multi-threaded internal structure (and APIs to match) are now starting to become more\r
+         common. These servers don&#39;t have all of the disadvantages described in Section 3. Does this mean that\r
+         FastCGI&#39;s performance advantages will disappear?\r
+      </P>\r
+      <P>\r
+         A superficial analysis says yes. An API-based application in a single-process, multi-threaded server can\r
+         maintain caches and database connections the same way a FastCGI application can. The API-based application\r
+         does not pay for inter-process communication, so the API-based application will be slightly faster than the\r
+         FastCGI application.\r
+      </P>\r
+      <P>\r
+         A deeper analysis says no. Multi-threaded programming is complex, because concurrency makes programs much more\r
+         difficult to test and debug. In the case of multi-threaded programming to Web server APIs, the normal problems\r
+         with multi-threading are compounded by the lack of isolation between different applications and between the\r
+         applications and the Web server. With FastCGI you can write programs in the familiar single-threaded style,\r
+         get all the reliability and maintainability of process isolation, and still get very high performance. If you\r
+         truly need multi-threading, you can write multi-threaded FastCGI and still isolate your multi-threaded\r
+         application from other applications and from the server. In short, multi-threading makes Web server APIs\r
+         unusable for practially all applications, reducing the choice to FastCGI versus CGI. The performance winner in\r
+         that contest is obviously FastCGI.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S7">7. Conclusion</A>\r
+      </H3>\r
+      <P>\r
+         Just how fast is FastCGI? The answer: very fast indeed. Not because it has some specially-greased path through\r
+         the operating system, but because its design is well matched to the needs of most applications. We invite you\r
+         to make FastCGI the fast, open foundation for your Web server applications.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <HR>\r
+      <A HREF="http://www.openmarket.com/"><IMG SRC="omi-logo.gif" ALT="OMI Home Page"></A> \r
+      <ADDRESS>\r
+         &copy; 1995, Open Market, Inc. / mbrown@openmarket.com\r
+      </ADDRESS>\r
+   </BODY>\r
+</HTML>\r
+\r
index 014c953..65cb067 100644 (file)
-<html>
-<head><title>Integrating FastCGI with Perl-5</title>
-</head>
-
-<body bgcolor="#FFFFFF" text="#000000" link="#cc0000" alink="#000011" 
-vlink="#555555">
-
-<center>
-<a href="http://fastcgi.com">
-    <img border=0 src="../images/fcgi-hd.gif" alt="[[FastCGI]]"></a>
-</center>
-<br clear=all>
-<h3><center>Integrating FastCGI with Perl-5</center></h3>
-
-<!--Copyright (c) 1996 Open Market, Inc.                                    -->
-<!--See the file "LICENSE.TERMS" for information on usage and redistribution-->
-<!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->
-
-<h5 align=center>
-Copyright &copy; 1996 Open Market, Inc.  245 First Street, Cambridge,
-  MA 02142 U.S.A.<br>
-Tel: 617-949-7000 URL:
-  <a href="http://www.openmarket.com/">http://www.openmarket.com/</a><br>
-$Id: fcgi-perl.htm,v 1.2 2001/05/14 13:00:30 robs Exp $ <br>
-</h5>
-<hr>
-
-<ul type=square>
-  <li><a HREF = "#S1">1. Introduction</a>
-  <li><a HREF = "#S2">2. Perl with sfio and an FCGI module</a>
-  <li><a HREF = "#S3">3. Perl with fcgi_stdio and an FCGI module</a>
-  <ul type=square>
-    <li><a HREF = "#S3.1">3.1 Basic recipe</a>
-    <li><a HREF = "#S3.2">3.2 Semi-advanced recipe</a>
-    <li><a HREF = "#S3.3">3.3 Advanced recipe</a>
-  </ul>
-  <li><a HREF = "#S4">4. Writing FastCGI applications in Perl</a>
-</ul>
-
-
-<H3><A NAME = "S1"> 1. Introduction</A></H3>
-Perl (Practical Extraction and Report Language) is a scripting language that
-is often used for CGI programming.  Perl is freely available as a
-source kit.<p>
-
-FastCGI has been integrated with Perl in two different ways:
-<ol>
-  <li>By writing a module that plugs into any Perl interpreter that's
-      been built with sfio, a stdio alternative from AT&T.
-  <li>By writing a module that plugs into any Perl interpreter that's
-      been built with FastCGI's fcgi_stdio library
-      layering over stdio.
-
-The first approach, implemented by Sven Verdoolaege
-(skimo@breughel.ufsia.ac.be), is probably the better of the two,
-since sfio is a generally useful addition to Perl.
-The second approach, implemented by engineers at Open Market,
-predates the availability of an sfio-integrated
-Perl and demonstrates that the fcgi_stdio library
-can be used with a substantial C application.<p>
-
-The two approaches
-are compatible at the Perl source code level; a Perl
-application developed using
-one approach can be run using the other.  And both approaches
-result in a general-purpose Perl interpreter, not a Perl interpreter
-that's only usable for FastCGI applications.<p>
-
-This memo documents both approaches and explains a small
-Perl FastCGI application.<p>
-
-
-<h3><a name ="S2"> 2. Perl with sfio and an FCGI module</a></h3>
-
-As of release 5 patch 3 subpatch 2 (5.003.02), Perl has announced an optional 
-support for sfio (safe/fast string/file I/O), which is an alternative
-to stdio that AT&T distributes freely.  An advantage of sfio over stdio
-is that sfio provides the ability to implement
-new stream classes that don't simply transfer sequential bytes to or from
-a file descriptor.  This flexibility is exactly what FastCGI needs in order
-to implement the standard I/O streams in a manner that's
-transparent to applications.<p>
-
-Perl interpreters incorporating sfio are not widely available in
-binary form, so most likely you'll have to build your own.
-Your build should go smoothly if you follow the instructions
-below.  The instructions assume:<p>
-
-<ul>
-  <li>You are building Perl 5.0 patch level 3 subpatch level 2 (5.003.02) 
-      or higher.  That's the first Perl release to support sfio.<p>
-</ul>
-<P>
-
-Follow these steps to build a Perl with sfio:<p>
-
-<ol>
-  <li>Obtain sfio source code from 
-      <a href="ftp://ftp.funet.fi/pub/languages/perl/CPAN/src/misc">
-      ftp://ftp.funet.fi/pub/languages/perl/CPAN/src/misc</a><p>
-
-  <li>Unpack the tar file using <tt>tar xvf</tt> command.  <EM>$sfio</EM>
-      will be used as a shorthand for the directory in which sfio package 
-      is installed.<p>
-
-  <li>Update your $PATH variable as specified in <tt>$sfio/README</tt> and 
-      run <tt>make</tt> command in the <tt>$sfio/src/lib/sfio</tt> subdirectory.<p>
-
-  <li>Rename or delete the file <tt>$sfio/include/stdio.h</tt>, since it may
-      interfere in the further build process.<p>
-
-  <li>Obtain Perl source (version 5 subversion 003 patchlevel 2 or higher) from
-      <a href="http://fohnix.metronet.com/perlinfo/source/5.0/unsupported">
-      http://fohnix.metronet.com/perlinfo/source/5.0/unsupported</a><p>
-
-  <li>Unpack the tar file using <tt>tar xvf</tt> command.  <EM>$perl</EM> is
-      used as a shorthand for the directory that is created.<p>
-
-  <li>Configure, build, and install Perl as follows:
-
-<pre>
-% cd $perl
-% ./Configure -Duseperlio -Dusesfio
-% make 
-% make test
-% make install
-</pre><p>
-
-There are certain Configure questions that must be answered
-differently when building Perl with sfio:<p>
-
-<DL>
-
-<DT><EM>Perl5 can now use alternate file IO mechanisms to ANSI stdio.
-However these are experimental and may cause problems with some
-extension modules.
-Use stdio as with previous versions? [y] </EM></DT>
-<DD>
-You should answer no.
-</DD><P>
-
-<DT><EM>Any additional cc flags?</EM></DT>
-<DD>
-You should use the following cc flags along with any defaults that Perl
-Configure supplied:
-<UL>
-<LI> <strong>-I<em>$sfio</em>/include</strong>
-</UL>
-</DD><P>
-
-<DT><EM>Any additional ld flags (NOT including libraries):</EM></DT>
-<DD>
-You should specify the following <tt>ld</tt> flags:
-<UL>
-<LI> <strong>-L<em>$sfio</em>/lib</strong>
-</UL>
-</DD><P>
-
-<DT><EM>Additional Libraries:</EM></DT>
-<DD>
-Check that <strong>-lsfio</strong> is one of the specified libraries.  Press 
-return key to continue.  
-</DD><P>
-</DL>
-
-<b>NOTE</b>: If you did not install Perl as a root user, make sure to 
-correctly set environment variable <tt>PERL5LIB</tt> to indicate the location
-of Perl libraries.  For example, if you installed Perl binary into the 
-<tt>$INSTALL</tt> subdirectory and you are running Solaris, the following 
-will set your proper library path: 
-<pre>
-% setenv PERL5LIB $INSTALL/lib:$INSTALL/lib/sun4-solaris/perl5.003_02
-</pre>
-
-<p>
-
-  <li>Obtain Perl/Sfio module for FastCGI support from 
-      <a href="ftp://ftp.funet.fi/pub/languages/perl/CPAN/authors/id/SKIMO">
-      ftp://ftp.funet.fi/pub/languages/perl/CPAN/authors/id/SKIMO</a><p>
-
-  <li>Unpack FCGI module using <tt>tar</tt> command.  We use <tt>$sfiomod</tt>
-      to denote the subdirectory that is created in the process.<p>
-
-  <li>Build and install the module with the following commands:
-<pre>
-% cd $sfiomod
-% $INSTALL/bin/perl Makefile.PL
-% make
-% make test
-% make install
-</pre>
-</ol>
-
-
-<H3><a NAME = "S3">3. Perl with fcgi_stdio and an FCGI module</a></H3>
-
-<H4><a NAME = "S3.1">3.1 Basic recipe</a></H4>
-
-Here are the assumptions embedded in the following recipe:
-<UL>
-
-<LI>You are building Perl 5.0 Patch 2 (5.002) or higher, since 
-all examples that are provided are based on that release.
-<P></P>
-
-<LI>You have gcc version 2.7 installed on your system, and use it in the
-build.  gcc is convenient because it supports the <tt>-include</tt>
-command-line option that instructs the C preprocessor to include a specific
-file before processing any other include files.  This allows you to include
-<tt>fcgi_stdio.h</tt> without modifying Perl source files.  (The reason for
-specifying gcc version 2.7 is that I have experienced bad behavior with an
-earlier version and the <tt>-include</tt> flag -- the C preprocessor died
-with SIGABRT.)
-<P></P>
-
-<LI> <EM>$fcgi</EM> is used as shorthand for the full path of the FastCGI
-developers kit.
-</UL>
-<P>
-If those are valid assumptions, follow these steps:
-<OL>
-<LI> Pull the Perl source kit from
-<A HREF="http://www.metronet.com/perlinfo/src/latest.tar.gz">
-http://www.metronet.com/perlinfo/src/latest.tar.gz</A>
-<P>
-There are good sources of information on Perl at:
-<UL>
-<LI> <A HREF="http://www.perl.com/">http://www.perl.com/</A>
-<LI> <A HREF="http://www.metronet.com/perlinfo/">http://www.metronet.com/perlinfo/</A>
-</UL>
-<p></P>
-
-<LI> Unpack the tar file in the parent directory of the FastCGI kit
-directory, so that the perl directory is a sibling of <tt>fcgi-devel-kit</tt>.
-<EM>$perl</EM> is used as shorthand for the full path of the directory
-in which Perl is installed.
-<p>
-<LI> Copy the version specific and the common files from
-<tt>fcgi-devel-kit/perl-5</tt> into the Perl-5 kit.
-<PRE>
-> cd $perl
-> mv perl.c perl.c.orig
-> mv proto.h proto.h.orig
-> mv Configure Configure.orig
-> cp -r ../fcgi-devel-kit/perl-5/perl5.002/* .
-> cp -r ../fcgi-devel-kit/perl-5/common/* .
-</PRE>
-<P>
-The files you are copying contain the Perl-5 FCGI extension, some
-files modified from the distribution, and a script to simplify the
-configuration process.
-</P>
-<LI> Set environment variables.
-The Perl-5 FastCGI configuration process requires that the environment
-variable <TT>FCGIDIR</TT> be set to the top level directory of the FastCGI
-development kit.
-<PRE>
-> setenv FCGIDIR <EM>$fcgi</EM>
-</PRE>
-If you do not want to use <tt>gcc</tt> to build Perl you can set the
-environment variable <TT>CC</TT> to the desired compiler. For example:
-<PRE>
-> setenv CC gcc2.7
-</PRE>
-By default Perl's installation prefix is /usr/local, so binaries get
-installed in /usr/local/bin, library files get installed into
-/usr/local/lib/perl, etc. If you want to specify a different installation
-prefix set the environment variable <tt>PERL_PREFIX</tt>.
-<PRE>
-> setenv PERL_PREFIX /usr/local/perl5-fcgi
-</PRE>
-<LI> Run fcgi-configure.
-<PRE>
-> ./fcgi-configure
-</PRE>
-<P>
-<TT>fcgi-configure</TT> is a wrapper around Perl's <tt>Configure</tt> script.
-It sets some variables according the the value of some environment variables,
-and runs Perl's <tt>Configure</tt> script
-in such a way that it does not prompt the
-user for any input. 90% of the time this should work without a problem.
-If for some reason this does not work for you, you'll have to
-follow the steps in the next section.<p>
-<LI> Run make.
-<PRE>
-> make
-</PRE>
-<LI> Install the newly built Perl-5.
-<PRE>
-> make install
-</PRE>
-</OL><p>
-
-
-<H4><a NAME = "S3.2">3.2 Semi-advanced recipe</a></H4>
-
-If you do not have experience configuring and building Perl, you
-should find someone who does.  Perl can be pretty intimidating to configure
-since it asks you a large number of irrelevant-seeming
-questions that you won't know how to answer.<p>
-<P>
-<OL>
-<LI>Go into the top level directory of the Perl distribution and run
-<tt>Configure</tt>.
-<PRE>
-> cd $perl
-> ./Configure
-</PRE>
-<LI>
-There are some questions that you are going to
-have to answer differently when building FastCGI into Perl.
-These are described below:
-<P></P>
-<DL>
-<DT><EM>Use which C compiler?</EM></DT>
-<DD>
-You should specify <tt>gcc</tt>.
-</DD>
-<P></P>
-<DT><EM>Any additional cc flags?</EM></DT>
-<DD>
-You should use the following cc flags along with any defaults that Perl
-Configure supplied:
-<UL>
-<LI> <strong>-I<em>$fcgi</em>/include</strong>
-<LI> <strong>-include <em>$fcgi</em>/include/fcgi_stdio.h</strong>
-</UL>
-This assumes you are using GCC.
-</DD>
-<P></P>
-
-<DT><EM>Any additional ld flags (NOT including libraries):</EM></DT>
-<DD>
-You should specify the following <tt>ld</tt> flags:
-<UL>
-<LI> <strong>-L<em>$fcgi</em>/libfcgi</strong>
-</UL
-></DD>
-<P></P>
-
-<DT><EM>Additional Libraries:</EM></DT>
-<DD>
-add <strong>-lfcgi</strong> to the list of additional libraries.
-It should be added before -lc.
-</DD>
-<P></P>
-
-<DT><EM>What extensions do you wish to load dynamically?</EM></DT>
-<DD>
-If you can support dynamic extensions, <tt>Configure</tt>
-will ask which of the
-supplied extensions should be loaded dynamically. Since we copied the FCGI
-extension into the Perl source directory it should be one of the ones in the
-default list. If you want FCGI to be dynamically loaded you should specify
-it here, otherwise leave it out.
-</DD>
-<P></P>
-
-<DT><EM>What extensions do you wish to load statically?</EM></DT>
-<DD>
-If you do not support Dynamic extensions this is the only question about
-extensions you would get asked. You should specify FCGI here if you did not
-get asked about dynamic extensions (or did not specify FCGI as a dynamic
-extension).
-</DD>
-</DL>
-<P></P>
-<LI> Copy in the new <tt>proto.h</tt>.
-<P>
-The file proto.h has some macros that conflict with the FastCGI macros.
-The version of <tt>proto.h</tt> supplied in the FastCGI kit
-includes these changes:<p>
-<UL>
-<LI> At the beginning of the file it adds the following lines:
-<PRE>
-#ifdef _FCGI_STDIO
-#undef printf
-#endif
-</PRE>
-<LI> At the bottom it adds:
-<PRE>
-#ifdef _FCGI_STDIO
-#define printf FCGI_printf
-#endif
-</PRE>
-</UL>
-<LI> Copy in the new <tt>perl.c</tt>.
-<P>
-Perl-5.002 has a bug in <tt>perl.c</tt> that has a great
-chance of getting exercised
-with FastCGI.  A fix has been sumbitted to the Perl developers and hopefully
-it'll make it into perl-5.003. It was a one line fix, here is a diff for the
-curious:
-<PRE>
-*** perl.c      1996/03/15 17:10:10     1.1
---- perl.c      1996/03/15 17:11:23
-***************
-*** 405,410 ****
---- 405,411 ----
-      if (e_fp) {
-       if (Fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
-           croak("Can't write to temp file for -e: %s", Strerror(errno));
-+      e_fp = Nullfp;
-       argc++,argv--;
-       scriptname = e_tmpname;
-      }
-</PRE>
-Pretty straightforward.<p>
-<LI> Build and install Perl.
-<PRE>
-> make
-<EM>[...]</EM>
-> make install
-</PRE>
-
-<p></P>
-<H4><a NAME = "S3.3">3.3 Advanced recipe</a></H4>
-
-<P>
-If you already have a Perl-5 package that has been configured, and you do
-not really want to re-run Configure, you can take the following steps.
-</P>
-<P ALIGN=CENTER><STRONG>THIS IS NOT RECOMMENDED</STRONG></P>
-<P>
-Edit config.sh with your favorite editor and modify the following lines:
-        <DL> 
-          <DT><EM>cc</EM></DT>
-          <DD> Change to use gcc if you are not using it already. </DD>
-          <P></P>
-          <DT><EM>ccflags</EM> AND <EM>cppflags</EM></DT>
-          <DD> Add the following flags: 
-            <UL>
-              <LI> <strong>-I<em>$fcgi</em>/include</strong> 
-              <LI> <strong>-include <em>$fcgi</em>/include/fcgi_stdio.h</strong> 
-            </UL>
-            This assumes you are using GCC. See the above section on assumptions 
-          </DD>
-          <P></P>
-          <DT><EM>extensions</EM> AND <EM>known_extensions</EM></DT>
-          <DD> Add FCGI to the list of extensions </DD>
-          <P></P>
-          <DT><EM>ldflags</EM></DT>
-          <DD> Add -L $fcgi/libfcgi to the list. </DD>
-          <P></P>
-          <DT><EM>libs</EM></DT>
-          <DD> Add -lfcgi to the list of libraries, should be added before -lc. 
-          </DD>
-          <P></P>
-          <DT><EM>static_ext</EM><STRONG> or </STRONG><EM>dynamic_ext</EM></DT>
-          <DD> Add FCGI to the list of statically or dynamically loaded extensions. 
-          </DD>
-          <P></P>
-          <DT><EM>d_stdio_cnt_lval, d_stdio_ptr_lval, d_stdiobase, d_stdstdio</EM></DT>
-          <DL> Change all of these to undef. </DL>
-          <P> One you have edited config.sh you should do a "make Makefile depend 
-            all". If you're paranoid like me you may want to do a "make clean" 
-            first. </P>
-          <H3><A NAME = "S4"> 4. Writing FastCGI applications in Perl</A></H3>
-          <P> The Perl program <tt>examples/tiny-perl-fcgi</tt> performs the same 
-            function as the C program <tt>examples/tiny-fcgi</tt> that's used 
-            as an example in the <A HREF="fcgi-devel-kit.htm#S3.1.1">FastCGI Developer's 
-            Kit</A>. Here's what the Perl version looks like: </P>
-          <pre>
-#!./perl
-use FCGI;
-$count = 0;
-while(FCGI::accept() >= 0) {
-    print("Content-type: text/html\r\n\r\n",
-          "&lt;title&gt;FastCGI Hello! (Perl)&lt;/title&gt;\n",
-          "&lt;h1&gt;FastCGI Hello! (Perl)&lt;/h1&gt;\n",
-          "Request number ", $++count,
-          " running on host &lt;i&gt;$ENV('SERVER_NAME')&lt;/i&gt;");
-}
-</pre>
-          If you've built Perl according to the recipe and you have a Web server 
-          set up to run FastCGI applications, load the FastCGI Developer's Kit 
-          Index Page in that server and run this Perl application now. 
-          <p> The script invokes Perl indirectly via the symbolic link <tt>examples/perl</tt>. 
-            It does this because HP-UX has a limit of 32 characters for the first 
-            line of a command-interpreter file such as <tt>examples/tiny-perl-fcgi</tt>. 
-            If you run on HP-UX you won't want to sprinkle symbolic links to perl 
-            everywhere, so you should choose a <tt>PERL_PREFIX</tt> shorter than 
-            <tt>/usr/local/perl5-fcgi</tt>.
-          <p> You need to be aware of the following bug. If the initial environment 
-            to a FastCGI Perl application is empty (contains no name-value pairs) 
-            then when the first call to <tt>FCGI::accept</tt> returns, the environment 
-            will <i>still</i> be empty, i.e. <tt>%ENV</tt> will contain no associations. 
-            All the variables associated with the first request are lost. There 
-            are two known workarounds:
-          <p> 
-          <ul>
-            <li> In your Perl application, enumerate <tt>%ENV</tt> using <tt>each</tt> 
-              before entering the <tt>FCGI::accept</tt> loop. The program <tt>examples/tiny-perl-fcgi</tt> 
-              contains code for this. 
-              <p> 
-            <li> In configuring your application be sure to set at least one initial 
-              environment variable. You do this with the <tt>AppClass -initial-env</tt> 
-              directive to the Web server, or by running <tt>cgi-fcgi</tt> in 
-              a non-empty environment. 
-          </ul>
-          <p> The Perl subroutine <tt>FCGI::accept</tt> treats the initial environment 
-            differently than the C function <tt>FCGI_Accept</tt>. The first call 
-            to the C function <tt>FCGI_Accept</tt> replaces the initial environment 
-            with the environment of the first request. The first call to the Perl 
-            subroutine <tt>FCGI::accept</tt> adds the variable bindings of the 
-            first request to the bindings present in the initial environment. 
-            So when the first call to <tt>FCGI::accept</tt> returns, bindings 
-            from the initial environment are still there (unless, due to naming 
-            conflicts, some of them have been overwritten by the first request). 
-            The next call to <tt>FCGI::accept</tt> removes the bindings made on 
-            the previous call before adding a new set for the request just accepted, 
-            again preserving the initial environment.
-          <p> The Perl <tt>FCGI</tt> module also includes subroutines <tt>FCGI::finish</tt>, 
-            <tt>FCGI::set_exit_status</tt>, and <tt>FCGI::start_filter_data</tt> 
-            that correspond to C functions in <tt>fcgi_stdio.h</tt>; see the manpages 
-            for full information.
-          <p> Converting a Perl CGI application to FastCGI is not fundamentally 
-            different from converting a C CGI application. 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 <tt>FCGI::accept</tt>.
-          <p> 
-        </dl>
-      </ol></ol></body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
+<HTML>\r
+   <HEAD>\r
+      <TITLE>\r
+         Integrating FastCGI with Perl-5\r
+      </TITLE>\r
+<STYLE TYPE="text/css">\r
+ body {\r
+  background-color: #FFFFFF;\r
+  color: #000000;\r
+ }\r
+ :link { color: #cc0000 }\r
+ :visited { color: #555555 }\r
+ :active { color: #000011 }\r
+ p.c3 {text-align: center}\r
+ h5.c2 {text-align: center}\r
+ div.c1 {text-align: center}\r
+</STYLE>\r
+   </HEAD>\r
+   <BODY>\r
+      <DIV CLASS="c1">\r
+         <A HREF="http://fastcgi.com"><IMG BORDER="0" SRC="../images/fcgi-hd.gif" ALT="[[FastCGI]]"></A>\r
+      </DIV>\r
+      <BR CLEAR="all">\r
+      <DIV CLASS="c1">\r
+         <H3>\r
+            Integrating FastCGI with Perl-5\r
+         </H3>\r
+      </DIV>\r
+      <!--Copyright (c) 1996 Open Market, Inc.                                    -->\r
+      <!--See the file "LICENSE.TERMS" for information on usage and redistribution-->\r
+      <!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->\r
+      <H5 CLASS="c2">\r
+         Copyright &copy; 1996 Open Market, Inc. 245 First Street, Cambridge, MA 02142 U.S.A.<BR>\r
+         Tel: 617-949-7000 URL: <A HREF="http://www.openmarket.com/">http://www.openmarket.com/</A><BR>\r
+         $Id: fcgi-perl.htm,v 1.3 2001/11/27 01:03:47 robs Exp $<BR>\r
+      </H5>\r
+      <HR>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            <A HREF="#S1">1. Introduction</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S2">2. Perl with sfio and an FCGI module</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S3">3. Perl with fcgi_stdio and an FCGI module</A> \r
+            <UL TYPE="square">\r
+               <LI>\r
+                  <A HREF="#S3.1">3.1 Basic recipe</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S3.2">3.2 Semi-advanced recipe</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S3.3">3.3 Advanced recipe</A>\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S4">4. Writing FastCGI applications in Perl</A>\r
+         </LI>\r
+      </UL>\r
+      <H3>\r
+         <A NAME="S1">1. Introduction</A>\r
+      </H3>\r
+      <P>\r
+         Perl (Practical Extraction and Report Language) is a scripting language that is often used for CGI\r
+         programming. Perl is freely available as a source kit.\r
+      </P>\r
+      <P>\r
+         FastCGI has been integrated with Perl in two different ways:\r
+      </P>\r
+      <OL>\r
+         <LI>\r
+            By writing a module that plugs into any Perl interpreter that&#39;s been built with sfio, a stdio\r
+            alternative from AT&amp;T.\r
+         </LI>\r
+         <LI>\r
+            By writing a module that plugs into any Perl interpreter that&#39;s been built with FastCGI&#39;s\r
+            fcgi_stdio library layering over stdio. The first approach, implemented by Sven Verdoolaege\r
+            (skimo@breughel.ufsia.ac.be), is probably the better of the two, since sfio is a generally useful addition\r
+            to Perl. The second approach, implemented by engineers at Open Market, predates the availability of an\r
+            sfio-integrated Perl and demonstrates that the fcgi_stdio library can be used with a substantial C\r
+            application.\r
+            <P>\r
+               The two approaches are compatible at the Perl source code level; a Perl application developed using one\r
+               approach can be run using the other. And both approaches result in a general-purpose Perl interpreter,\r
+               not a Perl interpreter that&#39;s only usable for FastCGI applications.\r
+            </P>\r
+            <P>\r
+               This memo documents both approaches and explains a small Perl FastCGI application.\r
+            </P>\r
+            <P>\r
+            </P>\r
+            <H3>\r
+               <A NAME="S2">2. Perl with sfio and an FCGI module</A>\r
+            </H3>\r
+            As of release 5 patch 3 subpatch 2 (5.003.02), Perl has announced an optional support for sfio (safe/fast\r
+            string/file I/O), which is an alternative to stdio that AT&amp;T distributes freely. An advantage of sfio\r
+            over stdio is that sfio provides the ability to implement new stream classes that don&#39;t simply transfer\r
+            sequential bytes to or from a file descriptor. This flexibility is exactly what FastCGI needs in order to\r
+            implement the standard I/O streams in a manner that&#39;s transparent to applications.\r
+            <P>\r
+               Perl interpreters incorporating sfio are not widely available in binary form, so most likely you&#39;ll\r
+               have to build your own. Your build should go smoothly if you follow the instructions below. The\r
+               instructions assume:\r
+            </P>\r
+            <P>\r
+            </P>\r
+            <UL>\r
+               <LI>\r
+                  You are building Perl 5.0 patch level 3 subpatch level 2 (5.003.02) or higher. That&#39;s the first\r
+                  Perl release to support sfio.<BR>\r
+                  <BR>\r
+               </LI>\r
+            </UL>\r
+            <P>\r
+               Follow these steps to build a Perl with sfio:\r
+            </P>\r
+            <P>\r
+            </P>\r
+            <OL>\r
+               <LI>\r
+                  Obtain sfio source code from <A HREF=\r
+                  "ftp://ftp.funet.fi/pub/languages/perl/CPAN/src/misc">ftp://ftp.funet.fi/pub/languages/perl/CPAN/src/misc</A>\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Unpack the tar file using <TT>tar xvf</TT> command. <EM>$sfio</EM> will be used as a shorthand for\r
+                  the directory in which sfio package is installed.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Update your $PATH variable as specified in <TT>$sfio/README</TT> and run <TT>make</TT> command in the\r
+                  <TT>$sfio/src/lib/sfio</TT> subdirectory.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Rename or delete the file <TT>$sfio/include/stdio.h</TT>, since it may interfere in the further build\r
+                  process.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Obtain Perl source (version 5 subversion 003 patchlevel 2 or higher) from <A HREF=\r
+                  "http://fohnix.metronet.com/perlinfo/source/5.0/unsupported">http://fohnix.metronet.com/perlinfo/source/5.0/unsupported</A>\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Unpack the tar file using <TT>tar xvf</TT> command. <EM>$perl</EM> is used as a shorthand for the\r
+                  directory that is created.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Configure, build, and install Perl as follows: \r
+<PRE>\r
+% cd $perl\r
+% ./Configure -Duseperlio -Dusesfio\r
+% make \r
+% make test\r
+% make install\r
+</PRE>\r
+                  <P>\r
+                     There are certain Configure questions that must be answered differently when building Perl with\r
+                     sfio:\r
+                  </P>\r
+                  <P>\r
+                  </P>\r
+                  <DL>\r
+                     <DT>\r
+                        <EM>Perl5 can now use alternate file IO mechanisms to ANSI stdio. However these are\r
+                        experimental and may cause problems with some extension modules. Use stdio as with previous\r
+                        versions? [y]</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        You should answer no.\r
+                     </DD>\r
+                     <DD>\r
+                        <P>\r
+                        </P>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>Any additional cc flags?</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        You should use the following cc flags along with any defaults that Perl Configure supplied: \r
+                        <UL>\r
+                           <LI>\r
+                              <STRONG>-I<EM>$sfio</EM>/include</STRONG>\r
+                           </LI>\r
+                        </UL>\r
+                     </DD>\r
+                     <DD>\r
+                        <P>\r
+                        </P>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>Any additional ld flags (NOT including libraries):</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        You should specify the following <TT>ld</TT> flags: \r
+                        <UL>\r
+                           <LI>\r
+                              <STRONG>-L<EM>$sfio</EM>/lib</STRONG>\r
+                           </LI>\r
+                        </UL>\r
+                     </DD>\r
+                     <DD>\r
+                        <P>\r
+                        </P>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>Additional Libraries:</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        Check that <STRONG>-lsfio</STRONG> is one of the specified libraries. Press return key to\r
+                        continue.\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                  </DL>\r
+                  <B>NOTE</B>: If you did not install Perl as a root user, make sure to correctly set environment\r
+                  variable <TT>PERL5LIB</TT> to indicate the location of Perl libraries. For example, if you installed\r
+                  Perl binary into the <TT>$INSTALL</TT> subdirectory and you are running Solaris, the following will\r
+                  set your proper library path: \r
+<PRE>\r
+% setenv PERL5LIB $INSTALL/lib:$INSTALL/lib/sun4-solaris/perl5.003_02\r
+</PRE>\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Obtain Perl/Sfio module for FastCGI support from <A HREF=\r
+                  "ftp://ftp.funet.fi/pub/languages/perl/CPAN/authors/id/SKIMO">ftp://ftp.funet.fi/pub/languages/perl/CPAN/authors/id/SKIMO</A>\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Unpack FCGI module using <TT>tar</TT> command. We use <TT>$sfiomod</TT> to denote the subdirectory\r
+                  that is created in the process.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Build and install the module with the following commands: \r
+<PRE>\r
+% cd $sfiomod\r
+% $INSTALL/bin/perl Makefile.PL\r
+% make\r
+% make test\r
+% make install\r
+</PRE>\r
+               </LI>\r
+            </OL>\r
+            <H3>\r
+               <A NAME="S3">3. Perl with fcgi_stdio and an FCGI module</A>\r
+            </H3>\r
+            <H4>\r
+               <A NAME="S3.1">3.1 Basic recipe</A>\r
+            </H4>\r
+            Here are the assumptions embedded in the following recipe: \r
+            <UL>\r
+               <LI>\r
+                  You are building Perl 5.0 Patch 2 (5.002) or higher, since all examples that are provided are based\r
+                  on that release. <BR>\r
+                  <BR>\r
+               </LI>\r
+               <LI>\r
+                  You have gcc version 2.7 installed on your system, and use it in the build. gcc is convenient because\r
+                  it supports the <TT>-include</TT> command-line option that instructs the C preprocessor to include a\r
+                  specific file before processing any other include files. This allows you to include\r
+                  <TT>fcgi_stdio.h</TT> without modifying Perl source files. (The reason for specifying gcc version 2.7\r
+                  is that I have experienced bad behavior with an earlier version and the <TT>-include</TT> flag -- the\r
+                  C preprocessor died with SIGABRT.) <BR>\r
+                  <BR>\r
+               </LI>\r
+               <LI>\r
+                  <EM>$fcgi</EM> is used as shorthand for the full path of the FastCGI developers kit.\r
+               </LI>\r
+            </UL>\r
+            <P>\r
+               If those are valid assumptions, follow these steps:\r
+            </P>\r
+            <OL>\r
+               <LI>\r
+                  Pull the Perl source kit from <A HREF=\r
+                  "http://www.metronet.com/perlinfo/src/latest.tar.gz">http://www.metronet.com/perlinfo/src/latest.tar.gz</A>\r
+                  \r
+                  <P>\r
+                     There are good sources of information on Perl at:\r
+                  </P>\r
+                  <UL>\r
+                     <LI>\r
+                        <A HREF="http://www.perl.com/">http://www.perl.com/</A>\r
+                     </LI>\r
+                     <LI>\r
+                        <A HREF="http://www.metronet.com/perlinfo/">http://www.metronet.com/perlinfo/</A>\r
+                     </LI>\r
+                  </UL>\r
+                  <BR>\r
+                  <BR>\r
+               </LI>\r
+               <LI>\r
+                  Unpack the tar file in the parent directory of the FastCGI kit directory, so that the perl directory\r
+                  is a sibling of <TT>fcgi-devel-kit</TT>. <EM>$perl</EM> is used as shorthand for the full path of the\r
+                  directory in which Perl is installed. <BR>\r
+                  <BR>\r
+               </LI>\r
+               <LI>\r
+                  Copy the version specific and the common files from <TT>fcgi-devel-kit/perl-5</TT> into the Perl-5\r
+                  kit. \r
+<PRE>\r
+&gt; cd $perl\r
+&gt; mv perl.c perl.c.orig\r
+&gt; mv proto.h proto.h.orig\r
+&gt; mv Configure Configure.orig\r
+&gt; cp -r ../fcgi-devel-kit/perl-5/perl5.002/* .\r
+&gt; cp -r ../fcgi-devel-kit/perl-5/common/* .\r
+</PRE>\r
+                  <P>\r
+                     The files you are copying contain the Perl-5 FCGI extension, some files modified from the\r
+                     distribution, and a script to simplify the configuration process.\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Set environment variables. The Perl-5 FastCGI configuration process requires that the environment\r
+                  variable <TT>FCGIDIR</TT> be set to the top level directory of the FastCGI development kit. \r
+<PRE>\r
+&gt; setenv FCGIDIR <EM>$fcgi</EM>\r
+</PRE>\r
+                  If you do not want to use <TT>gcc</TT> to build Perl you can set the environment variable <TT>CC</TT>\r
+                  to the desired compiler. For example: \r
+<PRE>\r
+&gt; setenv CC gcc2.7\r
+</PRE>\r
+                  By default Perl&#39;s installation prefix is /usr/local, so binaries get installed in /usr/local/bin,\r
+                  library files get installed into /usr/local/lib/perl, etc. If you want to specify a different\r
+                  installation prefix set the environment variable <TT>PERL_PREFIX</TT>. \r
+<PRE>\r
+&gt; setenv PERL_PREFIX /usr/local/perl5-fcgi\r
+</PRE>\r
+               </LI>\r
+               <LI>\r
+                  Run fcgi-configure. \r
+<PRE>\r
+&gt; ./fcgi-configure\r
+</PRE>\r
+                  <P>\r
+                     <TT>fcgi-configure</TT> is a wrapper around Perl&#39;s <TT>Configure</TT> script. It sets some\r
+                     variables according the the value of some environment variables, and runs Perl&#39;s\r
+                     <TT>Configure</TT> script in such a way that it does not prompt the user for any input. 90% of the\r
+                     time this should work without a problem. If for some reason this does not work for you, you&#39;ll\r
+                     have to follow the steps in the next section.\r
+                  </P>\r
+                  <BR>\r
+                  <BR>\r
+               </LI>\r
+               <LI>\r
+                  Run make. \r
+<PRE>\r
+&gt; make\r
+</PRE>\r
+               </LI>\r
+               <LI>\r
+                  Install the newly built Perl-5. \r
+<PRE>\r
+&gt; make install\r
+</PRE>\r
+               </LI>\r
+            </OL>\r
+            <P>\r
+            </P>\r
+            <H4>\r
+               <A NAME="S3.2">3.2 Semi-advanced recipe</A>\r
+            </H4>\r
+            If you do not have experience configuring and building Perl, you should find someone who does. Perl can be\r
+            pretty intimidating to configure since it asks you a large number of irrelevant-seeming questions that you\r
+            won&#39;t know how to answer.<BR>\r
+            <BR>\r
+            <BR>\r
+            <BR>\r
+            <OL>\r
+               <LI>\r
+                  Go into the top level directory of the Perl distribution and run <TT>Configure</TT>. \r
+<PRE>\r
+&gt; cd $perl\r
+&gt; ./Configure\r
+</PRE>\r
+               </LI>\r
+               <LI>\r
+                  There are some questions that you are going to have to answer differently when building FastCGI into\r
+                  Perl. These are described below: <BR>\r
+                  <BR>\r
+                  <DL>\r
+                     <DT>\r
+                        <EM>Use which C compiler?</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        You should specify <TT>gcc</TT>.\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>Any additional cc flags?</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        You should use the following cc flags along with any defaults that Perl Configure supplied: \r
+                        <UL>\r
+                           <LI>\r
+                              <STRONG>-I<EM>$fcgi</EM>/include</STRONG>\r
+                           </LI>\r
+                           <LI>\r
+                              <STRONG>-include <EM>$fcgi</EM>/include/fcgi_stdio.h</STRONG>\r
+                           </LI>\r
+                        </UL>\r
+                        This assumes you are using GCC.\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>Any additional ld flags (NOT including libraries):</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        You should specify the following <TT>ld</TT> flags: \r
+                        <UL>\r
+                           <LI>\r
+                              <STRONG>-L<EM>$fcgi</EM>/libfcgi</STRONG>\r
+                           </LI>\r
+                        </UL>\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>Additional Libraries:</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        add <STRONG>-lfcgi</STRONG> to the list of additional libraries. It should be added before -lc.\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>What extensions do you wish to load dynamically?</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        If you can support dynamic extensions, <TT>Configure</TT> will ask which of the supplied\r
+                        extensions should be loaded dynamically. Since we copied the FCGI extension into the Perl\r
+                        source directory it should be one of the ones in the default list. If you want FCGI to be\r
+                        dynamically loaded you should specify it here, otherwise leave it out.\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>What extensions do you wish to load statically?</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        If you do not support Dynamic extensions this is the only question about extensions you would\r
+                        get asked. You should specify FCGI here if you did not get asked about dynamic extensions (or\r
+                        did not specify FCGI as a dynamic extension).\r
+                     </DD>\r
+                  </DL>\r
+                  <BR>\r
+                  <BR>\r
+               </LI>\r
+               <LI>\r
+                  Copy in the new <TT>proto.h</TT>. \r
+                  <P>\r
+                     The file proto.h has some macros that conflict with the FastCGI macros. The version of\r
+                     <TT>proto.h</TT> supplied in the FastCGI kit includes these changes:\r
+                  </P>\r
+                  <BR>\r
+                  <BR>\r
+                  <UL>\r
+                     <LI>\r
+                        At the beginning of the file it adds the following lines: \r
+<PRE>\r
+#ifdef _FCGI_STDIO\r
+#undef printf\r
+#endif\r
+</PRE>\r
+                     </LI>\r
+                     <LI>\r
+                        At the bottom it adds: \r
+<PRE>\r
+#ifdef _FCGI_STDIO\r
+#define printf FCGI_printf\r
+#endif\r
+</PRE>\r
+                     </LI>\r
+                  </UL>\r
+               </LI>\r
+               <LI>\r
+                  Copy in the new <TT>perl.c</TT>. \r
+                  <P>\r
+                     Perl-5.002 has a bug in <TT>perl.c</TT> that has a great chance of getting exercised with FastCGI.\r
+                     A fix has been sumbitted to the Perl developers and hopefully it&#39;ll make it into perl-5.003.\r
+                     It was a one line fix, here is a diff for the curious:\r
+                  </P>\r
+<PRE>\r
+*** perl.c      1996/03/15 17:10:10     1.1\r
+--- perl.c      1996/03/15 17:11:23\r
+***************\r
+*** 405,410 ****\r
+--- 405,411 ----\r
+      if (e_fp) {\r
+ if (Fflush(e_fp) || ferror(e_fp) || fclose(e_fp))\r
+     croak(&quot;Can&#39;t write to temp file for -e: %s&quot;, Strerror(errno));\r
++ e_fp = Nullfp;\r
+ argc++,argv--;\r
+ scriptname = e_tmpname;\r
+      }\r
+</PRE>\r
+                  Pretty straightforward.<BR>\r
+                  <BR>\r
+               </LI>\r
+               <LI>\r
+                  Build and install Perl. \r
+<PRE>\r
+&gt; make\r
+<EM>[...]</EM>\r
+&gt; make install\r
+</PRE>\r
+                  <BR>\r
+                  <BR>\r
+                  <H4>\r
+                     <A NAME="S3.3">3.3 Advanced recipe</A>\r
+                  </H4>\r
+                  <P>\r
+                     If you already have a Perl-5 package that has been configured, and you do not really want to\r
+                     re-run Configure, you can take the following steps.\r
+                  </P>\r
+                  <P CLASS="c3">\r
+                     <STRONG>THIS IS NOT RECOMMENDED</STRONG>\r
+                  </P>\r
+                  <P>\r
+                     Edit config.sh with your favorite editor and modify the following lines:\r
+                  </P>\r
+                  <DL>\r
+                     <DT>\r
+                        <EM>cc</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        Change to use gcc if you are not using it already.\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>ccflags</EM> AND <EM>cppflags</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        Add the following flags: \r
+                        <UL>\r
+                           <LI>\r
+                              <STRONG>-I<EM>$fcgi</EM>/include</STRONG>\r
+                           </LI>\r
+                           <LI>\r
+                              <STRONG>-include <EM>$fcgi</EM>/include/fcgi_stdio.h</STRONG>\r
+                           </LI>\r
+                        </UL>\r
+                        This assumes you are using GCC. See the above section on assumptions\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>extensions</EM> AND <EM>known_extensions</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        Add FCGI to the list of extensions\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>ldflags</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        Add -L $fcgi/libfcgi to the list.\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>libs</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        Add -lfcgi to the list of libraries, should be added before -lc.\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>static_ext</EM> <STRONG>or</STRONG> <EM>dynamic_ext</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        Add FCGI to the list of statically or dynamically loaded extensions.\r
+                     </DD>\r
+                     <DD>\r
+                        <BR>\r
+                        <BR>\r
+                     </DD>\r
+                     <DT>\r
+                        <EM>d_stdio_cnt_lval, d_stdio_ptr_lval, d_stdiobase, d_stdstdio</EM>\r
+                     </DT>\r
+                     <DD>\r
+                        <DL>\r
+                           <DT>\r
+                              Change all of these to undef.\r
+                           </DT>\r
+                        </DL>\r
+                        <P>\r
+                           One you have edited config.sh you should do a &quot;make Makefile depend all&quot;. If\r
+                           you&#39;re paranoid like me you may want to do a &quot;make clean&quot; first.\r
+                        </P>\r
+                        <H3>\r
+                           <A NAME="S4">4. Writing FastCGI applications in Perl</A>\r
+                        </H3>\r
+                        <P>\r
+                           The Perl program <TT>examples/tiny-perl-fcgi</TT> performs the same function as the C\r
+                           program <TT>examples/tiny-fcgi</TT> that&#39;s used as an example in the <A HREF=\r
+                           "fcgi-devel-kit.htm#S3.1.1">FastCGI Developer&#39;s Kit</A>. Here&#39;s what the Perl\r
+                           version looks like:\r
+                        </P>\r
+<PRE>\r
+#!./perl\r
+use FCGI;\r
+$count = 0;\r
+while(FCGI::accept() &gt;= 0) {\r
+    print(&quot;Content-type: text/html\r\n\r\n&quot;,\r
+          &quot;&lt;title&gt;FastCGI Hello! (Perl)&lt;/title&gt;\n&quot;,\r
+          &quot;&lt;h1&gt;FastCGI Hello! (Perl)&lt;/h1&gt;\n&quot;,\r
+          &quot;Request number &quot;, $++count,\r
+          &quot; running on host &lt;i&gt;$ENV(&#39;SERVER_NAME&#39;)&lt;/i&gt;&quot;);\r
+}\r
+</PRE>\r
+                        If you&#39;ve built Perl according to the recipe and you have a Web server set up to run\r
+                        FastCGI applications, load the FastCGI Developer&#39;s Kit Index Page in that server and run\r
+                        this Perl application now. \r
+                        <P>\r
+                           The script invokes Perl indirectly via the symbolic link <TT>examples/perl</TT>. It does\r
+                           this because HP-UX has a limit of 32 characters for the first line of a command-interpreter\r
+                           file such as <TT>examples/tiny-perl-fcgi</TT>. If you run on HP-UX you won&#39;t want to\r
+                           sprinkle symbolic links to perl everywhere, so you should choose a <TT>PERL_PREFIX</TT>\r
+                           shorter than <TT>/usr/local/perl5-fcgi</TT>.\r
+                        </P>\r
+                        <P>\r
+                           You need to be aware of the following bug. If the initial environment to a FastCGI Perl\r
+                           application is empty (contains no name-value pairs) then when the first call to\r
+                           <TT>FCGI::accept</TT> returns, the environment will <I>still</I> be empty, i.e.\r
+                           <TT>%ENV</TT> will contain no associations. All the variables associated with the first\r
+                           request are lost. There are two known workarounds:\r
+                        </P>\r
+                        <P>\r
+                        </P>\r
+                        <UL>\r
+                           <LI>\r
+                              In your Perl application, enumerate <TT>%ENV</TT> using <TT>each</TT> before entering the\r
+                              <TT>FCGI::accept</TT> loop. The program <TT>examples/tiny-perl-fcgi</TT> contains code\r
+                              for this. \r
+                              <P>\r
+                              </P>\r
+                           </LI>\r
+                           <LI>\r
+                              In configuring your application be sure to set at least one initial environment variable.\r
+                              You do this with the <TT>AppClass -initial-env</TT> directive to the Web server, or by\r
+                              running <TT>cgi-fcgi</TT> in a non-empty environment.\r
+                           </LI>\r
+                        </UL>\r
+                        <P>\r
+                           The Perl subroutine <TT>FCGI::accept</TT> treats the initial environment differently than\r
+                           the C function <TT>FCGI_Accept</TT>. The first call to the C function <TT>FCGI_Accept</TT>\r
+                           replaces the initial environment with the environment of the first request. The first call\r
+                           to the Perl subroutine <TT>FCGI::accept</TT> adds the variable bindings of the first request\r
+                           to the bindings present in the initial environment. So when the first call to\r
+                           <TT>FCGI::accept</TT> returns, bindings from the initial environment are still there\r
+                           (unless, due to naming conflicts, some of them have been overwritten by the first request).\r
+                           The next call to <TT>FCGI::accept</TT> removes the bindings made on the previous call before\r
+                           adding a new set for the request just accepted, again preserving the initial environment.\r
+                        </P>\r
+                        <P>\r
+                           The Perl <TT>FCGI</TT> module also includes subroutines <TT>FCGI::finish</TT>,\r
+                           <TT>FCGI::set_exit_status</TT>, and <TT>FCGI::start_filter_data</TT> that correspond to C\r
+                           functions in <TT>fcgi_stdio.h</TT>; see the manpages for full information.\r
+                        </P>\r
+                        <P>\r
+                           Converting a Perl CGI application to FastCGI is not fundamentally different from converting\r
+                           a C CGI application. You separate the portion of the application that performs one-time\r
+                           initialization from the portion that performs per-request processing. You put the\r
+                           per-request processing into a loop controlled by <TT>FCGI::accept</TT>.\r
+                        </P>\r
+                        <P>\r
+                        </P>\r
+                     </DD>\r
+                  </DL>\r
+               </LI>\r
+            </OL>\r
+         </LI>\r
+      </OL>\r
+   </BODY>\r
+</HTML>\r
+\r
index b23c1ad..eb30ce8 100644 (file)
-<html>
-<!--Copyright (c) 1996 Open Market, Inc.                                    -->
-<!--See the file "LICENSE.TERMS" for information on usage and redistribution-->
-<!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->
-<head>
-<title>FastCGI Specification</title>
-</head>
-
-<body>
-<center>
-<h2>FastCGI Specification</h2>
-</center>
-
-<center>
-Mark R. Brown<br>
-Open Market, Inc.<br>
-<p>
-
-Document Version: 1.0<br>
-29 April 1996<br>
-</center>
-<p>
-
-<h5 align=center>
-Copyright &copy; 1996 Open Market, Inc.  245 First Street, Cambridge,
-  MA 02142 U.S.A.<br>
-Tel: 617-621-9500 Fax: 617-621-1703 URL:
-  <a href="http://www.openmarket.com/">http://www.openmarket.com/</a><br>
-<br>
-$Id: fcgi-spec.html,v 1.2 2001/05/14 13:00:30 robs Exp $
-</h5>
-<hr>
-
-
-<ul type=square>
-    <li><a HREF = "#S1">1. Introduction</a>
-    <li><a HREF = "#S2">2. Initial Process State</a>
-    <ul type=square>
-        <li><a HREF = "#S2.1">2.1 Argument list</a>
-        <li><a HREF = "#S2.2">2.2 File descriptors</a>
-        <li><a HREF = "#S2.3">2.3 Environment variables</a>
-        <li><a HREF = "#S2.4">2.4 Other state</a>
-    </ul>
-    <li><a HREF = "#S3">3. Protocol Basics</a>
-    <ul type=square>
-        <li><a HREF = "#S3.1">3.1 Notation</a>
-        <li><a HREF = "#S3.2">3.2 Accepting Transport Connections</a>
-        <li><a HREF = "#S3.3">3.3 Records</a>
-        <li><a HREF = "#S3.4">3.4 Name-Value Pairs</a>
-        <li><a HREF = "#S3.5">3.5 Closing Transport Connections</a>
-    </ul>
-    <li><a HREF = "#S4">4. Management Record Types</a>
-    <ul type=square>
-        <li><a HREF = "#S4.1">4.1 <tt>FCGI_GET_VALUES, FCGI_GET_VALUES_RESULT</tt></a>
-        <li><a HREF = "#S4.2">4.2 <tt>FCGI_UNKNOWN_TYPE</tt></a>
-    </ul>
-    <li><a HREF = "#S5">5. Application Record Types</a>
-    <ul type=square>
-        <li><a HREF = "#S5.1">5.1 <tt>FCGI_BEGIN_REQUEST</tt></a>
-        <li><a HREF = "#S5.2">5.2 Name-Value Pair Streams: <tt>FCGI_PARAMS</tt>, <tt>FCGI_RESULTS</tt></a>
-        <li><a HREF = "#S5.3">5.3 Byte Streams: <tt>FCGI_STDIN</tt>, <tt>FCGI_DATA</tt>, <tt>FCGI_STDOUT</tt>, <tt>FCGI_STDERR</tt></a>
-        <li><a HREF = "#S5.4">5.4 <tt>FCGI_ABORT_REQUEST</tt></a>
-        <li><a HREF = "#S5.5">5.5 <tt>FCGI_END_REQUEST</tt></a>
-    </ul>
-    <li><a HREF = "#S6">6. Roles</a>
-    <ul type=square>
-        <li><a HREF = "#S6.1">6.1 Role Protocols</a>
-        <li><a HREF = "#S6.2">6.2 Responder</a>
-        <li><a HREF = "#S6.3">6.3 Authorizer</a>
-        <li><a HREF = "#S6.4">6.4 Filter</a>
-    </ul>
-    <li><a HREF = "#S7">7. Errors</a>
-    <li><a HREF = "#S8">8. Types and Constants</a>
-    <li><a HREF = "#S9">9. References</a>
-    <li><a HREF = "#SA">A. Table: Properties of the record types</a>
-    <li><a HREF = "#SB">B. Typical Protocol Message Flow</a>
-</ul>
-<p>
-
-<hr>
-
-
-<h3><a name = "S1">1. Introduction</a></h3>
-
-FastCGI is an open extension to CGI that provides high performance
-for all Internet applications without the penalties of Web server
-APIs.<p>
-
-This specification has narrow
-goal: to specify, from an application perspective, the
-interface between a FastCGI application and a Web server that supports
-FastCGI.  Many Web server features related to FastCGI,
-e.g. application management facilities, have nothing to do with the
-application to Web server interface, and are not described here.<p>
-
-This specification is for Unix (more precisely, for POSIX systems that support
-Berkeley Sockets).  The bulk of the specification is a simple
-communications protocol that is independent of byte ordering
-and will extend to other systems.<p>
-
-We'll introduce FastCGI by comparing it with conventional Unix
-implementations of CGI/1.1.
-
-FastCGI is designed to support long-lived application processes,
-i.e. <i>application servers</i>.  That's a major difference
-compared with conventional Unix implementations of CGI/1.1,
-which construct an application process, use
-it respond to one request, and have it exit.<p>
-
-The initial state of a FastCGI process is more spartan than the initial
-state of a CGI/1.1 process, because the FastCGI process doesn't begin life
-connected to anything.  It doesn't have the conventional open files
-<tt>stdin</tt>, <tt>stdout</tt>, and <tt>stderr</tt>, and it doesn't
-receive much information through environment variables.  The key
-piece of initial state in a FastCGI process is a listening
-socket, through which it accepts connections from a Web server.<p>
-
-After a FastCGI process accepts a connection on its listening socket,
-the process executes a simple protocol to receive and send data.  The
-protocol serves two purposes.  First, the protocol
-multiplexes a single transport connection between several independent
-FastCGI requests.  This supports applications that are able to process
-concurrent requests using event-driven or multi-threaded programming
-techniques.  Second, within each request the protocol provides several
-independent data streams in each direction.  This way, for instance,
-both <tt>stdout</tt> and <tt>stderr</tt> data pass over a single
-transport connection from the application to the Web server, rather
-than requiring separate pipes as with CGI/1.1.<p>
-
-A FastCGI application plays one of several well-defined <i>roles</i>.
-The most familiar is the <i>Responder</i> role, in which the
-application receives all the information associated with an HTTP
-request and generates an HTTP response; that's the role CGI/1.1
-programs play.  A second role is <i>Authorizer</i>, in which the
-application receives all the information associated with an HTTP
-request and generates an authorized/unauthorized decision.
-A third role is <i>Filter</i>, in which the
-application receives all the information associated with an HTTP
-request, plus an extra stream of data from a file stored on the Web
-server, and generates a "filtered" version of the data stream as
-an HTTP response.  The framework is extensible so that more FastCGI
-can be defined later.<p>
-
-In the remainder of this specification the terms "FastCGI
-application," "application process," or "application server" are
-abbreviated to "application" whenever that won't cause confusion.<p>
-
-
-
-<h3><a name = "S2">2. Initial Process State</a></h3>
-
-
-<h4><a name = "S2.1">2.1 Argument list</a></h4>
-
-By default the Web server creates an argument list containing a single
-element, the name of the application, taken to be the last component
-of the executable's path name.  The Web server may provide a way
-to specify a different application name, or a more elaborate argument
-list.<p>
-
-Note that the file executed by the Web server might be an interpreter
-file (a text file that starts with the characters <tt>#!</tt>), in
-which case the application's argument list is constructed as described
-in the <tt>execve</tt> manpage.<p>
-
-
-<h4><a name = "S2.2">2.2 File descriptors</a></h4>
-
-The Web server leaves a single file descriptor,
-<tt>FCGI_LISTENSOCK_FILENO</tt>, open when the application begins
-execution.  This descriptor refers to a listening socket created by
-the Web server.<p>
-
-<tt>FCGI_LISTENSOCK_FILENO</tt> equals <tt>STDIN_FILENO</tt>.
-The standard descriptors
-<tt>STDOUT_FILENO</tt> and <tt>STDERR_FILENO</tt> are closed when
-the application begins execution.  A reliable method for an application
-to determine whether it was invoked using CGI or FastCGI is to call
-<tt>getpeername(FCGI_LISTENSOCK_FILENO)</tt>, which returns
--1 with <tt>errno</tt> set to <tt>ENOTCONN</tt> for
-a FastCGI application.<p>
-
-The Web server's choice of reliable transport, Unix stream pipes
-(<tt>AF_UNIX</tt>) or TCP/IP (<tt>AF_INET</tt>), is implicit in the
-internal state of the <tt>FCGI_LISTENSOCK_FILENO</tt> socket.<p>
-
-
-<h4><a name = "S2.3">2.3 Environment variables</a></h4>
-
-The Web server may use environment variables to pass parameters
-to the application.  This specification defines one such
-variable, <tt>FCGI_WEB_SERVER_ADDRS</tt>; we expect more to
-be defined as the specification evolves.
-
-The Web server may provide a way to bind other environment
-variables, such as the <tt>PATH</tt> variable.<p>
-
-
-<h4><a name = "S2.4">2.4 Other state</a></h4>
-
-The Web server may provide a way to specify other components of an
-application's initial process state, such as the priority,
-user ID, group ID, root directory, and working directory of the
-process.<p>
-
-
-
-<h3><a name = "S3">3. Protocol Basics</a></h3>
-
-
-<h4><a name = "S3.1">3.1 Notation</a></h4>
-
-We use C language notation to define protocol message
-formats.  All structure elements are defined in terms
-of the <tt>unsigned char</tt> type, and are arranged
-so that an ISO C compiler lays them out in the obvious
-manner, with no padding.  The first byte defined in the
-structure is transmitted first, the second byte second, etc.<p>
-
-We use two conventions to abbreviate our definitions.<p>
-
-First, when two adjacent structure components are named identically
-except for the suffixes "<tt>B1</tt>" and "<tt>B0</tt>," it means that
-the two components may be viewed as a single number, computed as
-<tt>B1<<8 + B0</tt>.  The name of this single number is the name of
-the components, minus the suffixes.  This convention generalizes in an
-obvious way to handle numbers represented in more than two bytes.<p>
-
-Second, we extend C <tt>struct</tt>s to allow the form
-<pre>
-        struct {
-            unsigned char mumbleLengthB1;
-            unsigned char mumbleLengthB0;
-            ... /* other stuff */
-            unsigned char mumbleData[mumbleLength];
-        };
-</pre>
-meaning a structure of varying length, where the length of
-a component is determined by the values of the indicated
-earlier component or components.<p>
-
-
-<h4><a name = "S3.2">3.2 Accepting Transport Connections</a></h4>
-
-A FastCGI application calls <tt>accept()</tt> on the socket referred to
-by file descriptor <tt>FCGI_LISTENSOCK_FILENO</tt> to accept a new
-transport connection.
-
-If the <tt>accept()</tt> succeeds, and the <tt>FCGI_WEB_SERVER_ADDRS</tt>
-environment variable is bound, the application
-application immediately performs the following
-special processing:<p>
-
-<ul type=square>
-    <li><tt>FCGI_WEB_SERVER_ADDRS</tt>:
-
-        The value is a list of valid IP addresses for the Web server.<p>
-
-        If <tt>FCGI_WEB_SERVER_ADDRS</tt>
-        was bound, the application checks the peer
-        IP address of the new connection for membership in the list.
-        If the check fails (including the possibility that the
-        connection didn't use TCP/IP transport), the application
-        responds by closing the connection.<p>
-
-        <tt>FCGI_WEB_SERVER_ADDRS</tt>
-        is expressed as a comma-separated list of IP
-        addresses.  Each IP address is written as four decimal numbers
-        in the range [0..255] separated by decimal points.  So one
-        legal binding for this variable is
-        <tt>FCGI_WEB_SERVER_ADDRS=199.170.183.28,199.170.183.71</tt>.<p>
-</ul>
-
-An application may accept several concurrent transport
-connections, but it need not do so.<p>
-
-
-<h4><a name = "S3.3">3.3 Records</a></h4>
-
-Applications execute requests from a Web server using a simple
-protocol.  Details of the protocol depend upon the application's role,
-but roughly speaking the Web server first sends parameters and other
-data to the application, then the application sends result data to the
-Web server, and finally the application sends the Web server an
-indication that the request is complete.<p>
-
-All data that flows over the transport connection is carried in
-<i>FastCGI records</i>.  FastCGI records accomplish two
-things.  First, records multiplex the transport connection between
-several independent FastCGI requests.  This multiplexing supports
-applications that are able to process concurrent requests using
-event-driven or multi-threaded programming techniques.  Second,
-records provide several independent data streams in each direction
-within a single request.  This way, for instance, both <tt>stdout</tt>
-and <tt>stderr</tt> data can pass over a single transport connection
-from the application to the Web server, rather than requiring separate
-connections.<p>
-
-<pre>
-        typedef struct {
-            unsigned char version;
-            unsigned char type;
-            unsigned char requestIdB1;
-            unsigned char requestIdB0;
-            unsigned char contentLengthB1;
-            unsigned char contentLengthB0;
-            unsigned char paddingLength;
-            unsigned char reserved;
-            unsigned char contentData[contentLength];
-            unsigned char paddingData[paddingLength];
-        } FCGI_Record;
-</pre>
-
-A FastCGI record consists of a fixed-length prefix followed by a
-variable number of content and padding bytes.  A record contains seven
-components:<p>
-
-<ul type=square>
-    <li><tt>version</tt>:
-
-        Identifies the FastCGI protocol version.  This specification
-        documents <tt>FCGI_VERSION_1</tt>.<p>
-
-    <li><tt>type</tt>:
-
-        Identifies the FastCGI record type, i.e. the general function
-        that the record performs.  Specific record types and their
-        functions are detailed in later sections.<p>
-
-    <li><tt>requestId</tt>:
-
-        Identifies the <i>FastCGI request</i> to which the record
-        belongs.<p>
-
-    <li><tt>contentLength</tt>:
-
-        The number of bytes in the <tt>contentData</tt> component of the
-        record.<p>
-
-    <li><tt>paddingLength</tt>:
-
-        The number of bytes in the <tt>paddingData</tt> component of the
-        record.<p>
-
-    <li><tt>contentData</tt>:
-
-        Between 0 and 65535 bytes of data, interpreted
-        according to the record type.<p>
-
-    <li><tt>paddingData</tt>:
-
-        Between 0 and 255 bytes of data, which are ignored.<p>
-</ul>
-
-We use a relaxed C <tt>struct</tt> initializer syntax to specify
-constant FastCGI records.  We omit the <tt>version</tt> component,
-ignore padding, and treat
-<tt>requestId</tt> as a number.  Thus <tt>{FCGI_END_REQUEST, 1,
-{FCGI_REQUEST_COMPLETE,0}}</tt> is a record with <tt>type ==
-FCGI_END_REQUEST</tt>, <tt>requestId == 1</tt>, and <tt>contentData ==
-{FCGI_REQUEST_COMPLETE,0}</tt>.<p>
-
-
-<h5>Padding</h5>
-
-The protocol allows senders to pad the records they send, and requires
-receivers to interpret the <tt>paddingLength</tt> and skip the
-<tt>paddingData</tt>.  Padding allows senders to keep data aligned
-for more efficient processing.  Experience with the X window
-system protocols shows the performance benefit of such alignment.<p>
-
-We recommend that records be placed on boundaries that are multiples
-of eight bytes.  The fixed-length portion of a <tt>FCGI_Record</tt>
-is eight bytes.<p>
-
-
-<h5>Managing Request IDs</h5>
-
-The Web server re-uses FastCGI request IDs; the application keeps
-track of the current state of each request ID on a given transport
-connection.  A request ID <tt>R</tt> becomes active when the application
-receives a record <tt>{FCGI_BEGIN_REQUEST, R, ...}</tt> and
-becomes inactive when the application sends a record
-<tt>{FCGI_END_REQUEST, R, ...}</tt> to the Web server.<p>
-
-While a request ID <tt>R</tt> is inactive, the application ignores
-records with <tt>requestId == R</tt>, except for <tt>FCGI_BEGIN_REQUEST</tt>
-records as just described.<p>
-
-The Web server attempts to keep FastCGI request IDs small.  That way
-the application can keep track of request ID states using a short
-array rather than a long array or a hash table.  An application
-also has the option of accepting only one request at a time.
-In this case the application simply checks incoming <tt>requestId</tt>
-values against the current request ID.<p>
-
-
-<h5>Types of Record Types</h5>
-
-There are two useful ways of classifying FastCGI record types.<p>
-
-The first distinction is between <i>management</i> records and
-<i>application</i> records.  A management record contains information
-that is not specific to any Web server request, such as information
-about the protocol capabilities of the application.
-An application record contains information
-about a particular request, identified by the <tt>requestId</tt>
-component.<p>
-
-Management records have a <tt>requestId</tt> value of zero,
-also called the <i>null request ID</i>.  Application
-records have a nonzero <tt>requestId</tt>.<p>
-
-The second distinction is between <i>discrete</i> and <i>stream</i>
-records.  A discrete record contains a meaningful unit of data all by
-itself.  A stream record is part of a <i>stream</i>, i.e. a series of
-zero or more non-empty records (<tt>length != 0</tt>) of the stream
-type, followed by an empty record (<tt>length == 0</tt>) of the stream
-type.  The <tt>contentData</tt> components of a stream's records, when
-concatenated, form a byte sequence; this byte sequence is the value of
-the stream.  Therefore the value of a stream is independent of how
-many records it contains or how its bytes are divided among the
-non-empty records.<p>
-
-These two classifications are independent.  Among the
-record types defined in this version of the FastCGI protocol,
-all management record types are also discrete record types,
-and nearly all application record types are stream record types.
-But three application record types are discrete, and nothing
-prevents defining a management record type that's a stream
-in some later version of the protocol.<p>
-
-
-<h4><a name = "S3.4">3.4 Name-Value Pairs</a></h4>
-
-In many of their roles, FastCGI applications need to read and write
-varying numbers of variable-length values.  So it is useful to adopt a
-standard format for encoding a name-value pair.<p>
-
-FastCGI  transmits a name-value pair as the length of the name,
-followed by the length of the value, followed by the name,
-followed by the value.  Lengths of 127 bytes and less can be encoded
-in one byte, while longer lengths are always encoded in four bytes:<p>
-
-<pre>
-        typedef struct {
-            unsigned char nameLengthB0;  /* nameLengthB0  >> 7 == 0 */
-            unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */
-            unsigned char nameData[nameLength];
-            unsigned char valueData[valueLength];
-        } FCGI_NameValuePair11;
-
-        typedef struct {
-            unsigned char nameLengthB0;  /* nameLengthB0  >> 7 == 0 */
-            unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */
-            unsigned char valueLengthB2;
-            unsigned char valueLengthB1;
-            unsigned char valueLengthB0;
-            unsigned char nameData[nameLength];
-            unsigned char valueData[valueLength
-                    ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
-        } FCGI_NameValuePair14;
-
-        typedef struct {
-            unsigned char nameLengthB3;  /* nameLengthB3  >> 7 == 1 */
-            unsigned char nameLengthB2;
-            unsigned char nameLengthB1;
-            unsigned char nameLengthB0;
-            unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */
-            unsigned char nameData[nameLength
-                    ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
-            unsigned char valueData[valueLength];
-        } FCGI_NameValuePair41;
-
-        typedef struct {
-            unsigned char nameLengthB3;  /* nameLengthB3  >> 7 == 1 */
-            unsigned char nameLengthB2;
-            unsigned char nameLengthB1;
-            unsigned char nameLengthB0;
-            unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */
-            unsigned char valueLengthB2;
-            unsigned char valueLengthB1;
-            unsigned char valueLengthB0;
-            unsigned char nameData[nameLength
-                    ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
-            unsigned char valueData[valueLength
-                    ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
-        } FCGI_NameValuePair44;
-</pre>
-
-The high-order bit of the first byte of a length indicates the length's
-encoding.  A high-order zero implies a one-byte encoding, a one a four-byte
-encoding.<p>
-
-This name-value pair format allows the sender to transmit binary values
-without additional encoding, and enables the receiver to allocate the correct
-amount of storage immediately even for large values.<p>
-
-
-<h4><a name = "S3.5">3.5 Closing Transport Connections</a></h4>
-
-The Web server controls the lifetime of transport connections.
-The Web server can close a connection when no requests are active.
-Or the Web server can delegate close authority to the application
-(see <tt>FCGI_BEGIN_REQUEST</tt>).
-In this case the application closes the connection at the end of
-a specified request.<p>
-
-This flexibility accommodates a variety of application styles.
-Simple applications will process one request at a time and
-accept a new transport connection for each request.  More
-complex applications
-will process concurrent requests, over one or multiple transport
-connections, and will keep transport connections open for long
-periods of time.<p>
-
-A simple application gets a significant performance boost by
-closing the transport connection when it has finished writing its
-response.  The Web server needs to control the connection lifetime
-for long-lived connections.<p>
-
-When an application closes a connection or finds that a connection
-has closed, the application initiates a new connection.<p>
-
-
-
-<h3><a name = "S4">4. Management Record Types</a></h3>
-
-
-<h4><a name = "S4.1">4.1 <tt>FCGI_GET_VALUES, FCGI_GET_VALUES_RESULT</tt></a></h4>
-
-The Web server can query specific variables within the application.
-The server will typically perform a query on application startup
-in order to to automate certain aspects of system configuration.<p>
-
-The application receives a query as a record <tt>{FCGI_GET_VALUES, 0,
-...}</tt>.  The <tt>contentData</tt> portion of a <tt>FCGI_GET_VALUES</tt>
-record contains a sequence of name-value pairs with empty values.<p>
-
-The application responds by sending a record
-<tt>{FCGI_GET_VALUES_RESULT, 0, ...}</tt> with the values supplied.  If the
-application doesn't understand a variable name that was
-included in the query, it omits that name from the
-response.<p>
-
-<tt>FCGI_GET_VALUES</tt> is designed to allow an open-ended
-set of variables.  The initial set provides information to help
-the server perform application and connection management:<p>
-
-<ul type=square>
-    <li><tt>FCGI_MAX_CONNS</tt>:
-        The maximum number of concurrent transport connections this
-        application will accept, e.g.
-        <tt>"1"</tt> or <tt>"10"</tt>.<p>
-
-    <li><tt>FCGI_MAX_REQS</tt>:
-        The maximum number of concurrent requests this application
-        will accept, e.g.
-        <tt>"1"</tt> or <tt>"50"</tt>.<p>
-
-    <li><tt>FCGI_MPXS_CONNS</tt>:
-        <tt>"0"</tt> if this application does not multiplex
-        connections (i.e. handle concurrent requests over each
-        connection), <tt>"1"</tt> otherwise.<p>
-</ul>
-
-An application may receive a <tt>FCGI_GET_VALUES</tt> record at any
-time.  The application's response should not involve the application
-proper but only the FastCGI library.<p>
-
-
-<h4><a name = "S4.2">4.2 <tt>FCGI_UNKNOWN_TYPE</tt></a></h4>
-
-The set of management record types is likely to grow in future versions
-of this protocol.  To provide for this evolution, the protocol
-includes the <tt>FCGI_UNKNOWN_TYPE</tt> management record.
-When an application receives a management record whose type <tt>T</tt>
-it does not understand, the application responds with
-<tt>{FCGI_UNKNOWN_TYPE, 0, {T}}</tt>.<p>
-
-The <tt>contentData</tt> component of a <tt>FCGI_UNKNOWN_TYPE</tt> record
-has the form:
-<pre>
-        typedef struct {
-            unsigned char type;    
-            unsigned char reserved[7];
-        } FCGI_UnknownTypeBody;
-</pre>
-<p>
-
-The <tt>type</tt> component is the type of the unrecognized management
-record.<p>
-
-
-
-<h3><a name = "S5">5. Application Record Types</a></h3>
-
-
-<h4><a name = "S5.1">5.1 <tt>FCGI_BEGIN_REQUEST</tt></a></h4>
-
-The Web server sends a <tt>FCGI_BEGIN_REQUEST</tt> record
-to start a request.<p>
-
-The <tt>contentData</tt> component of a <tt>FCGI_BEGIN_REQUEST</tt> record
-has the form:
-<pre>
-        typedef struct {
-            unsigned char roleB1;
-            unsigned char roleB0;
-            unsigned char flags;
-            unsigned char reserved[5];
-        } FCGI_BeginRequestBody;
-</pre>
-<p>
-
-The <tt>role</tt> component sets the role the Web server expects
-the application to play.  The currently-defined roles are:<p>
-
-<ul type=square>
-    <li><tt>FCGI_RESPONDER</tt>
-    <li><tt>FCGI_AUTHORIZER</tt>
-    <li><tt>FCGI_FILTER</tt>
-</ul>
-
-Roles are described in more detail in
-<a href = "#S6">Section 6</a> below.<p>
-
-The <tt>flags</tt> component contains a bit that
-controls connection shutdown:<p>
-
-<ul type=square>
-    <li><tt>flags & FCGI_KEEP_CONN</tt>:
-        If zero, the application closes the connection after responding to
-        this request.  If not zero, the application does not close
-        the connection after responding to this request; the Web server
-        retains responsibility for the connection.<p>
-</ul>
-
-
-<h4><a name = "S5.2">5.2 Name-Value Pair Stream: <tt>FCGI_PARAMS</tt></a></h4>
-
-<tt>FCGI_PARAMS</tt> is a stream record type used in sending
-name-value pairs from the Web server to the application.
-The name-value pairs are sent down the stream one after the other,
-in no specified order.<p>
-
-
-<h4><a name = "S5.3">5.3 Byte Streams: <tt>FCGI_STDIN</tt>, <tt>FCGI_DATA</tt>, <tt>FCGI_STDOUT</tt>, <tt>FCGI_STDERR</tt></a></h4>
-
-<tt>FCGI_STDIN</tt> is a stream record type used in sending arbitrary
-data from the Web server to the application.  <tt>FCGI_DATA</tt>
-is a second stream record type used to send additional
-data to the application.<p>
-
-<tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt> are stream record types
-for sending arbitrary data and error data respectively from the
-application to the Web server.<p>
-
-
-<h4><a name = "S5.4">5.4 <tt>FCGI_ABORT_REQUEST</tt></a></h4>
-
-The Web server sends a <tt>FCGI_ABORT_REQUEST</tt> record to
-abort a request.  After receiving <tt>{FCGI_ABORT_REQUEST, R}</tt>,
-the application responds as soon as possible with
-<tt>{FCGI_END_REQUEST, R, {FCGI_REQUEST_COMPLETE, appStatus}}</tt>.
-This is truly a response from the application, not a low-level
-acknowledgement from the FastCGI library.<p>
-
-A Web server aborts a FastCGI request when an HTTP client closes its
-transport connection while the FastCGI request is running on behalf of
-that client.  The situation may seem unlikely; most FastCGI
-requests will have short response times, with the Web server providing
-output buffering if the client is slow.  But the FastCGI application
-may be delayed communicating with another system, or performing a
-server push.<p>
-
-When a Web server is not multiplexing requests over a transport
-connection, the Web server can abort a request by closing the request's
-transport connection.  But with multiplexed requests, closing the
-transport connection has the unfortunate effect of aborting <i>all</i>
-the requests on the connection.<p>
-
-
-<h4><a name = "S5.5">5.5 <tt>FCGI_END_REQUEST</tt></a></h4>
-
-The application sends a <tt>FCGI_END_REQUEST</tt> record
-to terminate a request, either because the application
-has processed the request or because the application has rejected
-the request.<p>
-
-The <tt>contentData</tt> component of a <tt>FCGI_END_REQUEST</tt> record
-has the form:
-<pre>
-        typedef struct {
-            unsigned char appStatusB3;
-            unsigned char appStatusB2;
-            unsigned char appStatusB1;
-            unsigned char appStatusB0;
-            unsigned char protocolStatus;
-            unsigned char reserved[3];
-        } FCGI_EndRequestBody;
-</pre>
-<p>
-
-The <tt>appStatus</tt> component is an application-level status code.
-Each role documents its usage of <tt>appStatus</tt>.<p>
-
-The <tt>protocolStatus</tt> component is a protocol-level status code;
-the possible <tt>protocolStatus</tt> values are:<p>
-
-<ul type=square>
-    <li><tt>FCGI_REQUEST_COMPLETE</tt>:
-        normal end of request.<p>
-
-    <li><tt>FCGI_CANT_MPX_CONN</tt>:
-        rejecting a new request.  This happens when a Web server sends
-        concurrent requests over one connection to an application that
-        is designed to process one request at a time per
-        connection.<p>
-
-    <li><tt>FCGI_OVERLOADED</tt>:
-        rejecting a new request.  This happens when the application
-        runs out of some resource, e.g. database connections.<p>
-
-    <li><tt>FCGI_UNKNOWN_ROLE</tt>:
-        rejecting a new request.  This happens when the Web server
-        has specified a role that is unknown to the application.<p>
-</ul>
-
-
-
-<h3><a name = "S6">6. Roles</a></h3>
-
-
-<h4><a name = "S6.1">6.1 Role Protocols</a></h4>
-
-Role protocols only include records with application record
-types.  They transfer essentially all data using streams.<p>
-
-To make the protocols reliable and to simplify application
-programming, role protocols are designed to use <i>nearly sequential
-marshalling</i>.  In a protocol with strictly sequential marshalling,
-the application receives its first input, then its second, etc. until
-it has received them all.  Similarly, the application sends its first
-output, then its second, etc. until it has sent them all.  Inputs are
-not interleaved with each other, and outputs are not interleaved with
-each other.<p>
-
-The sequential marshalling rule is too restrictive for some
-FastCGI roles, because CGI programs can write to both <tt>stdout</tt>
-and <tt>stderr</tt> without timing restrictions.  So role
-protocols that use both <tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt>
-allow these two streams to be interleaved.<p>
-
-All role protocols use the <tt>FCGI_STDERR</tt> stream just the way
-<tt>stderr</tt> is used in conventional applications programming: to
-report application-level errors in an intelligible way.  Use of the
-<tt>FCGI_STDERR</tt> stream is always optional.  If an application has
-no errors to report, it sends either no <tt>FCGI_STDERR</tt> records or
-one zero-length <tt>FCGI_STDERR</tt> record.<p>
-
-When a role protocol calls for transmitting a stream other than
-<tt>FCGI_STDERR</tt>, at least one record of the stream type is always
-transmitted, even if the stream is empty.<p>
-
-Again in the interests of reliable protocols and simplified application
-programming, role protocols are designed to be <i>nearly
-request-response</i>.  In a truly request-response protocol, the
-application receives all of its input records before sending its first
-output record.  Request-response protocols don't allow pipelining.<p>
-
-The request-response rule is too restrictive for some FastCGI roles;
-after all, CGI programs aren't restricted to read all of
-<tt>stdin</tt> before starting to write <tt>stdout</tt>.  So some role
-protocols allow that specific possibility.  First the application
-receives all of its inputs except for a final stream input.  As the
-application begins to receive the final stream input, it can
-begin writing its output.<p>
-
-When a role protocol uses <tt>FCGI_PARAMS</tt> to transmit textual
-values, such as the values that CGI programs obtain from environment
-variables, the length of the value does not include the terminating
-null byte, and the value itself does not include a null byte.  An
-application that needs to provide <tt>environ(7)</tt> format
-name-value pairs must insert an equal sign between the name and value
-and append a null byte after the value.<p>
-
-Role protocols do not support the non-parsed header feature
-of CGI.  FastCGI applications set response status using
-the <tt>Status</tt> and <tt>Location</tt> CGI headers.<p>
-
-
-<h4><a name = "S6.2">6.2 Responder</a></h4>
-
-A Responder FastCGI application has the same purpose as a CGI/1.1 program:
-It receives all the information associated with an HTTP request and
-generates an HTTP response.<p>
-
-It suffices to explain how each element of CGI/1.1 is emulated by a
-Responder:<p>
-<ul type=square>
-    <li>
-        The Responder application receives CGI/1.1 environment variables from
-        the Web server over <tt>FCGI_PARAMS</tt>.<p>
-    <li>
-        Next the Responder application receives CGI/1.1
-        <tt>stdin</tt> data from
-        the Web server over <tt>FCGI_STDIN</tt>.  The application receives
-        at most <tt>CONTENT_LENGTH</tt> bytes from this stream before
-        receiving the end-of-stream indication.  (The application
-        receives less than <tt>CONTENT_LENGTH</tt> bytes only if the
-        HTTP client fails to provide them, e.g. because the client
-        crashed.)<p>
-    <li>
-        The Responder application sends CGI/1.1
-        <tt>stdout</tt> data to the Web
-        server over <tt>FCGI_STDOUT</tt>, and CGI/1.1 <tt>stderr</tt> data
-        over <tt>FCGI_STDERR</tt>.  The application sends these
-        concurrently, not one after the other.  The application must
-        wait to finish reading <tt>FCGI_PARAMS</tt> before it begins
-        writing <tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt>, but
-        it needn't finish reading from <tt>FCGI_STDIN</tt> before it
-        begins writing these two streams.<p>
-    <li>
-        After sending all its <tt>stdout</tt> and <tt>stderr</tt> data,
-        the Responder application sends a <tt>FCGI_END_REQUEST</tt> record.
-        The application sets the <tt>protocolStatus</tt> component to
-        <tt>FCGI_REQUEST_COMPLETE</tt> and the <tt>appStatus</tt> component
-        to the status code that the CGI program would have returned
-        via the <tt>exit</tt> system call.<p>
-</ul>
-
-A Responder performing an update, e.g. implementing a <tt>POST</tt>
-method, should compare the number of bytes received on <tt>FCGI_STDIN</tt>
-with <tt>CONTENT_LENGTH</tt> and abort the update if the two numbers
-are not equal.<p>
-
-
-<h4><a name = "S6.3">6.3 Authorizer</a></h4>
-
-An Authorizer FastCGI application receives all the information
-associated with an HTTP request and generates an
-authorized/unauthorized decision.  In case of an authorized
-decision the Authorizer can also associate name-value pairs
-with the HTTP request; when giving an unauthorized
-decision the Authorizer sends a complete response to the HTTP client.
-<p>
-
-Since CGI/1.1 defines a perfectly good way to represent the information
-associated with an HTTP request, Authorizers use the same
-representation:<p>
-
-<ul type=square>
-    <li>
-        The Authorizer application receives
-        HTTP request information from the Web
-        server on the <tt>FCGI_PARAMS</tt> stream,
-        in the same format as a Responder.  The Web server does not
-        send <tt>CONTENT_LENGTH</tt>,
-        <tt>PATH_INFO</tt>, <tt>PATH_TRANSLATED</tt>, and
-        <tt>SCRIPT_NAME</tt> headers.<p>
-    <li>
-       The Authorizer application sends
-        <tt>stdout</tt> and <tt>stderr</tt> data in
-       the same manner as a Responder.  The CGI/1.1 response
-       status specifies the disposition of the request.  If the
-        application sends status 200 (OK), the Web server allows
-        access.  Depending upon its configuration the Web server
-        may proceed with other access checks, including requests to other
-        Authorizers.<p>
-
-        An Authorizer application's 200 response may include headers
-        whose names are prefixed with <tt>Variable-</tt>.  These
-        headers communicate name-value pairs from the
-        application to the Web server.  For instance, the response header
-<pre>
-        Variable-AUTH_METHOD: database lookup
-</pre>
-        transmits the value <tt>"database lookup"</tt> with name
-        <tt>AUTH-METHOD</tt>.  The server associates such name-value
-        pairs with the HTTP request and includes them in subsequent
-        CGI or FastCGI requests performed in processing the HTTP
-        request.  When the application gives a 200 response, the
-        server ignores response headers whose names aren't prefixed
-        with <tt>Variable-</tt> prefix, and ignores any response
-        content.<p>
-
-       For Authorizer response status values other than "200" (OK), the
-        Web server denies access and sends
-       the response status, headers, and content
-        back to the HTTP client.<p>
-</ul>
-
-
-<h4><a name = "S6.4">6.4 Filter</a></h4>
-
-A Filter FastCGI application receives all the information associated
-with an HTTP request, plus an extra stream of data from a file stored
-on the Web server, and generates a "filtered" version of the data
-stream as an HTTP response.<p>
-
-A Filter is similar in functionality to a Responder that takes a data
-file as a parameter.  The difference is that with a Filter, both the
-data file and the Filter itself can be access controlled using the Web
-server's access control mechanisms, while a Responder that takes the
-name of a data file as a parameter must perform its own access control
-checks on the data file.<p>
-
-The steps taken by a Filter are similar to those of a Responder.
-The server presents the Filter with environment variables first,
-then standard input (normally form <tt>POST</tt> data), finally
-the data file input:<p>
-<ul type=square>
-    <li>
-        Like a Responder, the Filter application receives name-value
-        pairs from the Web server over <tt>FCGI_PARAMS</tt>.
-        Filter applications receive two Filter-specific variables:
-        <tt>FCGI_DATA_LAST_MOD</tt> and <tt>FCGI_DATA_LENGTH</tt>.<p>
-    <li>
-        Next the Filter application receives CGI/1.1 <tt>stdin</tt> data from
-        the Web server over <tt>FCGI_STDIN</tt>.  The application receives
-        at most <tt>CONTENT_LENGTH</tt> bytes from this stream before
-        receiving the end-of-stream indication.  (The application
-        receives less than <tt>CONTENT_LENGTH</tt> bytes only if the
-        HTTP client fails to provide them, e.g. because the client
-        crashed.)<p>
-    <li>
-        Next the Filter application receives the file data from the
-        Web server over <tt>FCGI_DATA</tt>.  This file's last
-        modification time (expressed as an integer number of seconds
-        since the epoch January 1, 1970 UTC) is
-        <tt>FCGI_DATA_LAST_MOD</tt>; the application may consult
-        this variable and respond from a cache without reading
-        the file data.  The application
-        reads at most <tt>FCGI_DATA_LENGTH</tt> bytes from this stream
-        before receiving the end-of-stream indication.<p>
-    <li>
-        The Filter application sends CGI/1.1 <tt>stdout</tt> data to the Web
-        server over <tt>FCGI_STDOUT</tt>, and CGI/1.1 <tt>stderr</tt> data
-        over <tt>FCGI_STDERR</tt>.  The application sends these
-        concurrently, not one after the other.  The application must
-        wait to finish reading <tt>FCGI_STDIN</tt> before it begins
-        writing <tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt>, but
-        it needn't finish reading from <tt>FCGI_DATA</tt> before it
-        begins writing these two streams.<p>
-    <li>
-        After sending all its <tt>stdout</tt> and <tt>stderr</tt> data,
-        the application sends a <tt>FCGI_END_REQUEST</tt> record.
-        The application sets the <tt>protocolStatus</tt> component to
-        <tt>FCGI_REQUEST_COMPLETE</tt> and the <tt>appStatus</tt> component
-        to the status code that a similar CGI program would have returned
-        via the <tt>exit</tt> system call.<p>
-</ul>
-
-A Filter should compare the number of bytes received on <tt>FCGI_STDIN</tt>
-with <tt>CONTENT_LENGTH</tt> and on <tt>FCGI_DATA</tt>
-with <tt>FCGI_DATA_LENGTH</tt>.  If the numbers don't match
-and the Filter is a query, the Filter
-response should provide an indication that data is missing.
-If the numbers don't match and the Filter is an update, the Filter
-should abort the update.<p>
-
-
-
-<h3><a name = "S7">7. Errors</a></h3>
-
-A FastCGI application exits with zero status to indicate that it
-terminated on purpose, e.g. in order to perform a crude form of
-garbage collection.  A FastCGI application that exits with nonzero
-status is assumed to have crashed.  How a Web server or other
-application manager responds to
-applications that exit with zero or nonzero status is outside the
-scope of this specification.<p>
-
-A Web server can request that a FastCGI application exit by sending it
-<tt>SIGTERM</tt>.  If the application ignores <tt>SIGTERM</tt> the Web
-server can resort to <tt>SIGKILL</tt>.<p>
-
-FastCGI applications report application-level errors with the
-<tt>FCGI_STDERR</tt> stream and the <tt>appStatus</tt> component of
-the <tt>FCGI_END_REQUEST</tt> record.  In many cases an error will be
-reported directly to the user via the <tt>FCGI_STDOUT</tt> stream.<p>
-
-On Unix, applications report lower-level errors, including
-FastCGI protocol errors and syntax errors in FastCGI environment
-variables, to <tt>syslog</tt>.  Depending upon the severity
-of the error, the application may either continue or
-exit with nonzero status.<p>
-
-
-
-<h3><a name = "S8">8. Types and Constants</a></h3>
-<pre>
-/*
- * Listening socket file number
- */
-#define FCGI_LISTENSOCK_FILENO 0
-
-typedef struct {
-    unsigned char version;
-    unsigned char type;
-    unsigned char requestIdB1;
-    unsigned char requestIdB0;
-    unsigned char contentLengthB1;
-    unsigned char contentLengthB0;
-    unsigned char paddingLength;
-    unsigned char reserved;
-} FCGI_Header;
-
-/*
- * Number of bytes in a FCGI_Header.  Future versions of the protocol
- * will not reduce this number.
- */
-#define FCGI_HEADER_LEN  8
-
-/*
- * Value for version component of FCGI_Header
- */
-#define FCGI_VERSION_1           1
-
-/*
- * Values for type component of FCGI_Header
- */
-#define FCGI_BEGIN_REQUEST       1
-#define FCGI_ABORT_REQUEST       2
-#define FCGI_END_REQUEST         3
-#define FCGI_PARAMS              4
-#define FCGI_STDIN               5
-#define FCGI_STDOUT              6
-#define FCGI_STDERR              7
-#define FCGI_DATA                8
-#define FCGI_GET_VALUES          9
-#define FCGI_GET_VALUES_RESULT  10
-#define FCGI_UNKNOWN_TYPE       11
-#define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE)
-
-/*
- * Value for requestId component of FCGI_Header
- */
-#define FCGI_NULL_REQUEST_ID     0
-
-typedef struct {
-    unsigned char roleB1;
-    unsigned char roleB0;
-    unsigned char flags;
-    unsigned char reserved[5];
-} FCGI_BeginRequestBody;
-
-typedef struct {
-    FCGI_Header header;
-    FCGI_BeginRequestBody body;
-} FCGI_BeginRequestRecord;
-
-/*
- * Mask for flags component of FCGI_BeginRequestBody
- */
-#define FCGI_KEEP_CONN  1
-
-/*
- * Values for role component of FCGI_BeginRequestBody
- */
-#define FCGI_RESPONDER  1
-#define FCGI_AUTHORIZER 2
-#define FCGI_FILTER     3
-
-typedef struct {
-    unsigned char appStatusB3;
-    unsigned char appStatusB2;
-    unsigned char appStatusB1;
-    unsigned char appStatusB0;
-    unsigned char protocolStatus;
-    unsigned char reserved[3];
-} FCGI_EndRequestBody;
-
-typedef struct {
-    FCGI_Header header;
-    FCGI_EndRequestBody body;
-} FCGI_EndRequestRecord;
-
-/*
- * Values for protocolStatus component of FCGI_EndRequestBody
- */
-#define FCGI_REQUEST_COMPLETE 0
-#define FCGI_CANT_MPX_CONN    1
-#define FCGI_OVERLOADED       2
-#define FCGI_UNKNOWN_ROLE     3
-
-/*
- * Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT records
- */
-#define FCGI_MAX_CONNS  "FCGI_MAX_CONNS"
-#define FCGI_MAX_REQS   "FCGI_MAX_REQS"
-#define FCGI_MPXS_CONNS "FCGI_MPXS_CONNS"
-
-typedef struct {
-    unsigned char type;    
-    unsigned char reserved[7];
-} FCGI_UnknownTypeBody;
-
-typedef struct {
-    FCGI_Header header;
-    FCGI_UnknownTypeBody body;
-} FCGI_UnknownTypeRecord;
-</pre>
-<p>
-
-
-
-<h3><a name = "S9">9. References</a></h3>
-
-
-National Center for Supercomputer Applications,
-<a href = "http://hoohoo.ncsa.uiuc.edu/cgi/">The Common Gateway Interface</a>,
-version CGI/1.1.<p>
-
-D.R.T. Robinson,
-<a href = "http://ds.internic.net/internet-drafts/draft-robinson-www-interface-01.txt">The WWW Common Gateway Interface Version 1.1</a>, Internet-Draft, 15 February 1996.<p>
-
-
-
-<h3><a name = "SA">A. Table: Properties of the record types</a></h3>
-
-The following chart lists all of the record types and
-indicates these properties of each:<p>
-
-<ul type=square>
-    <li><tt>WS->App</tt>:
-        records of this type can only be sent by the Web server to the
-        application.  Records of other types can only be sent by the
-        application to the Web server.<p>
-    <li><tt>management</tt>:
-        records of this type contain information that is not specific
-        to a Web server request, and use the null request ID.  Records
-        of other types contain request-specific information, and cannot
-        use the null request ID.<p>
-    <li><tt>stream</tt>:
-        records of this type form a stream, terminated by a
-        record with empty <tt>contentData</tt>.  Records of other types
-        are discrete; each carries a meaningful unit of data.<p>
-</ul>
-<pre>
-
-                               WS->App   management  stream
-
-        FCGI_GET_VALUES           x          x
-        FCGI_GET_VALUES_RESULT               x
-        FCGI_UNKNOWN_TYPE                    x
-
-        FCGI_BEGIN_REQUEST        x
-        FCGI_ABORT_REQUEST        x
-        FCGI_END_REQUEST
-        FCGI_PARAMS               x                    x
-        FCGI_STDIN                x                    x
-        FCGI_DATA                 x                    x
-        FCGI_STDOUT                                    x 
-        FCGI_STDERR                                    x     
-
-
-</pre>
-<p>
-
-
-
-<h3><a name = "SB">B. Typical Protocol Message Flow</a></h3>
-
-Additional notational conventions for the examples:
-
-<ul>
-    <li>The <tt>contentData</tt> of stream records (<tt>FCGI_PARAMS</tt>,
-        <tt>FCGI_STDIN</tt>, <tt>FCGI_STDOUT</tt>, and <tt>FCGI_STDERR</tt>)
-        is represented as a character string.  A string ending in
-        <tt>" ... "</tt> is too long to display, so only a prefix is shown.
-
-    <li>Messages sent to the Web server are indented
-        with respect to messages received from the Web server.
-
-    <li>Messages are shown in the time sequence experienced
-        by the application.
-</ul>
-
-1. A simple request with no data on <tt>stdin</tt>, and a successful response:
-<pre>
-{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, 0}}
-{FCGI_PARAMS,          1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
-{FCGI_PARAMS,          1, ""}
-{FCGI_STDIN,           1, ""}
-
-    {FCGI_STDOUT,      1, "Content-type: text/html\r\n\r\n&lt;html&gt;\n&lt;head&gt; ... "}
-    {FCGI_STDOUT,      1, ""}
-    {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
-</pre><p>
-
-2. Similar to example 1, but this time with data on <tt>stdin</tt>.
-The Web server chooses to send the
-parameters using more <tt>FCGI_PARAMS</tt> records than before:
-<pre>
-{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, 0}}
-{FCGI_PARAMS,          1, "\013\002SERVER_PORT80\013\016SER"}
-{FCGI_PARAMS,          1, "VER_ADDR199.170.183.42 ... "}
-{FCGI_PARAMS,          1, ""}
-{FCGI_STDIN,           1, "quantity=100&amp;item=3047936"}
-{FCGI_STDIN,           1, ""}
-
-    {FCGI_STDOUT,      1, "Content-type: text/html\r\n\r\n&lt;html&gt;\n&lt;head&gt; ... "}
-    {FCGI_STDOUT,      1, ""}
-    {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
-</pre><p>
-
-3. Similar to example 1, but this time the application detects an error.
-The application logs a message to
-<tt>stderr</tt>, returns a page to the client, and returns
-non-zero exit status to the Web server.  The application
-chooses to send the page using more <tt>FCGI_STDOUT</tt> records:
-<pre>
-{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, 0}}
-{FCGI_PARAMS,          1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
-{FCGI_PARAMS,          1, ""}
-{FCGI_STDIN,           1, ""}
-
-    {FCGI_STDOUT,      1, "Content-type: text/html\r\n\r\n&lt;ht"}
-    {FCGI_STDERR,      1, "config error: missing SI_UID\n"}
-    {FCGI_STDOUT,      1, "ml&gt;\n&lt;head&gt; ... "}
-    {FCGI_STDOUT,      1, ""}
-    {FCGI_STDERR,      1, ""}
-    {FCGI_END_REQUEST, 1, {938, FCGI_REQUEST_COMPLETE}}
-</pre><p>
-
-4. Two instances of example 1, multiplexed onto a single connection.
-The first request is more difficult than the second, so the
-application finishes the requests out of order:
-<pre>
-{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
-{FCGI_PARAMS,          1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
-{FCGI_PARAMS,          1, ""}
-{FCGI_BEGIN_REQUEST,   2, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
-{FCGI_PARAMS,          2, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
-{FCGI_STDIN,           1, ""}
-
-    {FCGI_STDOUT,      1, "Content-type: text/html\r\n\r\n"}
-
-{FCGI_PARAMS,          2, ""}
-{FCGI_STDIN,           2, ""}
-
-    {FCGI_STDOUT,      2, "Content-type: text/html\r\n\r\n&lt;html&gt;\n&lt;head&gt; ... "}
-    {FCGI_STDOUT,      2, ""}
-    {FCGI_END_REQUEST, 2, {0, FCGI_REQUEST_COMPLETE}}
-    {FCGI_STDOUT,      1, "&lt;html&gt;\n&lt;head&gt; ... "}
-    {FCGI_STDOUT,      1, ""}
-    {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
-</pre><p>
-
-<hr>
-
-<address>
-&#169 1995, 1996 Open Market, Inc. / mbrown@openmarket.com
-</address>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
+<HTML>\r
+   <!--Copyright (c) 1996 Open Market, Inc.                                    -->\r
+   <!--See the file "LICENSE.TERMS" for information on usage and redistribution-->\r
+   <!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->\r
+   <HEAD>\r
+      <TITLE>\r
+         FastCGI Specification\r
+      </TITLE>\r
+<STYLE TYPE="text/css">\r
+ h5.c2 {text-align: center}\r
+ div.c1 {text-align: center}\r
+</STYLE>\r
+   </HEAD>\r
+   <BODY>\r
+      <DIV CLASS="c1">\r
+         <H2>\r
+            FastCGI Specification\r
+         </H2>\r
+      </DIV>\r
+      <DIV CLASS="c1">\r
+         Mark R. Brown<BR>\r
+         Open Market, Inc.<BR>\r
+         <P>\r
+            Document Version: 1.0<BR>\r
+            29 April 1996<BR>\r
+         </P>\r
+      </DIV>\r
+      <P>\r
+      </P>\r
+      <H5 CLASS="c2">\r
+         Copyright &copy; 1996 Open Market, Inc. 245 First Street, Cambridge, MA 02142 U.S.A.<BR>\r
+         Tel: 617-621-9500 Fax: 617-621-1703 URL: <A HREF=\r
+         "http://www.openmarket.com/">http://www.openmarket.com/</A><BR>\r
+         <BR>\r
+         $Id: fcgi-spec.html,v 1.3 2001/11/27 01:03:47 robs Exp $\r
+      </H5>\r
+      <HR>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            <A HREF="#S1">1. Introduction</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S2">2. Initial Process State</A> \r
+            <UL TYPE="square">\r
+               <LI>\r
+                  <A HREF="#S2.1">2.1 Argument list</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S2.2">2.2 File descriptors</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S2.3">2.3 Environment variables</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S2.4">2.4 Other state</A>\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S3">3. Protocol Basics</A> \r
+            <UL TYPE="square">\r
+               <LI>\r
+                  <A HREF="#S3.1">3.1 Notation</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S3.2">3.2 Accepting Transport Connections</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S3.3">3.3 Records</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S3.4">3.4 Name-Value Pairs</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S3.5">3.5 Closing Transport Connections</A>\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S4">4. Management Record Types</A> \r
+            <UL TYPE="square">\r
+               <LI>\r
+                  <A HREF="#S4.1">4.1 <TT>FCGI_GET_VALUES, FCGI_GET_VALUES_RESULT</TT></A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S4.2">4.2 <TT>FCGI_UNKNOWN_TYPE</TT></A>\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S5">5. Application Record Types</A> \r
+            <UL TYPE="square">\r
+               <LI>\r
+                  <A HREF="#S5.1">5.1 <TT>FCGI_BEGIN_REQUEST</TT></A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S5.2">5.2 Name-Value Pair Streams: <TT>FCGI_PARAMS</TT>, <TT>FCGI_RESULTS</TT></A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S5.3">5.3 Byte Streams: <TT>FCGI_STDIN</TT>, <TT>FCGI_DATA</TT>, <TT>FCGI_STDOUT</TT>,\r
+                  <TT>FCGI_STDERR</TT></A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S5.4">5.4 <TT>FCGI_ABORT_REQUEST</TT></A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S5.5">5.5 <TT>FCGI_END_REQUEST</TT></A>\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S6">6. Roles</A> \r
+            <UL TYPE="square">\r
+               <LI>\r
+                  <A HREF="#S6.1">6.1 Role Protocols</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S6.2">6.2 Responder</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S6.3">6.3 Authorizer</A>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="#S6.4">6.4 Filter</A>\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S7">7. Errors</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S8">8. Types and Constants</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#S9">9. References</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#SA">A. Table: Properties of the record types</A>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="#SB">B. Typical Protocol Message Flow</A>\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+      </P>\r
+      <HR>\r
+      <H3>\r
+         <A NAME="S1">1. Introduction</A>\r
+      </H3>\r
+      <P>\r
+         FastCGI is an open extension to CGI that provides high performance for all Internet applications without the\r
+         penalties of Web server APIs.\r
+      </P>\r
+      <P>\r
+         This specification has narrow goal: to specify, from an application perspective, the interface between a\r
+         FastCGI application and a Web server that supports FastCGI. Many Web server features related to FastCGI, e.g.\r
+         application management facilities, have nothing to do with the application to Web server interface, and are\r
+         not described here.\r
+      </P>\r
+      <P>\r
+         This specification is for Unix (more precisely, for POSIX systems that support Berkeley Sockets). The bulk of\r
+         the specification is a simple communications protocol that is independent of byte ordering and will extend to\r
+         other systems.\r
+      </P>\r
+      <P>\r
+         We&#39;ll introduce FastCGI by comparing it with conventional Unix implementations of CGI/1.1. FastCGI is\r
+         designed to support long-lived application processes, i.e. <I>application servers</I>. That&#39;s a major\r
+         difference compared with conventional Unix implementations of CGI/1.1, which construct an application process,\r
+         use it respond to one request, and have it exit.\r
+      </P>\r
+      <P>\r
+         The initial state of a FastCGI process is more spartan than the initial state of a CGI/1.1 process, because\r
+         the FastCGI process doesn&#39;t begin life connected to anything. It doesn&#39;t have the conventional open\r
+         files <TT>stdin</TT>, <TT>stdout</TT>, and <TT>stderr</TT>, and it doesn&#39;t receive much information\r
+         through environment variables. The key piece of initial state in a FastCGI process is a listening socket,\r
+         through which it accepts connections from a Web server.\r
+      </P>\r
+      <P>\r
+         After a FastCGI process accepts a connection on its listening socket, the process executes a simple protocol\r
+         to receive and send data. The protocol serves two purposes. First, the protocol multiplexes a single transport\r
+         connection between several independent FastCGI requests. This supports applications that are able to process\r
+         concurrent requests using event-driven or multi-threaded programming techniques. Second, within each request\r
+         the protocol provides several independent data streams in each direction. This way, for instance, both\r
+         <TT>stdout</TT> and <TT>stderr</TT> data pass over a single transport connection from the application to the\r
+         Web server, rather than requiring separate pipes as with CGI/1.1.\r
+      </P>\r
+      <P>\r
+         A FastCGI application plays one of several well-defined <I>roles</I>. The most familiar is the\r
+         <I>Responder</I> role, in which the application receives all the information associated with an HTTP request\r
+         and generates an HTTP response; that&#39;s the role CGI/1.1 programs play. A second role is <I>Authorizer</I>,\r
+         in which the application receives all the information associated with an HTTP request and generates an\r
+         authorized/unauthorized decision. A third role is <I>Filter</I>, in which the application receives all the\r
+         information associated with an HTTP request, plus an extra stream of data from a file stored on the Web\r
+         server, and generates a &quot;filtered&quot; version of the data stream as an HTTP response. The framework is\r
+         extensible so that more FastCGI can be defined later.\r
+      </P>\r
+      <P>\r
+         In the remainder of this specification the terms &quot;FastCGI application,&quot; &quot;application\r
+         process,&quot; or &quot;application server&quot; are abbreviated to &quot;application&quot; whenever that\r
+         won&#39;t cause confusion.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S2">2. Initial Process State</A>\r
+      </H3>\r
+      <H4>\r
+         <A NAME="S2.1">2.1 Argument list</A>\r
+      </H4>\r
+      <P>\r
+         By default the Web server creates an argument list containing a single element, the name of the application,\r
+         taken to be the last component of the executable&#39;s path name. The Web server may provide a way to specify\r
+         a different application name, or a more elaborate argument list.\r
+      </P>\r
+      <P>\r
+         Note that the file executed by the Web server might be an interpreter file (a text file that starts with the\r
+         characters <TT>#!</TT>), in which case the application&#39;s argument list is constructed as described in the\r
+         <TT>execve</TT> manpage.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S2.2">2.2 File descriptors</A>\r
+      </H4>\r
+      <P>\r
+         The Web server leaves a single file descriptor, <TT>FCGI_LISTENSOCK_FILENO</TT>, open when the application\r
+         begins execution. This descriptor refers to a listening socket created by the Web server.\r
+      </P>\r
+      <P>\r
+         <TT>FCGI_LISTENSOCK_FILENO</TT> equals <TT>STDIN_FILENO</TT>. The standard descriptors <TT>STDOUT_FILENO</TT>\r
+         and <TT>STDERR_FILENO</TT> are closed when the application begins execution. A reliable method for an\r
+         application to determine whether it was invoked using CGI or FastCGI is to call\r
+         <TT>getpeername(FCGI_LISTENSOCK_FILENO)</TT>, which returns -1 with <TT>errno</TT> set to <TT>ENOTCONN</TT>\r
+         for a FastCGI application.\r
+      </P>\r
+      <P>\r
+         The Web server&#39;s choice of reliable transport, Unix stream pipes (<TT>AF_UNIX</TT>) or TCP/IP\r
+         (<TT>AF_INET</TT>), is implicit in the internal state of the <TT>FCGI_LISTENSOCK_FILENO</TT> socket.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S2.3">2.3 Environment variables</A>\r
+      </H4>\r
+      <P>\r
+         The Web server may use environment variables to pass parameters to the application. This specification defines\r
+         one such variable, <TT>FCGI_WEB_SERVER_ADDRS</TT>; we expect more to be defined as the specification evolves.\r
+         The Web server may provide a way to bind other environment variables, such as the <TT>PATH</TT> variable.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S2.4">2.4 Other state</A>\r
+      </H4>\r
+      <P>\r
+         The Web server may provide a way to specify other components of an application&#39;s initial process state,\r
+         such as the priority, user ID, group ID, root directory, and working directory of the process.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S3">3. Protocol Basics</A>\r
+      </H3>\r
+      <H4>\r
+         <A NAME="S3.1">3.1 Notation</A>\r
+      </H4>\r
+      <P>\r
+         We use C language notation to define protocol message formats. All structure elements are defined in terms of\r
+         the <TT>unsigned char</TT> type, and are arranged so that an ISO C compiler lays them out in the obvious\r
+         manner, with no padding. The first byte defined in the structure is transmitted first, the second byte second,\r
+         etc.\r
+      </P>\r
+      <P>\r
+         We use two conventions to abbreviate our definitions.\r
+      </P>\r
+      <P>\r
+         First, when two adjacent structure components are named identically except for the suffixes\r
+         &quot;<TT>B1</TT>&quot; and &quot;<TT>B0</TT>,&quot; it means that the two components may be viewed as a\r
+         single number, computed as <TT>B1&lt;&lt;8 + B0</TT>. The name of this single number is the name of the\r
+         components, minus the suffixes. This convention generalizes in an obvious way to handle numbers represented in\r
+         more than two bytes.\r
+      </P>\r
+      <P>\r
+         Second, we extend C <TT>struct</TT>s to allow the form\r
+      </P>\r
+<PRE>\r
+        struct {\r
+            unsigned char mumbleLengthB1;\r
+            unsigned char mumbleLengthB0;\r
+            ... /* other stuff */\r
+            unsigned char mumbleData[mumbleLength];\r
+        };\r
+</PRE>\r
+      <P>\r
+         meaning a structure of varying length, where the length of a component is determined by the values of the\r
+         indicated earlier component or components.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S3.2">3.2 Accepting Transport Connections</A>\r
+      </H4>\r
+      <P>\r
+         A FastCGI application calls <TT>accept()</TT> on the socket referred to by file descriptor\r
+         <TT>FCGI_LISTENSOCK_FILENO</TT> to accept a new transport connection. If the <TT>accept()</TT> succeeds, and\r
+         the <TT>FCGI_WEB_SERVER_ADDRS</TT> environment variable is bound, the application application immediately\r
+         performs the following special processing:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            <TT>FCGI_WEB_SERVER_ADDRS</TT>: The value is a list of valid IP addresses for the Web server.\r
+            <P>\r
+               If <TT>FCGI_WEB_SERVER_ADDRS</TT> was bound, the application checks the peer IP address of the new\r
+               connection for membership in the list. If the check fails (including the possibility that the connection\r
+               didn&#39;t use TCP/IP transport), the application responds by closing the connection.\r
+            </P>\r
+            <P>\r
+               <TT>FCGI_WEB_SERVER_ADDRS</TT> is expressed as a comma-separated list of IP addresses. Each IP address\r
+               is written as four decimal numbers in the range [0..255] separated by decimal points. So one legal\r
+               binding for this variable is <TT>FCGI_WEB_SERVER_ADDRS=199.170.183.28,199.170.183.71</TT>.\r
+            </P>\r
+            <BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         An application may accept several concurrent transport connections, but it need not do so.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S3.3">3.3 Records</A>\r
+      </H4>\r
+      <P>\r
+         Applications execute requests from a Web server using a simple protocol. Details of the protocol depend upon\r
+         the application&#39;s role, but roughly speaking the Web server first sends parameters and other data to the\r
+         application, then the application sends result data to the Web server, and finally the application sends the\r
+         Web server an indication that the request is complete.\r
+      </P>\r
+      <P>\r
+         All data that flows over the transport connection is carried in <I>FastCGI records</I>. FastCGI records\r
+         accomplish two things. First, records multiplex the transport connection between several independent FastCGI\r
+         requests. This multiplexing supports applications that are able to process concurrent requests using\r
+         event-driven or multi-threaded programming techniques. Second, records provide several independent data\r
+         streams in each direction within a single request. This way, for instance, both <TT>stdout</TT> and\r
+         <TT>stderr</TT> data can pass over a single transport connection from the application to the Web server,\r
+         rather than requiring separate connections.\r
+      </P>\r
+      <P>\r
+      </P>\r
+<PRE>\r
+        typedef struct {\r
+            unsigned char version;\r
+            unsigned char type;\r
+            unsigned char requestIdB1;\r
+            unsigned char requestIdB0;\r
+            unsigned char contentLengthB1;\r
+            unsigned char contentLengthB0;\r
+            unsigned char paddingLength;\r
+            unsigned char reserved;\r
+            unsigned char contentData[contentLength];\r
+            unsigned char paddingData[paddingLength];\r
+        } FCGI_Record;\r
+</PRE>\r
+      <P>\r
+         A FastCGI record consists of a fixed-length prefix followed by a variable number of content and padding bytes.\r
+         A record contains seven components:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            <TT>version</TT>: Identifies the FastCGI protocol version. This specification documents\r
+            <TT>FCGI_VERSION_1</TT>.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>type</TT>: Identifies the FastCGI record type, i.e. the general function that the record performs.\r
+            Specific record types and their functions are detailed in later sections.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>requestId</TT>: Identifies the <I>FastCGI request</I> to which the record belongs.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>contentLength</TT>: The number of bytes in the <TT>contentData</TT> component of the record.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>paddingLength</TT>: The number of bytes in the <TT>paddingData</TT> component of the record.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>contentData</TT>: Between 0 and 65535 bytes of data, interpreted according to the record type.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>paddingData</TT>: Between 0 and 255 bytes of data, which are ignored.<BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         We use a relaxed C <TT>struct</TT> initializer syntax to specify constant FastCGI records. We omit the\r
+         <TT>version</TT> component, ignore padding, and treat <TT>requestId</TT> as a number. Thus\r
+         <TT>{FCGI_END_REQUEST, 1, {FCGI_REQUEST_COMPLETE,0}}</TT> is a record with <TT>type == FCGI_END_REQUEST</TT>,\r
+         <TT>requestId == 1</TT>, and <TT>contentData == {FCGI_REQUEST_COMPLETE,0}</TT>.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H5>\r
+         Padding\r
+      </H5>\r
+      <P>\r
+         The protocol allows senders to pad the records they send, and requires receivers to interpret the\r
+         <TT>paddingLength</TT> and skip the <TT>paddingData</TT>. Padding allows senders to keep data aligned for more\r
+         efficient processing. Experience with the X window system protocols shows the performance benefit of such\r
+         alignment.\r
+      </P>\r
+      <P>\r
+         We recommend that records be placed on boundaries that are multiples of eight bytes. The fixed-length portion\r
+         of a <TT>FCGI_Record</TT> is eight bytes.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H5>\r
+         Managing Request IDs\r
+      </H5>\r
+      <P>\r
+         The Web server re-uses FastCGI request IDs; the application keeps track of the current state of each request\r
+         ID on a given transport connection. A request ID <TT>R</TT> becomes active when the application receives a\r
+         record <TT>{FCGI_BEGIN_REQUEST, R, ...}</TT> and becomes inactive when the application sends a record\r
+         <TT>{FCGI_END_REQUEST, R, ...}</TT> to the Web server.\r
+      </P>\r
+      <P>\r
+         While a request ID <TT>R</TT> is inactive, the application ignores records with <TT>requestId == R</TT>,\r
+         except for <TT>FCGI_BEGIN_REQUEST</TT> records as just described.\r
+      </P>\r
+      <P>\r
+         The Web server attempts to keep FastCGI request IDs small. That way the application can keep track of request\r
+         ID states using a short array rather than a long array or a hash table. An application also has the option of\r
+         accepting only one request at a time. In this case the application simply checks incoming <TT>requestId</TT>\r
+         values against the current request ID.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H5>\r
+         Types of Record Types\r
+      </H5>\r
+      <P>\r
+         There are two useful ways of classifying FastCGI record types.\r
+      </P>\r
+      <P>\r
+         The first distinction is between <I>management</I> records and <I>application</I> records. A management record\r
+         contains information that is not specific to any Web server request, such as information about the protocol\r
+         capabilities of the application. An application record contains information about a particular request,\r
+         identified by the <TT>requestId</TT> component.\r
+      </P>\r
+      <P>\r
+         Management records have a <TT>requestId</TT> value of zero, also called the <I>null request ID</I>.\r
+         Application records have a nonzero <TT>requestId</TT>.\r
+      </P>\r
+      <P>\r
+         The second distinction is between <I>discrete</I> and <I>stream</I> records. A discrete record contains a\r
+         meaningful unit of data all by itself. A stream record is part of a <I>stream</I>, i.e. a series of zero or\r
+         more non-empty records (<TT>length != 0</TT>) of the stream type, followed by an empty record (<TT>length ==\r
+         0</TT>) of the stream type. The <TT>contentData</TT> components of a stream&#39;s records, when concatenated,\r
+         form a byte sequence; this byte sequence is the value of the stream. Therefore the value of a stream is\r
+         independent of how many records it contains or how its bytes are divided among the non-empty records.\r
+      </P>\r
+      <P>\r
+         These two classifications are independent. Among the record types defined in this version of the FastCGI\r
+         protocol, all management record types are also discrete record types, and nearly all application record types\r
+         are stream record types. But three application record types are discrete, and nothing prevents defining a\r
+         management record type that&#39;s a stream in some later version of the protocol.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S3.4">3.4 Name-Value Pairs</A>\r
+      </H4>\r
+      <P>\r
+         In many of their roles, FastCGI applications need to read and write varying numbers of variable-length values.\r
+         So it is useful to adopt a standard format for encoding a name-value pair.\r
+      </P>\r
+      <P>\r
+         FastCGI transmits a name-value pair as the length of the name, followed by the length of the value, followed\r
+         by the name, followed by the value. Lengths of 127 bytes and less can be encoded in one byte, while longer\r
+         lengths are always encoded in four bytes:\r
+      </P>\r
+      <P>\r
+      </P>\r
+<PRE>\r
+        typedef struct {\r
+            unsigned char nameLengthB0;  /* nameLengthB0  &gt;&gt; 7 == 0 */\r
+            unsigned char valueLengthB0; /* valueLengthB0 &gt;&gt; 7 == 0 */\r
+            unsigned char nameData[nameLength];\r
+            unsigned char valueData[valueLength];\r
+        } FCGI_NameValuePair11;\r
+\r
+        typedef struct {\r
+            unsigned char nameLengthB0;  /* nameLengthB0  &gt;&gt; 7 == 0 */\r
+            unsigned char valueLengthB3; /* valueLengthB3 &gt;&gt; 7 == 1 */\r
+            unsigned char valueLengthB2;\r
+            unsigned char valueLengthB1;\r
+            unsigned char valueLengthB0;\r
+            unsigned char nameData[nameLength];\r
+            unsigned char valueData[valueLength\r
+                    ((B3 &amp; 0x7f) &lt;&lt; 24) + (B2 &lt;&lt; 16) + (B1 &lt;&lt; 8) + B0];\r
+        } FCGI_NameValuePair14;\r
+\r
+        typedef struct {\r
+            unsigned char nameLengthB3;  /* nameLengthB3  &gt;&gt; 7 == 1 */\r
+            unsigned char nameLengthB2;\r
+            unsigned char nameLengthB1;\r
+            unsigned char nameLengthB0;\r
+            unsigned char valueLengthB0; /* valueLengthB0 &gt;&gt; 7 == 0 */\r
+            unsigned char nameData[nameLength\r
+                    ((B3 &amp; 0x7f) &lt;&lt; 24) + (B2 &lt;&lt; 16) + (B1 &lt;&lt; 8) + B0];\r
+            unsigned char valueData[valueLength];\r
+        } FCGI_NameValuePair41;\r
+\r
+        typedef struct {\r
+            unsigned char nameLengthB3;  /* nameLengthB3  &gt;&gt; 7 == 1 */\r
+            unsigned char nameLengthB2;\r
+            unsigned char nameLengthB1;\r
+            unsigned char nameLengthB0;\r
+            unsigned char valueLengthB3; /* valueLengthB3 &gt;&gt; 7 == 1 */\r
+            unsigned char valueLengthB2;\r
+            unsigned char valueLengthB1;\r
+            unsigned char valueLengthB0;\r
+            unsigned char nameData[nameLength\r
+                    ((B3 &amp; 0x7f) &lt;&lt; 24) + (B2 &lt;&lt; 16) + (B1 &lt;&lt; 8) + B0];\r
+            unsigned char valueData[valueLength\r
+                    ((B3 &amp; 0x7f) &lt;&lt; 24) + (B2 &lt;&lt; 16) + (B1 &lt;&lt; 8) + B0];\r
+        } FCGI_NameValuePair44;\r
+</PRE>\r
+      <P>\r
+         The high-order bit of the first byte of a length indicates the length&#39;s encoding. A high-order zero\r
+         implies a one-byte encoding, a one a four-byte encoding.\r
+      </P>\r
+      <P>\r
+         This name-value pair format allows the sender to transmit binary values without additional encoding, and\r
+         enables the receiver to allocate the correct amount of storage immediately even for large values.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S3.5">3.5 Closing Transport Connections</A>\r
+      </H4>\r
+      <P>\r
+         The Web server controls the lifetime of transport connections. The Web server can close a connection when no\r
+         requests are active. Or the Web server can delegate close authority to the application (see\r
+         <TT>FCGI_BEGIN_REQUEST</TT>). In this case the application closes the connection at the end of a specified\r
+         request.\r
+      </P>\r
+      <P>\r
+         This flexibility accommodates a variety of application styles. Simple applications will process one request at\r
+         a time and accept a new transport connection for each request. More complex applications will process\r
+         concurrent requests, over one or multiple transport connections, and will keep transport connections open for\r
+         long periods of time.\r
+      </P>\r
+      <P>\r
+         A simple application gets a significant performance boost by closing the transport connection when it has\r
+         finished writing its response. The Web server needs to control the connection lifetime for long-lived\r
+         connections.\r
+      </P>\r
+      <P>\r
+         When an application closes a connection or finds that a connection has closed, the application initiates a new\r
+         connection.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S4">4. Management Record Types</A>\r
+      </H3>\r
+      <H4>\r
+         <A NAME="S4.1">4.1 <TT>FCGI_GET_VALUES, FCGI_GET_VALUES_RESULT</TT></A>\r
+      </H4>\r
+      <P>\r
+         The Web server can query specific variables within the application. The server will typically perform a query\r
+         on application startup in order to to automate certain aspects of system configuration.\r
+      </P>\r
+      <P>\r
+         The application receives a query as a record <TT>{FCGI_GET_VALUES, 0, ...}</TT>. The <TT>contentData</TT>\r
+         portion of a <TT>FCGI_GET_VALUES</TT> record contains a sequence of name-value pairs with empty values.\r
+      </P>\r
+      <P>\r
+         The application responds by sending a record <TT>{FCGI_GET_VALUES_RESULT, 0, ...}</TT> with the values\r
+         supplied. If the application doesn&#39;t understand a variable name that was included in the query, it omits\r
+         that name from the response.\r
+      </P>\r
+      <P>\r
+         <TT>FCGI_GET_VALUES</TT> is designed to allow an open-ended set of variables. The initial set provides\r
+         information to help the server perform application and connection management:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            <TT>FCGI_MAX_CONNS</TT>: The maximum number of concurrent transport connections this application will\r
+            accept, e.g. <TT>&quot;1&quot;</TT> or <TT>&quot;10&quot;</TT>.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>FCGI_MAX_REQS</TT>: The maximum number of concurrent requests this application will accept, e.g.\r
+            <TT>&quot;1&quot;</TT> or <TT>&quot;50&quot;</TT>.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>FCGI_MPXS_CONNS</TT>: <TT>&quot;0&quot;</TT> if this application does not multiplex connections (i.e.\r
+            handle concurrent requests over each connection), <TT>&quot;1&quot;</TT> otherwise.<BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         An application may receive a <TT>FCGI_GET_VALUES</TT> record at any time. The application&#39;s response\r
+         should not involve the application proper but only the FastCGI library.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S4.2">4.2 <TT>FCGI_UNKNOWN_TYPE</TT></A>\r
+      </H4>\r
+      <P>\r
+         The set of management record types is likely to grow in future versions of this protocol. To provide for this\r
+         evolution, the protocol includes the <TT>FCGI_UNKNOWN_TYPE</TT> management record. When an application\r
+         receives a management record whose type <TT>T</TT> it does not understand, the application responds with\r
+         <TT>{FCGI_UNKNOWN_TYPE, 0, {T}}</TT>.\r
+      </P>\r
+      <P>\r
+         The <TT>contentData</TT> component of a <TT>FCGI_UNKNOWN_TYPE</TT> record has the form:\r
+      </P>\r
+<PRE>\r
+        typedef struct {\r
+            unsigned char type;    \r
+            unsigned char reserved[7];\r
+        } FCGI_UnknownTypeBody;\r
+</PRE>\r
+      <P>\r
+         The <TT>type</TT> component is the type of the unrecognized management record.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S5">5. Application Record Types</A>\r
+      </H3>\r
+      <H4>\r
+         <A NAME="S5.1">5.1 <TT>FCGI_BEGIN_REQUEST</TT></A>\r
+      </H4>\r
+      <P>\r
+         The Web server sends a <TT>FCGI_BEGIN_REQUEST</TT> record to start a request.\r
+      </P>\r
+      <P>\r
+         The <TT>contentData</TT> component of a <TT>FCGI_BEGIN_REQUEST</TT> record has the form:\r
+      </P>\r
+<PRE>\r
+        typedef struct {\r
+            unsigned char roleB1;\r
+            unsigned char roleB0;\r
+            unsigned char flags;\r
+            unsigned char reserved[5];\r
+        } FCGI_BeginRequestBody;\r
+</PRE>\r
+      <P>\r
+         The <TT>role</TT> component sets the role the Web server expects the application to play. The\r
+         currently-defined roles are:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            <TT>FCGI_RESPONDER</TT>\r
+         </LI>\r
+         <LI>\r
+            <TT>FCGI_AUTHORIZER</TT>\r
+         </LI>\r
+         <LI>\r
+            <TT>FCGI_FILTER</TT>\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         Roles are described in more detail in <A HREF="#S6">Section 6</A> below.\r
+      </P>\r
+      <P>\r
+         The <TT>flags</TT> component contains a bit that controls connection shutdown:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            <TT>flags &amp; FCGI_KEEP_CONN</TT>: If zero, the application closes the connection after responding to\r
+            this request. If not zero, the application does not close the connection after responding to this request;\r
+            the Web server retains responsibility for the connection.<BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+      <H4>\r
+         <A NAME="S5.2">5.2 Name-Value Pair Stream: <TT>FCGI_PARAMS</TT></A>\r
+      </H4>\r
+      <TT>FCGI_PARAMS</TT>\r
+      <P>\r
+         is a stream record type used in sending name-value pairs from the Web server to the application. The\r
+         name-value pairs are sent down the stream one after the other, in no specified order.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S5.3">5.3 Byte Streams: <TT>FCGI_STDIN</TT>, <TT>FCGI_DATA</TT>, <TT>FCGI_STDOUT</TT>,\r
+         <TT>FCGI_STDERR</TT></A>\r
+      </H4>\r
+      <TT>FCGI_STDIN</TT>\r
+      <P>\r
+         is a stream record type used in sending arbitrary data from the Web server to the application.\r
+         <TT>FCGI_DATA</TT> is a second stream record type used to send additional data to the application.\r
+      </P>\r
+      <P>\r
+         <TT>FCGI_STDOUT</TT> and <TT>FCGI_STDERR</TT> are stream record types for sending arbitrary data and error\r
+         data respectively from the application to the Web server.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S5.4">5.4 <TT>FCGI_ABORT_REQUEST</TT></A>\r
+      </H4>\r
+      <P>\r
+         The Web server sends a <TT>FCGI_ABORT_REQUEST</TT> record to abort a request. After receiving\r
+         <TT>{FCGI_ABORT_REQUEST, R}</TT>, the application responds as soon as possible with <TT>{FCGI_END_REQUEST, R,\r
+         {FCGI_REQUEST_COMPLETE, appStatus}}</TT>. This is truly a response from the application, not a low-level\r
+         acknowledgement from the FastCGI library.\r
+      </P>\r
+      <P>\r
+         A Web server aborts a FastCGI request when an HTTP client closes its transport connection while the FastCGI\r
+         request is running on behalf of that client. The situation may seem unlikely; most FastCGI requests will have\r
+         short response times, with the Web server providing output buffering if the client is slow. But the FastCGI\r
+         application may be delayed communicating with another system, or performing a server push.\r
+      </P>\r
+      <P>\r
+         When a Web server is not multiplexing requests over a transport connection, the Web server can abort a request\r
+         by closing the request&#39;s transport connection. But with multiplexed requests, closing the transport\r
+         connection has the unfortunate effect of aborting <I>all</I> the requests on the connection.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S5.5">5.5 <TT>FCGI_END_REQUEST</TT></A>\r
+      </H4>\r
+      <P>\r
+         The application sends a <TT>FCGI_END_REQUEST</TT> record to terminate a request, either because the\r
+         application has processed the request or because the application has rejected the request.\r
+      </P>\r
+      <P>\r
+         The <TT>contentData</TT> component of a <TT>FCGI_END_REQUEST</TT> record has the form:\r
+      </P>\r
+<PRE>\r
+        typedef struct {\r
+            unsigned char appStatusB3;\r
+            unsigned char appStatusB2;\r
+            unsigned char appStatusB1;\r
+            unsigned char appStatusB0;\r
+            unsigned char protocolStatus;\r
+            unsigned char reserved[3];\r
+        } FCGI_EndRequestBody;\r
+</PRE>\r
+      <P>\r
+         The <TT>appStatus</TT> component is an application-level status code. Each role documents its usage of\r
+         <TT>appStatus</TT>.\r
+      </P>\r
+      <P>\r
+         The <TT>protocolStatus</TT> component is a protocol-level status code; the possible <TT>protocolStatus</TT>\r
+         values are:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            <TT>FCGI_REQUEST_COMPLETE</TT>: normal end of request.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>FCGI_CANT_MPX_CONN</TT>: rejecting a new request. This happens when a Web server sends concurrent\r
+            requests over one connection to an application that is designed to process one request at a time per\r
+            connection.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>FCGI_OVERLOADED</TT>: rejecting a new request. This happens when the application runs out of some\r
+            resource, e.g. database connections.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>FCGI_UNKNOWN_ROLE</TT>: rejecting a new request. This happens when the Web server has specified a role\r
+            that is unknown to the application.<BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+      <H3>\r
+         <A NAME="S6">6. Roles</A>\r
+      </H3>\r
+      <H4>\r
+         <A NAME="S6.1">6.1 Role Protocols</A>\r
+      </H4>\r
+      <P>\r
+         Role protocols only include records with application record types. They transfer essentially all data using\r
+         streams.\r
+      </P>\r
+      <P>\r
+         To make the protocols reliable and to simplify application programming, role protocols are designed to use\r
+         <I>nearly sequential marshalling</I>. In a protocol with strictly sequential marshalling, the application\r
+         receives its first input, then its second, etc. until it has received them all. Similarly, the application\r
+         sends its first output, then its second, etc. until it has sent them all. Inputs are not interleaved with each\r
+         other, and outputs are not interleaved with each other.\r
+      </P>\r
+      <P>\r
+         The sequential marshalling rule is too restrictive for some FastCGI roles, because CGI programs can write to\r
+         both <TT>stdout</TT> and <TT>stderr</TT> without timing restrictions. So role protocols that use both\r
+         <TT>FCGI_STDOUT</TT> and <TT>FCGI_STDERR</TT> allow these two streams to be interleaved.\r
+      </P>\r
+      <P>\r
+         All role protocols use the <TT>FCGI_STDERR</TT> stream just the way <TT>stderr</TT> is used in conventional\r
+         applications programming: to report application-level errors in an intelligible way. Use of the\r
+         <TT>FCGI_STDERR</TT> stream is always optional. If an application has no errors to report, it sends either no\r
+         <TT>FCGI_STDERR</TT> records or one zero-length <TT>FCGI_STDERR</TT> record.\r
+      </P>\r
+      <P>\r
+         When a role protocol calls for transmitting a stream other than <TT>FCGI_STDERR</TT>, at least one record of\r
+         the stream type is always transmitted, even if the stream is empty.\r
+      </P>\r
+      <P>\r
+         Again in the interests of reliable protocols and simplified application programming, role protocols are\r
+         designed to be <I>nearly request-response</I>. In a truly request-response protocol, the application receives\r
+         all of its input records before sending its first output record. Request-response protocols don&#39;t allow\r
+         pipelining.\r
+      </P>\r
+      <P>\r
+         The request-response rule is too restrictive for some FastCGI roles; after all, CGI programs aren&#39;t\r
+         restricted to read all of <TT>stdin</TT> before starting to write <TT>stdout</TT>. So some role protocols\r
+         allow that specific possibility. First the application receives all of its inputs except for a final stream\r
+         input. As the application begins to receive the final stream input, it can begin writing its output.\r
+      </P>\r
+      <P>\r
+         When a role protocol uses <TT>FCGI_PARAMS</TT> to transmit textual values, such as the values that CGI\r
+         programs obtain from environment variables, the length of the value does not include the terminating null\r
+         byte, and the value itself does not include a null byte. An application that needs to provide\r
+         <TT>environ(7)</TT> format name-value pairs must insert an equal sign between the name and value and append a\r
+         null byte after the value.\r
+      </P>\r
+      <P>\r
+         Role protocols do not support the non-parsed header feature of CGI. FastCGI applications set response status\r
+         using the <TT>Status</TT> and <TT>Location</TT> CGI headers.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S6.2">6.2 Responder</A>\r
+      </H4>\r
+      <P>\r
+         A Responder FastCGI application has the same purpose as a CGI/1.1 program: It receives all the information\r
+         associated with an HTTP request and generates an HTTP response.\r
+      </P>\r
+      <P>\r
+         It suffices to explain how each element of CGI/1.1 is emulated by a Responder:\r
+      </P>\r
+      <BR>\r
+      <BR>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            The Responder application receives CGI/1.1 environment variables from the Web server over\r
+            <TT>FCGI_PARAMS</TT>.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            Next the Responder application receives CGI/1.1 <TT>stdin</TT> data from the Web server over\r
+            <TT>FCGI_STDIN</TT>. The application receives at most <TT>CONTENT_LENGTH</TT> bytes from this stream before\r
+            receiving the end-of-stream indication. (The application receives less than <TT>CONTENT_LENGTH</TT> bytes\r
+            only if the HTTP client fails to provide them, e.g. because the client crashed.)\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            The Responder application sends CGI/1.1 <TT>stdout</TT> data to the Web server over <TT>FCGI_STDOUT</TT>,\r
+            and CGI/1.1 <TT>stderr</TT> data over <TT>FCGI_STDERR</TT>. The application sends these concurrently, not\r
+            one after the other. The application must wait to finish reading <TT>FCGI_PARAMS</TT> before it begins\r
+            writing <TT>FCGI_STDOUT</TT> and <TT>FCGI_STDERR</TT>, but it needn&#39;t finish reading from\r
+            <TT>FCGI_STDIN</TT> before it begins writing these two streams.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            After sending all its <TT>stdout</TT> and <TT>stderr</TT> data, the Responder application sends a\r
+            <TT>FCGI_END_REQUEST</TT> record. The application sets the <TT>protocolStatus</TT> component to\r
+            <TT>FCGI_REQUEST_COMPLETE</TT> and the <TT>appStatus</TT> component to the status code that the CGI program\r
+            would have returned via the <TT>exit</TT> system call.<BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         A Responder performing an update, e.g. implementing a <TT>POST</TT> method, should compare the number of bytes\r
+         received on <TT>FCGI_STDIN</TT> with <TT>CONTENT_LENGTH</TT> and abort the update if the two numbers are not\r
+         equal.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H4>\r
+         <A NAME="S6.3">6.3 Authorizer</A>\r
+      </H4>\r
+      <P>\r
+         An Authorizer FastCGI application receives all the information associated with an HTTP request and generates\r
+         an authorized/unauthorized decision. In case of an authorized decision the Authorizer can also associate\r
+         name-value pairs with the HTTP request; when giving an unauthorized decision the Authorizer sends a complete\r
+         response to the HTTP client.\r
+      </P>\r
+      <P>\r
+         Since CGI/1.1 defines a perfectly good way to represent the information associated with an HTTP request,\r
+         Authorizers use the same representation:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            The Authorizer application receives HTTP request information from the Web server on the\r
+            <TT>FCGI_PARAMS</TT> stream, in the same format as a Responder. The Web server does not send\r
+            <TT>CONTENT_LENGTH</TT>, <TT>PATH_INFO</TT>, <TT>PATH_TRANSLATED</TT>, and <TT>SCRIPT_NAME</TT> headers.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            The Authorizer application sends <TT>stdout</TT> and <TT>stderr</TT> data in the same manner as a\r
+            Responder. The CGI/1.1 response status specifies the disposition of the request. If the application sends\r
+            status 200 (OK), the Web server allows access. Depending upon its configuration the Web server may proceed\r
+            with other access checks, including requests to other Authorizers.\r
+            <P>\r
+               An Authorizer application&#39;s 200 response may include headers whose names are prefixed with\r
+               <TT>Variable-</TT>. These headers communicate name-value pairs from the application to the Web server.\r
+               For instance, the response header\r
+            </P>\r
+<PRE>\r
+        Variable-AUTH_METHOD: database lookup\r
+</PRE>\r
+            transmits the value <TT>&quot;database lookup&quot;</TT> with name <TT>AUTH-METHOD</TT>. The server\r
+            associates such name-value pairs with the HTTP request and includes them in subsequent CGI or FastCGI\r
+            requests performed in processing the HTTP request. When the application gives a 200 response, the server\r
+            ignores response headers whose names aren&#39;t prefixed with <TT>Variable-</TT> prefix, and ignores any\r
+            response content.\r
+            <P>\r
+               For Authorizer response status values other than &quot;200&quot; (OK), the Web server denies access and\r
+               sends the response status, headers, and content back to the HTTP client.\r
+            </P>\r
+            <BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+      <H4>\r
+         <A NAME="S6.4">6.4 Filter</A>\r
+      </H4>\r
+      <P>\r
+         A Filter FastCGI application receives all the information associated with an HTTP request, plus an extra\r
+         stream of data from a file stored on the Web server, and generates a &quot;filtered&quot; version of the data\r
+         stream as an HTTP response.\r
+      </P>\r
+      <P>\r
+         A Filter is similar in functionality to a Responder that takes a data file as a parameter. The difference is\r
+         that with a Filter, both the data file and the Filter itself can be access controlled using the Web\r
+         server&#39;s access control mechanisms, while a Responder that takes the name of a data file as a parameter\r
+         must perform its own access control checks on the data file.\r
+      </P>\r
+      <P>\r
+         The steps taken by a Filter are similar to those of a Responder. The server presents the Filter with\r
+         environment variables first, then standard input (normally form <TT>POST</TT> data), finally the data file\r
+         input:\r
+      </P>\r
+      <BR>\r
+      <BR>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            Like a Responder, the Filter application receives name-value pairs from the Web server over\r
+            <TT>FCGI_PARAMS</TT>. Filter applications receive two Filter-specific variables:\r
+            <TT>FCGI_DATA_LAST_MOD</TT> and <TT>FCGI_DATA_LENGTH</TT>.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            Next the Filter application receives CGI/1.1 <TT>stdin</TT> data from the Web server over\r
+            <TT>FCGI_STDIN</TT>. The application receives at most <TT>CONTENT_LENGTH</TT> bytes from this stream before\r
+            receiving the end-of-stream indication. (The application receives less than <TT>CONTENT_LENGTH</TT> bytes\r
+            only if the HTTP client fails to provide them, e.g. because the client crashed.)\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            Next the Filter application receives the file data from the Web server over <TT>FCGI_DATA</TT>. This\r
+            file&#39;s last modification time (expressed as an integer number of seconds since the epoch January 1,\r
+            1970 UTC) is <TT>FCGI_DATA_LAST_MOD</TT>; the application may consult this variable and respond from a\r
+            cache without reading the file data. The application reads at most <TT>FCGI_DATA_LENGTH</TT> bytes from\r
+            this stream before receiving the end-of-stream indication.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            The Filter application sends CGI/1.1 <TT>stdout</TT> data to the Web server over <TT>FCGI_STDOUT</TT>, and\r
+            CGI/1.1 <TT>stderr</TT> data over <TT>FCGI_STDERR</TT>. The application sends these concurrently, not one\r
+            after the other. The application must wait to finish reading <TT>FCGI_STDIN</TT> before it begins writing\r
+            <TT>FCGI_STDOUT</TT> and <TT>FCGI_STDERR</TT>, but it needn&#39;t finish reading from <TT>FCGI_DATA</TT>\r
+            before it begins writing these two streams.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            After sending all its <TT>stdout</TT> and <TT>stderr</TT> data, the application sends a\r
+            <TT>FCGI_END_REQUEST</TT> record. The application sets the <TT>protocolStatus</TT> component to\r
+            <TT>FCGI_REQUEST_COMPLETE</TT> and the <TT>appStatus</TT> component to the status code that a similar CGI\r
+            program would have returned via the <TT>exit</TT> system call.<BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         A Filter should compare the number of bytes received on <TT>FCGI_STDIN</TT> with <TT>CONTENT_LENGTH</TT> and\r
+         on <TT>FCGI_DATA</TT> with <TT>FCGI_DATA_LENGTH</TT>. If the numbers don&#39;t match and the Filter is a\r
+         query, the Filter response should provide an indication that data is missing. If the numbers don&#39;t match\r
+         and the Filter is an update, the Filter should abort the update.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S7">7. Errors</A>\r
+      </H3>\r
+      <P>\r
+         A FastCGI application exits with zero status to indicate that it terminated on purpose, e.g. in order to\r
+         perform a crude form of garbage collection. A FastCGI application that exits with nonzero status is assumed to\r
+         have crashed. How a Web server or other application manager responds to applications that exit with zero or\r
+         nonzero status is outside the scope of this specification.\r
+      </P>\r
+      <P>\r
+         A Web server can request that a FastCGI application exit by sending it <TT>SIGTERM</TT>. If the application\r
+         ignores <TT>SIGTERM</TT> the Web server can resort to <TT>SIGKILL</TT>.\r
+      </P>\r
+      <P>\r
+         FastCGI applications report application-level errors with the <TT>FCGI_STDERR</TT> stream and the\r
+         <TT>appStatus</TT> component of the <TT>FCGI_END_REQUEST</TT> record. In many cases an error will be reported\r
+         directly to the user via the <TT>FCGI_STDOUT</TT> stream.\r
+      </P>\r
+      <P>\r
+         On Unix, applications report lower-level errors, including FastCGI protocol errors and syntax errors in\r
+         FastCGI environment variables, to <TT>syslog</TT>. Depending upon the severity of the error, the application\r
+         may either continue or exit with nonzero status.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S8">8. Types and Constants</A>\r
+      </H3>\r
+<PRE>\r
+/*\r
+ * Listening socket file number\r
+ */\r
+#define FCGI_LISTENSOCK_FILENO 0\r
+\r
+typedef struct {\r
+    unsigned char version;\r
+    unsigned char type;\r
+    unsigned char requestIdB1;\r
+    unsigned char requestIdB0;\r
+    unsigned char contentLengthB1;\r
+    unsigned char contentLengthB0;\r
+    unsigned char paddingLength;\r
+    unsigned char reserved;\r
+} FCGI_Header;\r
+\r
+/*\r
+ * Number of bytes in a FCGI_Header.  Future versions of the protocol\r
+ * will not reduce this number.\r
+ */\r
+#define FCGI_HEADER_LEN  8\r
+\r
+/*\r
+ * Value for version component of FCGI_Header\r
+ */\r
+#define FCGI_VERSION_1           1\r
+\r
+/*\r
+ * Values for type component of FCGI_Header\r
+ */\r
+#define FCGI_BEGIN_REQUEST       1\r
+#define FCGI_ABORT_REQUEST       2\r
+#define FCGI_END_REQUEST         3\r
+#define FCGI_PARAMS              4\r
+#define FCGI_STDIN               5\r
+#define FCGI_STDOUT              6\r
+#define FCGI_STDERR              7\r
+#define FCGI_DATA                8\r
+#define FCGI_GET_VALUES          9\r
+#define FCGI_GET_VALUES_RESULT  10\r
+#define FCGI_UNKNOWN_TYPE       11\r
+#define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE)\r
+\r
+/*\r
+ * Value for requestId component of FCGI_Header\r
+ */\r
+#define FCGI_NULL_REQUEST_ID     0\r
+\r
+typedef struct {\r
+    unsigned char roleB1;\r
+    unsigned char roleB0;\r
+    unsigned char flags;\r
+    unsigned char reserved[5];\r
+} FCGI_BeginRequestBody;\r
+\r
+typedef struct {\r
+    FCGI_Header header;\r
+    FCGI_BeginRequestBody body;\r
+} FCGI_BeginRequestRecord;\r
+\r
+/*\r
+ * Mask for flags component of FCGI_BeginRequestBody\r
+ */\r
+#define FCGI_KEEP_CONN  1\r
+\r
+/*\r
+ * Values for role component of FCGI_BeginRequestBody\r
+ */\r
+#define FCGI_RESPONDER  1\r
+#define FCGI_AUTHORIZER 2\r
+#define FCGI_FILTER     3\r
+\r
+typedef struct {\r
+    unsigned char appStatusB3;\r
+    unsigned char appStatusB2;\r
+    unsigned char appStatusB1;\r
+    unsigned char appStatusB0;\r
+    unsigned char protocolStatus;\r
+    unsigned char reserved[3];\r
+} FCGI_EndRequestBody;\r
+\r
+typedef struct {\r
+    FCGI_Header header;\r
+    FCGI_EndRequestBody body;\r
+} FCGI_EndRequestRecord;\r
+\r
+/*\r
+ * Values for protocolStatus component of FCGI_EndRequestBody\r
+ */\r
+#define FCGI_REQUEST_COMPLETE 0\r
+#define FCGI_CANT_MPX_CONN    1\r
+#define FCGI_OVERLOADED       2\r
+#define FCGI_UNKNOWN_ROLE     3\r
+\r
+/*\r
+ * Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT records\r
+ */\r
+#define FCGI_MAX_CONNS  &quot;FCGI_MAX_CONNS&quot;\r
+#define FCGI_MAX_REQS   &quot;FCGI_MAX_REQS&quot;\r
+#define FCGI_MPXS_CONNS &quot;FCGI_MPXS_CONNS&quot;\r
+\r
+typedef struct {\r
+    unsigned char type;    \r
+    unsigned char reserved[7];\r
+} FCGI_UnknownTypeBody;\r
+\r
+typedef struct {\r
+    FCGI_Header header;\r
+    FCGI_UnknownTypeBody body;\r
+} FCGI_UnknownTypeRecord;\r
+</PRE>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S9">9. References</A>\r
+      </H3>\r
+      <P>\r
+         National Center for Supercomputer Applications, <A HREF="http://hoohoo.ncsa.uiuc.edu/cgi/">The Common Gateway\r
+         Interface</A>, version CGI/1.1.\r
+      </P>\r
+      <P>\r
+         D.R.T. Robinson, <A HREF="http://cgi-spec.golux.com/">The WWW\r
+         Common Gateway Interface Version 1.1</A>, Internet-Draft, 15 February 1996.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="SA">A. Table: Properties of the record types</A>\r
+      </H3>\r
+      <P>\r
+         The following chart lists all of the record types and indicates these properties of each:\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <UL TYPE="square">\r
+         <LI>\r
+            <TT>WS-&gt;App</TT>: records of this type can only be sent by the Web server to the application. Records of\r
+            other types can only be sent by the application to the Web server.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>management</TT>: records of this type contain information that is not specific to a Web server request,\r
+            and use the null request ID. Records of other types contain request-specific information, and cannot use\r
+            the null request ID.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>stream</TT>: records of this type form a stream, terminated by a record with empty\r
+            <TT>contentData</TT>. Records of other types are discrete; each carries a meaningful unit of data.<BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+<PRE>\r
+                               WS-&gt;App   management  stream\r
+\r
+        FCGI_GET_VALUES           x          x\r
+        FCGI_GET_VALUES_RESULT               x\r
+        FCGI_UNKNOWN_TYPE                    x\r
+\r
+        FCGI_BEGIN_REQUEST        x\r
+        FCGI_ABORT_REQUEST        x\r
+        FCGI_END_REQUEST\r
+        FCGI_PARAMS               x                    x\r
+        FCGI_STDIN                x                    x\r
+        FCGI_DATA                 x                    x\r
+        FCGI_STDOUT                                    x \r
+        FCGI_STDERR                                    x     \r
+\r
+\r
+</PRE>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="SB">B. Typical Protocol Message Flow</A>\r
+      </H3>\r
+      <P>\r
+         Additional notational conventions for the examples:\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            The <TT>contentData</TT> of stream records (<TT>FCGI_PARAMS</TT>, <TT>FCGI_STDIN</TT>,\r
+            <TT>FCGI_STDOUT</TT>, and <TT>FCGI_STDERR</TT>) is represented as a character string. A string ending in\r
+            <TT>&quot; ... &quot;</TT> is too long to display, so only a prefix is shown.\r
+         </LI>\r
+         <LI>\r
+            Messages sent to the Web server are indented with respect to messages received from the Web server.\r
+         </LI>\r
+         <LI>\r
+            Messages are shown in the time sequence experienced by the application.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         1. A simple request with no data on <TT>stdin</TT>, and a successful response:\r
+      </P>\r
+<PRE>\r
+{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, 0}}\r
+{FCGI_PARAMS,          1, &quot;\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... &quot;}\r
+{FCGI_PARAMS,          1, &quot;&quot;}\r
+{FCGI_STDIN,           1, &quot;&quot;}\r
+\r
+    {FCGI_STDOUT,      1, &quot;Content-type: text/html\r\n\r\n&lt;html&gt;\n&lt;head&gt; ... &quot;}\r
+    {FCGI_STDOUT,      1, &quot;&quot;}\r
+    {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}\r
+</PRE>\r
+      <P>\r
+         2. Similar to example 1, but this time with data on <TT>stdin</TT>. The Web server chooses to send the\r
+         parameters using more <TT>FCGI_PARAMS</TT> records than before:\r
+      </P>\r
+<PRE>\r
+{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, 0}}\r
+{FCGI_PARAMS,          1, &quot;\013\002SERVER_PORT80\013\016SER&quot;}\r
+{FCGI_PARAMS,          1, &quot;VER_ADDR199.170.183.42 ... &quot;}\r
+{FCGI_PARAMS,          1, &quot;&quot;}\r
+{FCGI_STDIN,           1, &quot;quantity=100&amp;item=3047936&quot;}\r
+{FCGI_STDIN,           1, &quot;&quot;}\r
+\r
+    {FCGI_STDOUT,      1, &quot;Content-type: text/html\r\n\r\n&lt;html&gt;\n&lt;head&gt; ... &quot;}\r
+    {FCGI_STDOUT,      1, &quot;&quot;}\r
+    {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}\r
+</PRE>\r
+      <P>\r
+         3. Similar to example 1, but this time the application detects an error. The application logs a message to\r
+         <TT>stderr</TT>, returns a page to the client, and returns non-zero exit status to the Web server. The\r
+         application chooses to send the page using more <TT>FCGI_STDOUT</TT> records:\r
+      </P>\r
+<PRE>\r
+{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, 0}}\r
+{FCGI_PARAMS,          1, &quot;\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... &quot;}\r
+{FCGI_PARAMS,          1, &quot;&quot;}\r
+{FCGI_STDIN,           1, &quot;&quot;}\r
+\r
+    {FCGI_STDOUT,      1, &quot;Content-type: text/html\r\n\r\n&lt;ht&quot;}\r
+    {FCGI_STDERR,      1, &quot;config error: missing SI_UID\n&quot;}\r
+    {FCGI_STDOUT,      1, &quot;ml&gt;\n&lt;head&gt; ... &quot;}\r
+    {FCGI_STDOUT,      1, &quot;&quot;}\r
+    {FCGI_STDERR,      1, &quot;&quot;}\r
+    {FCGI_END_REQUEST, 1, {938, FCGI_REQUEST_COMPLETE}}\r
+</PRE>\r
+      <P>\r
+         4. Two instances of example 1, multiplexed onto a single connection. The first request is more difficult than\r
+         the second, so the application finishes the requests out of order:\r
+      </P>\r
+<PRE>\r
+{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, FCGI_KEEP_CONN}}\r
+{FCGI_PARAMS,          1, &quot;\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... &quot;}\r
+{FCGI_PARAMS,          1, &quot;&quot;}\r
+{FCGI_BEGIN_REQUEST,   2, {FCGI_RESPONDER, FCGI_KEEP_CONN}}\r
+{FCGI_PARAMS,          2, &quot;\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... &quot;}\r
+{FCGI_STDIN,           1, &quot;&quot;}\r
+\r
+    {FCGI_STDOUT,      1, &quot;Content-type: text/html\r\n\r\n&quot;}\r
+\r
+{FCGI_PARAMS,          2, &quot;&quot;}\r
+{FCGI_STDIN,           2, &quot;&quot;}\r
+\r
+    {FCGI_STDOUT,      2, &quot;Content-type: text/html\r\n\r\n&lt;html&gt;\n&lt;head&gt; ... &quot;}\r
+    {FCGI_STDOUT,      2, &quot;&quot;}\r
+    {FCGI_END_REQUEST, 2, {0, FCGI_REQUEST_COMPLETE}}\r
+    {FCGI_STDOUT,      1, &quot;&lt;html&gt;\n&lt;head&gt; ... &quot;}\r
+    {FCGI_STDOUT,      1, &quot;&quot;}\r
+    {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}\r
+</PRE>\r
+      <P>\r
+      </P>\r
+      <HR>\r
+      <ADDRESS>\r
+         &copy; 1995, 1996 Open Market, Inc. / mbrown@openmarket.com\r
+      </ADDRESS>\r
+   </BODY>\r
+</HTML>\r
+\r
index f860fcc..7556ef6 100644 (file)
-<html>
-<head><title>Integrating FastCGI with Tcl</title>
-</head>
-
-<body bgcolor="#FFFFFF" text="#000000" link="#cc0000" alink="#000011" 
-vlink="#555555">
-
-<center>
-<a href="http://fastcgi.com">
-    <img border=0 src="../images/fcgi-hd.gif" alt="[[FastCGI]]"></a>
-</center>
-<br clear=all>
-<h3><center>Integrating FastCGI with Tcl</center></h3>
-
-<!--Copyright (c) 1996 Open Market, Inc.                                    -->
-<!--See the file "LICENSE.TERMS" for information on usage and redistribution-->
-<!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->
-
-<P ALIGN=CENTER>
-Michael S. Shanzer
-<BR>
-Open Market, Inc.
-<BR>
-<EM>19 January 1995</EM>
-</P>
-
-<h5 align=center>
-Copyright &copy; 1996 Open Market, Inc.  245 First Street, Cambridge,
-  MA 02142 U.S.A.<br>
-Tel: 617-621-9500 Fax: 617-621-1703 URL:
-  <a href="http://www.openmarket.com/">http://www.openmarket.com/</a><br>
-$Id: fcgi-tcl.htm,v 1.2 2001/05/14 13:00:30 robs Exp $ <br>
-</h5>
-<hr>
-
-
-<h3><a NAME = "S1">1. Introduction</a></h3>
-
-
-Tcl (tool command language) is an embeddable scripting language
-that's often used for CGI programming.  Tcl is freely available
-as a source kit.<p>
-
-We've built a Tcl interpreter that runs as a FastCGI application.  Our
-purpose in doing so was twofold:
-
-<ul>
-    <li><i>Create a useful artifact.</i>
-        Open Market has written many CGI applications using Tcl.
-        Now we'd like to turn them into FastCGI applications.<p>
-    <li><i>Demonstrate how easy it is to integrate FastCGI with an
-        existing program.</i>
-        The Tcl interpreter is a substantial program, so integrating
-        FastCGI with the Tcl interpreter is a good test of the
-        <tt>fcgi_stdio</tt> compatability library.
-</ul>
-
-We've succeeded on both counts.  We now have a platform for
-migrating our Tcl-based CGI applications to FastCGI.  And
-the integration required a very small effort.  The only source
-code change to the Tcl interpreter was the routine addition of a
-handful of new commands: <tt>FCGI_Accept</tt>, <tt>FCGI_Finish</tt>,
-<tt>FCGI_SetExitStatus</tt>, and <tt>FCGI_StartFilterData</tt>.<p>
-
-The FastCGI-integrated Tcl interpreter works as usual when run
-from a shell or as a CGI program.  You don't need two Tcls,
-one for FastCGI and one for other uses.<p>
-
-The remainder of this document gives a recipe you can follow to
-build FastCGI into Tcl, explains what's happening in the recipe,
-and illustrates the use of FastCGI Tcl with
-an example program.<p>
-
-<h3><a NAME = "S2">2. Recipe</a></h3>
-
-Here are the assumptions embedded in the following recipe:
-<ul>
-    <li>You are building Tcl 7.4p3, the current stable Tcl release
-    as this is written.
-    You unpack the Tcl kit into a directory <tt>tcl7.4</tt>
-    that's a sibling of the FastCGI kit directory
-    <tt>fcgi-devel-kit</tt>.<p>
-
-    <li>You have gcc version 2.7
-    installed on your system, and use it in the build.
-    gcc is convenient because it supports the <tt>-include</tt>
-    command-line option
-    that instructs the C preprocessor to include a specific file before
-    processing any other include files.  This allows you to include
-    <tt>fcgi_stdio.h</tt> without modifying Tcl source files.  (The
-    reason for specifying gcc version 2.7 is that I have
-    experienced bad behavior with an earlier version and the <tt>-include</tt>
-    flag -- the C preprocessor died with SIGABRT.)<p>
-
-    <li>You have GNU autoconf
-    installed on your system.  If you don't have GNU autoconf,
-    you will have to make certain edits by hand and
-    repeat these edits for each build platform.<p>
-</ul>
-
-If those are valid assumptions, follow these steps:
-<ol>
-    <li><i>Build the FastCGI Developer's Kit.</i>
-    Tcl needs to link against <tt>libfcgi.a</tt>, so
-    <a href="fcgi-devel-kit.htm#S2">build
-    the FastCGI Developer's Kit</a>
-    in order to create this library for your platform.<p>
-
-    <li><i>Pull the Tcl 7.4p3 kit.</i>
-    You'll need the files
-    <a href="ftp://ftp.smli.com/pub/tcl/tcl7.4.tar.Z">tcl7.4.tar.Z</a>,
-    <a href="ftp://ftp.smli.com/pub/tcl/tcl7.4p1.patch.gz">tcl7.4p1.patch.gz</a>,
-    <a href="ftp://ftp.smli.com/pub/tcl/tcl7.4p2.patch.gz">tcl7.4p2.patch.gz</a>,
-    and
-    <a href="ftp://ftp.smli.com/pub/tcl/tcl7.4p3.patch.gz">tcl7.4p3.patch.gz</a>.
-    (Some older Netscape browsers can't perform these
-    retrievals because of a protocol conflict between Netscape
-    and Sun's firewall.)<p>
-
-    Unpack the tar file in the parent directory of the
-    FastCGI kit directory you used in the previous step,
-    so that the directories <tt>tcl7.4</tt> and <tt>fcgi-devel-kit</tt>
-    are siblings.  After unpacking the tar file, follow the directions
-    in the <tt>README</tt> to apply the patches.<p>
-
-    The <a href="http://www.sunlabs.com:80/research/tcl/">Sun Labs Tcl/Tk
-    Project Page</a> contains a wealth of information on Tcl, including
-    up to date information on the latest kits.<p>
-
-    <li><i>Copy the files <tt>tclFCGI.c</tt>, <tt>tclAppInit.c</tt>,
-        <tt>Makefile.in</tt>, and <tt>configure.in</tt> from the FastCGI kit.</i>
-    <pre>
-    > cd tcl7.4
-    > mv tclAppInit.c tclAppInit.c.orig
-    > mv Makefile.in.orig Makefile.in.orig.orig
-    > mv Makefile.in Makefile.in.orig
-    > mv configure.in configure.in.orig
-    > cp ../fcgi-devel-kit/tcl/tcl7.4/* .
-    > cp ../fcgi-devel-kit/tcl/common/* .</pre>
-
-    <li><i>Create a new <tt>configure</tt> script.</i>
-    <pre>
-    > autoconf</pre>
-
-    <li><i>Configure and build.</i>
-    <pre>
-    > ./configure
-    > make</pre>
-    The <tt>make</tt> creates the Tcl interpreter <tt>tclsh</tt>
-    and library archive <tt>libtcl.a</tt> (for embedding Tcl in
-    your own C applications).  The Tcl <tt>README</tt> file
-    explains how you can experiment with <tt>tclsh</tt>
-    without installing it in a standard place.<p>
-</ol>
-
-<h3><a NAME = "S3">3. Recipe Explained</a></h3>
-
-The recipe alone is fine if you are using Tcl 7.4p3, you have gcc
-version 2.7, and you have GNU autoconf.  In case one or more of these
-assumptions doesn't hold for you, and to illuminate how little work was
-involved in integrating FastCGI, here's an explanation of how
-and why you would modify the files <tt>tclAppInit.c</tt>,
-<tt>Makefile.in</tt>, and <tt>configure.in</tt> from the Tcl kit.
-
-<ul>
-    <li><tt>tclAppInit.c</tt>:<p>
-    <ul>
-        <li>Add the following three lines of code
-        to the function <tt>Tcl_AppInit</tt> after the call
-        to <tt>Tcl_Init</tt> and after the comment about calling init
-        procedures:
-        <pre>
-    if (FCGI_Init(interp) == TCL_ERROR) {
-        return TCL_ERROR;
-    }</pre>
-        This registers four Tcl commands (<tt>FCGI_Accept</tt>,
-        <tt>FCGI_Finish</tt>, <tt>FCGI_SetExitStatus</tt>, and
-        <tt>FCGI_StartFilterData</tt>), implemented in
-        <tt>tclFCGI.c</tt>, with the Tcl interpreter.<p>
-    </ul>
-
-    <li><tt>Makefile.in</tt>:<p>
-    <ul>
-        <li>Add <tt>tclFCGI.o</tt> to the <tt>GENERIC_OBJS</tt> variable, and
-            add <tt>tclFCGI.c</tt> to the <tt>SRCS</tt> variable.<p>
-
-            This builds the FastCGI Tcl commands and
-            links them into the Tcl interpreter.<p>
-
-        <li>Add <tt>-I../fcgi-devel-kit/include
-                    -include ../fcgi-devel-kit/include/fcgi_stdio.h</tt>
-            to the <tt>CFLAGS</tt> variable.<p>
-
-            This includes <tt>fcgi_stdio.h</tt>
-            when compiling C code for the Tcl interpreter, overriding
-            the normal <tt>stdio</tt> types, variables, and functions.<p>
-
-        <li>Add <tt>../fcgi-devel-kit/libfcgi/libfcgi.a</tt> before the
-            <tt>@LIBS@</tt> part of the <tt>LIBS</tt> variable.<p>
-
-            This links the implementation of <tt>fcgi_stdio.h</tt>
-            into the Tcl interpreter, for use by the <tt>FCGI_accept</tt>
-            command and any code that uses <tt>stdio</tt> variables
-            or calls <tt>stdio</tt> functions.<p>
-    </ul><p>
-
-    The last two edits will vary if you use a compiler other than gcc or
-    install the <tt>tcl7.4</tt> directory
-    somewhere else in relation to the <tt>fcgi-devel-kit</tt> directory.<p>
-
-    <li><tt>configure.in</tt>:<p>
-    <ul>
-        <li>
-        Replace the lines
-        <pre>
-AC_C_CROSS
-CC=${CC-cc}</pre>
-        with the lines
-        <pre>
-AC_PROG_CC
-AC_C_CROSS</pre>
-        This selects gcc in preference to other C compilers.<p>
-         
-        <li>
-        Add the following lines just after the
-        <tt>AC_SUBST(CC)</tt> line:
-        <pre>
-AC_CHECK_LIB(socket, main, [LIBS="$LIBS -lsocket"])
-AC_CHECK_LIB(nsl, main, [LIBS="$LIBS -lnsl"])
-AC_SUBST(LIBS)</pre>
-        This ensures that the socket libraries used by FastCGI
-        are linked into the Tcl interpreter.<p>
-    </ul>
-    If GNU autoconf is not available to you, you'll leave
-    <tt>configure.in</tt> alone and perform the following steps:<p>
-    <ul>
-        <li>
-        Execute
-        <pre>
-    > SETENV CC gcc</pre>
-        before running <tt>configure</tt>.<p>
-
-        <li>
-        If you are running on a SVR4-derived Unix platform,
-        edit <tt>Makefile</tt> to add
-        <tt>-lsocket -lnsl</tt> to the <tt>LIBS</tt> value
-        after running <tt>configure</tt>.<p>
-    </ul>
-    If you ever re-run <tt>configure</tt>, you'll need to repeat
-    these steps.<p>
-
-</ul>
-
-
-<h3><a NAME = "S4">4. Writing FastCGI applications in Tcl</a></h3>
-
-The Tcl program <tt>tcl/tiny-tcl-fcgi</tt> performs the same function as the C 
-program <tt>examples/tiny-fcgi.c</tt> that's used as an example in the <a href="fcgi-devel-kit.htm#S3.1.1">FastCGI 
-Developer's Kit document</a>. Here's what the Tcl version looks like:
-<p>
-
-<pre>
-#!./tclsh
-set count 0 
-while {[FCGI_Accept] &gt;= 0 } {
-    incr count
-    puts -nonewline "Content-type: text/html\r\n\r\n"
-    puts "&lt;title&gt;FastCGI Hello! (Tcl)&lt;/title&gt;"
-    puts "&lt;h1&gt;FastCGI Hello! (Tcl)&lt;/h1&gt;"
-    puts "Request number $count running on host &lt;i&gt;$env(SERVER_NAME)&lt;/i&gt;"
-}
-</pre>
-
-If you've built Tcl according to the recipe and you have a Web server
-set up to run FastCGI applications, load the FastCGI Developer's Kit
-Index Page in that server and run this Tcl application now.<p>
-
-The script invokes Tcl indirectly via the symbolic link
-<tt>examples/tclsh</tt>.  It does this because HP-UX has a limit of 32
-characters for the first line of a command-interpreter file such as
-<tt>examples/tiny-tcl-fcgi</tt>.  If you run on HP-UX you won't want
-to sprinkle symbolic links to <tt>tclsh</tt> everywhere, so you should install
-<tt>tclsh</tt> with a shorter pathname than
-<tt>/usr/local/tcl7.4-fcgi/bin/tclsh7.4</tt>.<p>
-
-The Tcl command <tt>FCGI_Accept</tt> treats the initial
-environment differently than the C function <tt>FCGI_Accept</tt>.  The
-first call to the
-C function <tt>FCGI_Accept</tt> replaces the initial environment with
-the environment of the first request.  The first call to the Tcl command
-<tt>FCGI_Accept</tt> adds the variable bindings of the first request
-to the bindings present in the initial environment.  So when the first
-call to <tt>FCGI_Accept</tt> returns, bindings from the initial
-environment are still there (unless, due to naming conflicts, some of
-them have been overwritten by the first request).  The next call to
-<tt>FCGI_Accept</tt> removes the bindings made on the previous call
-before adding a new set for the request just accepted, again preserving
-the initial environment.<p>
-
-The FastCGI-integrated <tt>tclsh</tt> also includes
-commands <tt>FCGI_Finish</tt>, <tt>FCGI_SetExitStatus</tt>,
-and <tt>FCGI_StartFilterData</tt> that correspond to
-C functions in <tt>fcgi_stdio.h</tt>; see the manpages for
-full information.<p>
-
-Converting a Tcl CGI application to FastCGI is not fundamentally
-different from converting a C CGI application.  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 <tt>FCGI_Accept</tt>.<p>
-
-<HR>
-<ADDRESS><A HREF="mailto:shanzer@openmarket.com">Mike Shanzer // shanzer@openmarket.com</A></ADDRESS>
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
+<HTML>\r
+   <HEAD>\r
+      <TITLE>\r
+         Integrating FastCGI with Tcl\r
+      </TITLE>\r
+<STYLE TYPE="text/css">\r
+ body {\r
+  background-color: #FFFFFF;\r
+  color: #000000;\r
+ }\r
+ :link { color: #cc0000 }\r
+ :visited { color: #555555 }\r
+ :active { color: #000011 }\r
+ h5.c3 {text-align: center}\r
+ p.c2 {text-align: center}\r
+ div.c1 {text-align: center}\r
+</STYLE>\r
+   </HEAD>\r
+   <BODY>\r
+      <DIV CLASS="c1">\r
+         <A HREF="http://fastcgi.com"><IMG BORDER="0" SRC="../images/fcgi-hd.gif" ALT="[[FastCGI]]"></A>\r
+      </DIV>\r
+      <BR CLEAR="all">\r
+      <DIV CLASS="c1">\r
+         <H3>\r
+            Integrating FastCGI with Tcl\r
+         </H3>\r
+      </DIV>\r
+      <!--Copyright (c) 1996 Open Market, Inc.                                    -->\r
+      <!--See the file "LICENSE.TERMS" for information on usage and redistribution-->\r
+      <!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->\r
+      <P CLASS="c2">\r
+         Michael S. Shanzer<BR>\r
+         Open Market, Inc.<BR>\r
+         <EM>19 January 1995</EM>\r
+      </P>\r
+      <H5 CLASS="c3">\r
+         Copyright &copy; 1996 Open Market, Inc. 245 First Street, Cambridge, MA 02142 U.S.A.<BR>\r
+         Tel: 617-621-9500 Fax: 617-621-1703 URL: <A HREF=\r
+         "http://www.openmarket.com/">http://www.openmarket.com/</A><BR>\r
+         $Id: fcgi-tcl.htm,v 1.3 2001/11/27 01:03:47 robs Exp $<BR>\r
+      </H5>\r
+      <HR>\r
+      <H3>\r
+         <A NAME="S1">1. Introduction</A>\r
+      </H3>\r
+      <P>\r
+         Tcl (tool command language) is an embeddable scripting language that&#39;s often used for CGI programming. Tcl\r
+         is freely available as a source kit.\r
+      </P>\r
+      <P>\r
+         We&#39;ve built a Tcl interpreter that runs as a FastCGI application. Our purpose in doing so was twofold:\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            <I>Create a useful artifact.</I> Open Market has written many CGI applications using Tcl. Now we&#39;d like\r
+            to turn them into FastCGI applications.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <I>Demonstrate how easy it is to integrate FastCGI with an existing program.</I> The Tcl interpreter is a\r
+            substantial program, so integrating FastCGI with the Tcl interpreter is a good test of the\r
+            <TT>fcgi_stdio</TT> compatability library.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         We&#39;ve succeeded on both counts. We now have a platform for migrating our Tcl-based CGI applications to\r
+         FastCGI. And the integration required a very small effort. The only source code change to the Tcl interpreter\r
+         was the routine addition of a handful of new commands: <TT>FCGI_Accept</TT>, <TT>FCGI_Finish</TT>,\r
+         <TT>FCGI_SetExitStatus</TT>, and <TT>FCGI_StartFilterData</TT>.\r
+      </P>\r
+      <P>\r
+         The FastCGI-integrated Tcl interpreter works as usual when run from a shell or as a CGI program. You don&#39;t\r
+         need two Tcls, one for FastCGI and one for other uses.\r
+      </P>\r
+      <P>\r
+         The remainder of this document gives a recipe you can follow to build FastCGI into Tcl, explains what&#39;s\r
+         happening in the recipe, and illustrates the use of FastCGI Tcl with an example program.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <H3>\r
+         <A NAME="S2">2. Recipe</A>\r
+      </H3>\r
+      <P>\r
+         Here are the assumptions embedded in the following recipe:\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            You are building Tcl 7.4p3, the current stable Tcl release as this is written. You unpack the Tcl kit into\r
+            a directory <TT>tcl7.4</TT> that&#39;s a sibling of the FastCGI kit directory <TT>fcgi-devel-kit</TT>.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            You have gcc version 2.7 installed on your system, and use it in the build. gcc is convenient because it\r
+            supports the <TT>-include</TT> command-line option that instructs the C preprocessor to include a specific\r
+            file before processing any other include files. This allows you to include <TT>fcgi_stdio.h</TT> without\r
+            modifying Tcl source files. (The reason for specifying gcc version 2.7 is that I have experienced bad\r
+            behavior with an earlier version and the <TT>-include</TT> flag -- the C preprocessor died with SIGABRT.)\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            You have GNU autoconf installed on your system. If you don&#39;t have GNU autoconf, you will have to make\r
+            certain edits by hand and repeat these edits for each build platform.<BR>\r
+            <BR>\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         If those are valid assumptions, follow these steps:\r
+      </P>\r
+      <OL>\r
+         <LI>\r
+            <I>Build the FastCGI Developer&#39;s Kit.</I> Tcl needs to link against <TT>libfcgi.a</TT>, so <A HREF=\r
+            "fcgi-devel-kit.htm#S2">build the FastCGI Developer&#39;s Kit</A> in order to create this library for your\r
+            platform.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <I>Pull the Tcl 7.4p3 kit.</I> You&#39;ll need the files <A HREF=\r
+            "ftp://ftp.smli.com/pub/tcl/tcl7.4.tar.Z">tcl7.4.tar.Z</A>, <A HREF=\r
+            "ftp://ftp.smli.com/pub/tcl/tcl7.4p1.patch.gz">tcl7.4p1.patch.gz</A>, <A HREF=\r
+            "ftp://ftp.smli.com/pub/tcl/tcl7.4p2.patch.gz">tcl7.4p2.patch.gz</A>, and <A HREF=\r
+            "ftp://ftp.smli.com/pub/tcl/tcl7.4p3.patch.gz">tcl7.4p3.patch.gz</A>. (Some older Netscape browsers\r
+            can&#39;t perform these retrievals because of a protocol conflict between Netscape and Sun&#39;s firewall.)\r
+            <P>\r
+               Unpack the tar file in the parent directory of the FastCGI kit directory you used in the previous step,\r
+               so that the directories <TT>tcl7.4</TT> and <TT>fcgi-devel-kit</TT> are siblings. After unpacking the\r
+               tar file, follow the directions in the <TT>README</TT> to apply the patches.\r
+            </P>\r
+            <P>\r
+               The <A HREF="http://www.sunlabs.com:80/research/tcl/">Sun Labs Tcl/Tk Project Page</A> contains a wealth\r
+               of information on Tcl, including up to date information on the latest kits.\r
+            </P>\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <I>Copy the files <TT>tclFCGI.c</TT>, <TT>tclAppInit.c</TT>, <TT>Makefile.in</TT>, and\r
+            <TT>configure.in</TT> from the FastCGI kit.</I> \r
+<PRE>\r
+    &gt; cd tcl7.4\r
+    &gt; mv tclAppInit.c tclAppInit.c.orig\r
+    &gt; mv Makefile.in.orig Makefile.in.orig.orig\r
+    &gt; mv Makefile.in Makefile.in.orig\r
+    &gt; mv configure.in configure.in.orig\r
+    &gt; cp ../fcgi-devel-kit/tcl/tcl7.4/* .\r
+    &gt; cp ../fcgi-devel-kit/tcl/common/* .\r
+</PRE>\r
+         </LI>\r
+         <LI>\r
+            <I>Create a new <TT>configure</TT> script.</I> \r
+<PRE>\r
+    &gt; autoconf\r
+</PRE>\r
+         </LI>\r
+         <LI>\r
+            <I>Configure and build.</I> \r
+<PRE>\r
+    &gt; ./configure\r
+    &gt; make\r
+</PRE>\r
+            The <TT>make</TT> creates the Tcl interpreter <TT>tclsh</TT> and library archive <TT>libtcl.a</TT> (for\r
+            embedding Tcl in your own C applications). The Tcl <TT>README</TT> file explains how you can experiment\r
+            with <TT>tclsh</TT> without installing it in a standard place.<BR>\r
+            <BR>\r
+         </LI>\r
+      </OL>\r
+      <H3>\r
+         <A NAME="S3">3. Recipe Explained</A>\r
+      </H3>\r
+      <P>\r
+         The recipe alone is fine if you are using Tcl 7.4p3, you have gcc version 2.7, and you have GNU autoconf. In\r
+         case one or more of these assumptions doesn&#39;t hold for you, and to illuminate how little work was involved\r
+         in integrating FastCGI, here&#39;s an explanation of how and why you would modify the files\r
+         <TT>tclAppInit.c</TT>, <TT>Makefile.in</TT>, and <TT>configure.in</TT> from the Tcl kit.\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            <TT>tclAppInit.c</TT>:\r
+            <P>\r
+            </P>\r
+            <UL>\r
+               <LI>\r
+                  Add the following three lines of code to the function <TT>Tcl_AppInit</TT> after the call to\r
+                  <TT>Tcl_Init</TT> and after the comment about calling init procedures: \r
+<PRE>\r
+    if (FCGI_Init(interp) == TCL_ERROR) {\r
+        return TCL_ERROR;\r
+    }\r
+</PRE>\r
+                  This registers four Tcl commands (<TT>FCGI_Accept</TT>, <TT>FCGI_Finish</TT>,\r
+                  <TT>FCGI_SetExitStatus</TT>, and <TT>FCGI_StartFilterData</TT>), implemented in <TT>tclFCGI.c</TT>,\r
+                  with the Tcl interpreter.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <TT>Makefile.in</TT>:\r
+            <P>\r
+            </P>\r
+            <UL>\r
+               <LI>\r
+                  Add <TT>tclFCGI.o</TT> to the <TT>GENERIC_OBJS</TT> variable, and add <TT>tclFCGI.c</TT> to the\r
+                  <TT>SRCS</TT> variable.\r
+                  <P>\r
+                     This builds the FastCGI Tcl commands and links them into the Tcl interpreter.\r
+                  </P>\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Add <TT>-I../fcgi-devel-kit/include -include ../fcgi-devel-kit/include/fcgi_stdio.h</TT> to the\r
+                  <TT>CFLAGS</TT> variable.\r
+                  <P>\r
+                     This includes <TT>fcgi_stdio.h</TT> when compiling C code for the Tcl interpreter, overriding the\r
+                     normal <TT>stdio</TT> types, variables, and functions.\r
+                  </P>\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Add <TT>../fcgi-devel-kit/libfcgi/libfcgi.a</TT> before the <TT>@LIBS@</TT> part of the <TT>LIBS</TT>\r
+                  variable.\r
+                  <P>\r
+                     This links the implementation of <TT>fcgi_stdio.h</TT> into the Tcl interpreter, for use by the\r
+                     <TT>FCGI_accept</TT> command and any code that uses <TT>stdio</TT> variables or calls\r
+                     <TT>stdio</TT> functions.\r
+                  </P>\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+            </UL>\r
+            <P>\r
+               The last two edits will vary if you use a compiler other than gcc or install the <TT>tcl7.4</TT>\r
+               directory somewhere else in relation to the <TT>fcgi-devel-kit</TT> directory.\r
+            </P>\r
+            <P>\r
+            </P>\r
+         </LI>\r
+         <LI>\r
+            <TT>configure.in</TT>:\r
+            <P>\r
+            </P>\r
+            <UL>\r
+               <LI>\r
+                  Replace the lines \r
+<PRE>\r
+AC_C_CROSS\r
+CC=${CC-cc}\r
+</PRE>\r
+                  with the lines \r
+<PRE>\r
+AC_PROG_CC\r
+AC_C_CROSS\r
+</PRE>\r
+                  This selects gcc in preference to other C compilers.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  Add the following lines just after the <TT>AC_SUBST(CC)</TT> line: \r
+<PRE>\r
+AC_CHECK_LIB(socket, main, [LIBS=&quot;$LIBS -lsocket&quot;])\r
+AC_CHECK_LIB(nsl, main, [LIBS=&quot;$LIBS -lnsl&quot;])\r
+AC_SUBST(LIBS)\r
+</PRE>\r
+                  This ensures that the socket libraries used by FastCGI are linked into the Tcl interpreter.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+            </UL>\r
+            If GNU autoconf is not available to you, you&#39;ll leave <TT>configure.in</TT> alone and perform the\r
+            following steps:\r
+            <P>\r
+            </P>\r
+            <UL>\r
+               <LI>\r
+                  Execute \r
+<PRE>\r
+    &gt; SETENV CC gcc\r
+</PRE>\r
+                  before running <TT>configure</TT>.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+               <LI>\r
+                  If you are running on a SVR4-derived Unix platform, edit <TT>Makefile</TT> to add <TT>-lsocket\r
+                  -lnsl</TT> to the <TT>LIBS</TT> value after running <TT>configure</TT>.\r
+                  <P>\r
+                  </P>\r
+               </LI>\r
+            </UL>\r
+            If you ever re-run <TT>configure</TT>, you&#39;ll need to repeat these steps.\r
+            <P>\r
+            </P>\r
+         </LI>\r
+      </UL>\r
+      <H3>\r
+         <A NAME="S4">4. Writing FastCGI applications in Tcl</A>\r
+      </H3>\r
+      <P>\r
+         The Tcl program <TT>tcl/tiny-tcl-fcgi</TT> performs the same function as the C program\r
+         <TT>examples/tiny-fcgi.c</TT> that&#39;s used as an example in the <A HREF="fcgi-devel-kit.htm#S3.1.1">FastCGI\r
+         Developer&#39;s Kit document</A>. Here&#39;s what the Tcl version looks like:\r
+      </P>\r
+      <P>\r
+      </P>\r
+<PRE>\r
+#!./tclsh\r
+set count 0 \r
+while {[FCGI_Accept] &gt;= 0 } {\r
+    incr count\r
+    puts -nonewline &quot;Content-type: text/html\r\n\r\n&quot;\r
+    puts &quot;&lt;title&gt;FastCGI Hello! (Tcl)&lt;/title&gt;&quot;\r
+    puts &quot;&lt;h1&gt;FastCGI Hello! (Tcl)&lt;/h1&gt;&quot;\r
+    puts &quot;Request number $count running on host &lt;i&gt;$env(SERVER_NAME)&lt;/i&gt;&quot;\r
+}\r
+</PRE>\r
+      <P>\r
+         If you&#39;ve built Tcl according to the recipe and you have a Web server set up to run FastCGI applications,\r
+         load the FastCGI Developer&#39;s Kit Index Page in that server and run this Tcl application now.\r
+      </P>\r
+      <P>\r
+         The script invokes Tcl indirectly via the symbolic link <TT>examples/tclsh</TT>. It does this because HP-UX\r
+         has a limit of 32 characters for the first line of a command-interpreter file such as\r
+         <TT>examples/tiny-tcl-fcgi</TT>. If you run on HP-UX you won&#39;t want to sprinkle symbolic links to\r
+         <TT>tclsh</TT> everywhere, so you should install <TT>tclsh</TT> with a shorter pathname than\r
+         <TT>/usr/local/tcl7.4-fcgi/bin/tclsh7.4</TT>.\r
+      </P>\r
+      <P>\r
+         The Tcl command <TT>FCGI_Accept</TT> treats the initial environment differently than the C function\r
+         <TT>FCGI_Accept</TT>. The first call to the C function <TT>FCGI_Accept</TT> replaces the initial environment\r
+         with the environment of the first request. The first call to the Tcl command <TT>FCGI_Accept</TT> adds the\r
+         variable bindings of the first request to the bindings present in the initial environment. So when the first\r
+         call to <TT>FCGI_Accept</TT> returns, bindings from the initial environment are still there (unless, due to\r
+         naming conflicts, some of them have been overwritten by the first request). The next call to\r
+         <TT>FCGI_Accept</TT> removes the bindings made on the previous call before adding a new set for the request\r
+         just accepted, again preserving the initial environment.\r
+      </P>\r
+      <P>\r
+         The FastCGI-integrated <TT>tclsh</TT> also includes commands <TT>FCGI_Finish</TT>,\r
+         <TT>FCGI_SetExitStatus</TT>, and <TT>FCGI_StartFilterData</TT> that correspond to C functions in\r
+         <TT>fcgi_stdio.h</TT>; see the manpages for full information.\r
+      </P>\r
+      <P>\r
+         Converting a Tcl CGI application to FastCGI is not fundamentally different from converting a C CGI\r
+         application. You separate the portion of the application that performs one-time initialization from the\r
+         portion that performs per-request processing. You put the per-request processing into a loop controlled by\r
+         <TT>FCGI_Accept</TT>.\r
+      </P>\r
+      <P>\r
+      </P>\r
+      <HR>\r
+      <ADDRESS>\r
+         <A HREF="mailto:shanzer@openmarket.com">Mike Shanzer // shanzer@openmarket.com</A>\r
+      </ADDRESS>\r
+   </BODY>\r
+</HTML>\r
+\r
index ac78048..3afa216 100644 (file)
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<HTML>
-   <HEAD>
-      <TITLE>
-         FastCGI Developer&#39;s Kit Index Page
-      </TITLE>
-<STYLE TYPE="text/css">
- div.c1 {text-align: center}
-</STYLE>
-   </HEAD>
-   <BODY>
-      <DIV CLASS="c1">
-         <H2>
-            FastCGI Developer&#39;s Kit
-         </H2>
-      </DIV>
-      <!--Copyright (c) 1996 Open Market, Inc.                                    -->
-      <!--See the file "LICENSE.TERMS" for information on usage and redistribution-->
-      <!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->
-      <!-- $Id: overview.html,v 1.2 2001/09/22 17:42:44 robs Exp $ -->
-      <UL>
-         <LI>
-            <A HREF=".">doc</A> 
-            <UL>
-               <LI>
-                  <A HREF="fastcgi-whitepaper/fastcgi.htm">FastCGI Technical White Paper</A> Motivates FastCGI, then
-                  explains the FastCGI interface, FastCGI application roles, the FastCGI application library, server
-                  support for FastCGI, and FastCGI performance.
-               </LI>
-               <LI>
-                  <A HREF="fcgi-perf.htm">Understanding FastCGI Application Performance</A> Why FastCGI applications
-                  often run faster than applications coded directly to Web server APIs.
-               </LI>
-               <LI>
-                  <A HREF="fcgi-devel-kit.htm">FastCGI Developer&#39;s Kit</A><BR>
-                   
-                  <UL>
-                     <LI>
-                        How to configure and build the kit for your development platform.
-                     </LI>
-                     <LI>
-                        How to write applications using the libraries in the kit.
-                     </LI>
-                     <LI>
-                        Documents <TT>cgi-fcgi</TT>, a tool in the kit that allows you to develop and test FastCGI
-                        applications using a Web server that lacks FastCGI support.
-                     </LI>
-                  </UL>
-               </LI>
-               <LI>
-                  <A HREF="fastcgi-prog-guide/cover.htm">Open Market FastCGI 1.0 Programmer&#39;s Guide</A>
-                  Programmer-oriented documentation for developers of applications that run on the Open Market&#39;s
-                  Secure WebServer 2.0. The content overlaps considerably with Section 3 of the Developer&#39;s Kit
-                  document.
-               </LI>
-               <LI>
-                  <A HREF="FCGI_Accept.3">FCGI_Accept.3</A>, <A HREF="FCGI_Finish.3">FCGI_Finish.3</A>, <A HREF=
-                  "FCGI_SetExitStatus.3">FCGI_SetExitStatus.3</A>, <A HREF=
-                  "FCGI_StartFilterData.3">FCGI_StartFilterData.3</A>, and <A HREF="cgi-fcgi.1">cgi-fcgi.1</A>
-                  manpages.
-               </LI>
-               <LI>
-                  <A HREF="fcgi-perl.htm">Integrating FastCGI with Perl</A> How to build FastCGI support into the Perl
-                  interpreter and how to write FastCGI applications in Perl.
-               </LI>
-               <LI>
-                  <A HREF="fcgi-tcl.htm">Integrating FastCGI with Tcl</A> How to build FastCGI support into the Tcl
-                  interpreter and how to write FastCGI applications in Tcl.
-               </LI>
-               <LI>
-                  <A HREF="fcgi-java.htm">Integrating FastCGI with Java</A> How to build Web server applications in
-                  Java using FastCGI.
-               </LI>
-               <LI>
-                  <A HREF="www5-api-workshop.html">FastCGI: A High-Performance Gateway Interface</A> Position paper
-                  presented at the workshop &quot;Programming the Web -- a search for APIs&quot;, Fifth International
-                  World Wide Web Conference, 6 May 1996, Paris, France. A short paper, addressed to an audience of
-                  technical specialists.
-               </LI>
-               <LI>
-                  <A HREF="fcgi-spec.html">FastCGI Specification</A> document.<BR>
-                   Defines the interface between a FastCGI application and a Web server that supports FastCGI. This is
-                  dry stuff, not needed for writing applications!
-               </LI>
-            </UL>
-         </LI>
-         <LI>
-            <A HREF="../include">include</A> .h files for the FastCGI libraries.
-         </LI>
-         <LI>
-            <A HREF="../libfcgi">libfcgi</A> .c files for the FastCGI libraries.
-         </LI>
-         <LI>
-            <A HREF="../examples">examples</A> Several example FastCGI programs.
-         </LI>
-         <LI>
-            <A HREF="../perl">perl</A> The FastCGI Perl module, FCGI.pm.
-         </LI>
-         <LI>
-            <A HREF="../java">java</A> The FastCGI Java library.
-         </LI>
-         <LI>
-            <A HREF="../cgi-fcgi">cgi-fcgi</A> The CGI-to-FastCGI bridge source code.
-         </LI>
-      </UL>
-      <HR>
-      <ADDRESS>
-         &copy; 1996, Open Market, Inc.
-      </ADDRESS>
-   </BODY>
-</HTML>
-
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r
+<HTML>\r
+   <HEAD>\r
+      <TITLE>\r
+         FastCGI Developer&#39;s Kit Index Page\r
+      </TITLE>\r
+<STYLE TYPE="text/css">\r
+ div.c1 {text-align: center}\r
+</STYLE>\r
+   </HEAD>\r
+   <BODY>\r
+      <DIV CLASS="c1">\r
+         <H2>\r
+            FastCGI Developer&#39;s Kit\r
+         </H2>\r
+      </DIV>\r
+      <!--Copyright (c) 1996 Open Market, Inc.                                    -->\r
+      <!--See the file "LICENSE.TERMS" for information on usage and redistribution-->\r
+      <!--of this file, and for a DISCLAIMER OF ALL WARRANTIES.                   -->\r
+      <!-- $Id: overview.html,v 1.3 2001/11/27 01:03:47 robs Exp $ -->\r
+      <UL>\r
+         <LI>\r
+            <A HREF=".">doc</A> \r
+            <UL>\r
+               <LI>\r
+                  <A HREF="fastcgi-whitepaper/fastcgi.htm">FastCGI Technical White Paper</A> Motivates FastCGI, then\r
+                  explains the FastCGI interface, FastCGI application roles, the FastCGI application library, server\r
+                  support for FastCGI, and FastCGI performance.\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="fcgi-perf.htm">Understanding FastCGI Application Performance</A> Why FastCGI applications\r
+                  often run faster than applications coded directly to Web server APIs.\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="fcgi-devel-kit.htm">FastCGI Developer&#39;s Kit</A><BR>\r
+                   \r
+                  <UL>\r
+                     <LI>\r
+                        How to configure and build the kit for your development platform.\r
+                     </LI>\r
+                     <LI>\r
+                        How to write applications using the libraries in the kit.\r
+                     </LI>\r
+                     <LI>\r
+                        Documents <TT>cgi-fcgi</TT>, a tool in the kit that allows you to develop and test FastCGI\r
+                        applications using a Web server that lacks FastCGI support.\r
+                     </LI>\r
+                  </UL>\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="fastcgi-prog-guide/cover.htm">Open Market FastCGI 1.0 Programmer&#39;s Guide</A>\r
+                  Programmer-oriented documentation for developers of applications that run on the Open Market&#39;s\r
+                  Secure WebServer 2.0. The content overlaps considerably with Section 3 of the Developer&#39;s Kit\r
+                  document.\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="FCGI_Accept.3">FCGI_Accept.3</A>, <A HREF="FCGI_Finish.3">FCGI_Finish.3</A>, <A HREF=\r
+                  "FCGI_SetExitStatus.3">FCGI_SetExitStatus.3</A>, <A HREF=\r
+                  "FCGI_StartFilterData.3">FCGI_StartFilterData.3</A>, and <A HREF="cgi-fcgi.1">cgi-fcgi.1</A>\r
+                  manpages.\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="fcgi-perl.htm">Integrating FastCGI with Perl</A> How to build FastCGI support into the Perl\r
+                  interpreter and how to write FastCGI applications in Perl.\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="fcgi-tcl.htm">Integrating FastCGI with Tcl</A> How to build FastCGI support into the Tcl\r
+                  interpreter and how to write FastCGI applications in Tcl.\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="fcgi-java.htm">Integrating FastCGI with Java</A> How to build Web server applications in\r
+                  Java using FastCGI.\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="www5-api-workshop.html">FastCGI: A High-Performance Gateway Interface</A> Position paper\r
+                  presented at the workshop &quot;Programming the Web -- a search for APIs&quot;, Fifth International\r
+                  World Wide Web Conference, 6 May 1996, Paris, France. A short paper, addressed to an audience of\r
+                  technical specialists.\r
+               </LI>\r
+               <LI>\r
+                  <A HREF="fcgi-spec.html">FastCGI Specification</A> document.<BR>\r
+                   Defines the interface between a FastCGI application and a Web server that supports FastCGI. This is\r
+                  dry stuff, not needed for writing applications!\r
+               </LI>\r
+            </UL>\r
+         </LI>\r
+         <LI>\r
+            <A HREF="../include/">include</A> .h files for the FastCGI libraries.\r
+         </LI>\r
+         <LI>\r
+            <A HREF="../libfcgi/">libfcgi</A> .c files for the FastCGI libraries.\r
+         </LI>\r
+         <LI>\r
+            <A HREF="../examples/">examples</A> Several example FastCGI programs.\r
+         </LI>\r
+         <LI>\r
+            <A HREF="../perl/">perl</A> The FastCGI Perl module, FCGI.pm.\r
+         </LI>\r
+         <LI>\r
+            <A HREF="../java/">java</A> The FastCGI Java library.\r
+         </LI>\r
+         <LI>\r
+            <A HREF="../cgi-fcgi/">cgi-fcgi</A> The CGI-to-FastCGI bridge source code.\r
+         </LI>\r
+      </UL>\r
+      <HR>\r
+      <ADDRESS>\r
+         &copy; 1996, Open Market, Inc.\r
+      </ADDRESS>\r
+   </BODY>\r
+</HTML>\r
+\r
index 13d005f..5d4fef6 100644 (file)
-<html>
-<head>
-<title>FastCGI: A High-Performance Gateway Interface</title>
-</head>
-
-<body>
-<center>
-<h2>FastCGI: A High-Performance Gateway Interface</h2>
-Position paper for the workshop
-"Programming the Web - a search for APIs",<br>
-Fifth International World Wide Web Conference,
-6 May 1996, Paris, France.<br>
-<p>
-Mark R. Brown<br>
-Open Market, Inc.<br>
-<p>
-
-2 May 1996<br>
-</center>
-<p>
-
-<h5 align=center>
-Copyright &copy; 1996 Open Market, Inc.  245 First Street, Cambridge,
-  MA 02142 U.S.A.<br>
-Tel: 617-621-9500 Fax: 617-621-1703 URL:
-  <a href="http://www.openmarket.com/">http://www.openmarket.com/</a><br>
-</h5>
-<hr>
-
-
-<H3>Abstract</H3>
-
-FastCGI is a fast, open, and secure Web server interface that
-solves the performance problems inherent in CGI without
-introducing any of the new problems associated with writing applications
-to lower-level Web server APIs.  Modules to support FastCGI can
-be plugged into Web server APIs such as Apache API, NSAPI, and ISAPI.
-Key considerations in designing FastCGI included minimizing the cost of
-migrating CGI applications (including applications written in popular
-scripting languages such as Perl), supporting both single-threaded and
-multi-threaded application programming, supporting distributed configurations
-for scaling and high availability, and generalizing the roles that
-gateway applications can play beyond CGI's "responder" role.<p>
-
-For more information on FastCGI, including an interface specification
-and a module for the Apache server, visit the
-<a href = "http://www.fastcgi.com/">www.fastcgi.com Web site</a>.
-
-
-<H3>1. Introduction</H3>
-
-The surge in the use of the Web by business has created great demand
-for applications that create dynamic content.  These applications
-allow businesses to deliver products, services, and messages whose
-shape and content are influenced by interaction with and knowledge
-of users.
-
-<P> This move towards dynamic Web content has highlighted the performance
-limits of CGI (Common Gateway Interface).  In response there has been
-a proliferation of Web server APIs.  These APIs address some (though
-not all) of the performance problems with CGI, but are not designed to
-meet the need of business applications.  When applied to business
-applications, Web server APIs suffer from these problems:
-
-<UL>
-<LI><B>Complexity.</B>
-  Server APIs introduce a steep learning curve, with increased
-  implementation and maintenance costs.
-<LI><B>Language dependence.</B>
-  Applications have to be written in a language supported by the
-  server API (usually C/C++).  Perl, the most popular language for
-  CGI programs, can't be used with any existing server API.
-<LI><B>No process isolation.</B>
-  Since the applications run in the server's address space, buggy
-  applications can corrupt the core server (or each other).  A
-  malicious or buggy application can compromise server security, and
-  bugs in the core server can corrupt applications.
-<LI><B>Proprietary.</B>
-  Coding your application to a particular API locks you into a
-  particular server.
-<LI><B>Tie-in to server architecture.</B>
-  API applications have to share the same architecture as the server:
-  If the Web server is multi-threaded, the application has to be
-  thread-safe.  If the Web server has single-threaded processes,
-  multi-threaded applications don't gain any performance advantage.
-  Also, when the server's architecture changes, the API
-  will usually have to change, and applications will have to be
-  adapted or rewritten.
-</UL>
-
-Web server APIs are suitable for applications that require an intimate
-connection to the core Web server, such as security protocols.  But
-using a Web server API for a Web business application would be much
-like using an old-fashioned TP monitor, which required linking
-applications right into the monitor, for a modern business transaction
-processing application.  The old-fashioned solution suffers a huge
-development and maintenance cost penalty because it ignores 30 years
-of progress in computing technology, and may end up
-providing inferior performance to boot.  Nobody uses the old technology
-unless they are already locked into it.
-
-<p> FastCGI is best viewed as a new implementation of CGI,
-designed to overcome CGI's performance problems.  The major
-implementation differences are:
-
-<UL>
-  <LI>FastCGI processes are persistent: after finishing a request,
-  they wait for a new request instead of exiting.
-
-  <LI>Instead of using operating system environment variables and
-  pipes, the FastCGI protocol multiplexes the environment information,
-  standard input, output, and error over a single full-duplex
-  connection.  This allows FastCGI programs to run on remote machines,
-  using TCP connections between the Web server and the FastCGI
-  application.
-</UL>
-
-<p> FastCGI communicates the exact same information as CGI in a
-different way.  Because FastCGI <i>is</i> CGI, and like CGI runs
-applications in separate processes, it suffers none of the server API
-problems listed above.
-
-
-<H3>2. Migration from CGI</H3>
-
-Open Market has developed a FastCGI application library
-that implements the FastCGI protocol, hiding the protocol details
-from the developer. This library, which is freely available,
-makes writing FastCGI programs
-as easy as writing CGI applications.
-
-<P> The application library provides replacements for the C language
-standard I/O (stdio) routines such as <TT>printf()</TT> and
-<TT>gets()</TT>.  The library converts references to environment
-variables, standard input,
-standard output, and standard error to the FastCGI protocol.
-References to other files &quot;fall through&quot; to the underlying
-operating system standard I/O routines.  This approach has several benefits:
-
-<UL>
-  <LI>Developers don't have to learn a new API to develop FastCGI
-  applications.
-
-  <LI>Existing CGI programs can be migrated with minimal
-  source changes.
-
-  <LI>FastCGI interpreters for Perl, Tcl, and other interpreted
-  languages can be built without modifying the interpreter source
-  code.
-</UL>
-
-<P>
-Here's a simple FastCGI application:<P>
-<PRE>
-    #include &lt;fcgi_stdio.h&gt;
-
-    void main(void)
-    {
-        int count = 0;
-        while(FCGI_Accept() &gt;= 0) {
-            printf("Content-type: text/html\r\n");
-            printf("\r\n");
-            printf("Hello world!&lt;br&gt;\r\n");
-            printf("Request number %d.", count++);
-        }
-        exit(0);
-    }
-</PRE>
-This application returns a &quot;Hello world&quot;
-HTML response to the client.  It also keeps a counter of the number
-of times it has been accessed, displaying the value of the counter
-at each request.  The <TT>fcgi_stdio.h</TT>
-header file provides the FastCGI replacement routines for the
-C standard I/O library.  The <TT>FCGI_Accept()</TT>
-routine accepts a new request from the Web server.</FONT>
-
-<p> The application library was designed to make migration
-of existing CGI programs as simple as possible.  Many applications
-can be converted by adding a loop around the main request processing
-code and recompiling with the FastCGI application library.
-To ease migration to FastCGI, executables built with
-the application library can run as either CGI or FastCGI programs,
-depending on how they are invoked.  The library detects the execution
-environment and automatically selects FastCGI or regular I/O routines,
-as appropriate.
-
-<P> Applications written in Perl, Tcl, and other scripting
-languages can be migrated by using a language interpreter built
-with the application library.  FastCGI-integrated Tcl and Perl
-interpreters for popular Unix platforms are available from
-the <i>www.fastcgi.com</i> Web site.  The interpreters are
-backward-compatible:  They can run standard Tcl and Perl applications.
-
-
-<H3>3. Single-threaded and multi-threaded applications</H3>
-
-FastCGI gives developers a free choice of whether to develop
-applications in a single-threaded or multi-threaded style.
-The FastCGI interface supports multi-threading in two ways:
-
-<ul>
-  <li> Applications can accept concurrent Web server connections
-  to provide concurrent requests to multiple application threads.
-
-  <li> Applications can accept multiplexed Web server connections,
-  in which concurrent requests are communicated over a single
-  connection to multiple application threads.
-</ul>
-
-<p> Multi-threaded programming is complex -- concurrency makes
-programs difficult to test and debug -- so many developers will prefer
-to program in the familiar single-threaded style.  By having several
-concurrent processes running the same application it is often possible
-to achieve high performance with single-threaded programming.
-
-<p> The FastCGI interface allows Web servers to implement <i>session
-affinity</i>, a feature that allows applications to maintain
-caches of user-related data.  With session affinity, when several
-concurrent processes are running the same application, the Web
-server routes all requests from a particular user to the same
-application process.  Web server APIs don't provide this functionality
-to single-threaded applications, so the performance of an API-based
-application is often inferior to the performance of the
-corresponding FastCGI application.
-
-
-<H3>4. Distributed FastCGI</H3>
-
-Because FastCGI can communicate over TCP/IP connections, it supports
-configurations in which applications run remotely from
-the Web server.  This can provide scaling, load balancing,
-high availability, and connections to systems that don't have
-Web servers.
-
-<p> Distributed FastCGI can also provide security advantages.
-A Web server outside a corporate firewall can communicate
-through the firewall to internal databases.  For instance,
-an application might need to authenticate incoming users
-as customers in order to give access to certain documents
-on the external Web site.  With FastCGI this authentication
-can be done without replicating data and without compromising
-security.
-
-
-<H3>5. Roles</H3>
-
-A problem with CGI is its limited functionality:
-CGI programs can only provide responses to requests. 
-FastCGI provides expanded functionality with support for three
-different application &quot;roles&quot;:
-<UL>
-
-  <LI><B>Responder.</B> This is the basic FastCGI role, and
-  corresponds to the simple functionality offered by CGI today.
-
-  <LI><B>Filter.</B> The FastCGI application filters the requested Web
-  server file before sending it to the client.
-
-  <LI><B>Authorizer.</B> The FastCGI program performs an access
-  control decision for the request (such as performing a
-  username/password database lookup).
-
-</UL>
-
-<P>
-Other roles will be defined in the future.  For instance,
-a &quot;logger&quot; role would be useful, where the FastCGI program
-would receive the server's log entries for real-time processing
-and analysis.
-
-
-<H3>6. Conclusions</H3>
-
-<P>Today's Web business applications need a platform that's fast,
-open, maintainable, straightforward, stable, and secure.  FastCGI's
-design meets these requirements, and provides a logical migration
-path from the proven and widely deployed CGI technology.  This allows
-developers to take advantage of FastCGI's benefits without losing
-their existing investment in CGI applications.
-
-<P>For more information about FastCGI, visit the
-<a href = "http://www.fastcgi.com/">www.fastcgi.com Web site</a>.
-
-
-</BODY>
-</HTML>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
+<HTML>\r
+   <HEAD>\r
+      <TITLE>\r
+         FastCGI: A High-Performance Gateway Interface\r
+      </TITLE>\r
+<STYLE TYPE="text/css">\r
+ h5.c2 {text-align: center}\r
+ div.c1 {text-align: center}\r
+</STYLE>\r
+   </HEAD>\r
+   <BODY>\r
+      <DIV CLASS="c1">\r
+         <H2>\r
+            FastCGI: A High-Performance Gateway Interface\r
+         </H2>\r
+         Position paper for the workshop &quot;Programming the Web - a search for APIs&quot;,<BR>\r
+         Fifth International World Wide Web Conference, 6 May 1996, Paris, France.<BR>\r
+         <P>\r
+            Mark R. Brown<BR>\r
+            Open Market, Inc.<BR>\r
+         </P>\r
+         <P>\r
+            2 May 1996<BR>\r
+         </P>\r
+      </DIV>\r
+      <P>\r
+      </P>\r
+      <H5 CLASS="c2">\r
+         Copyright &copy; 1996 Open Market, Inc. 245 First Street, Cambridge, MA 02142 U.S.A.<BR>\r
+         Tel: 617-621-9500 Fax: 617-621-1703 URL: <A HREF=\r
+         "http://www.openmarket.com/">http://www.openmarket.com/</A><BR>\r
+      </H5>\r
+      <HR>\r
+      <H3>\r
+         Abstract\r
+      </H3>\r
+      <P>\r
+         FastCGI is a fast, open, and secure Web server interface that solves the performance problems inherent in CGI\r
+         without introducing any of the new problems associated with writing applications to lower-level Web server\r
+         APIs. Modules to support FastCGI can be plugged into Web server APIs such as Apache API, NSAPI, and ISAPI. Key\r
+         considerations in designing FastCGI included minimizing the cost of migrating CGI applications (including\r
+         applications written in popular scripting languages such as Perl), supporting both single-threaded and\r
+         multi-threaded application programming, supporting distributed configurations for scaling and high\r
+         availability, and generalizing the roles that gateway applications can play beyond CGI&#39;s\r
+         &quot;responder&quot; role.\r
+      </P>\r
+      <P>\r
+         For more information on FastCGI, including an interface specification and a module for the Apache server,\r
+         visit the <A HREF="http://www.fastcgi.com/">www.fastcgi.com Web site</A>.\r
+      </P>\r
+      <H3>\r
+         1. Introduction\r
+      </H3>\r
+      <P>\r
+         The surge in the use of the Web by business has created great demand for applications that create dynamic\r
+         content. These applications allow businesses to deliver products, services, and messages whose shape and\r
+         content are influenced by interaction with and knowledge of users.\r
+      </P>\r
+      <P>\r
+         This move towards dynamic Web content has highlighted the performance limits of CGI (Common Gateway\r
+         Interface). In response there has been a proliferation of Web server APIs. These APIs address some (though not\r
+         all) of the performance problems with CGI, but are not designed to meet the need of business applications.\r
+         When applied to business applications, Web server APIs suffer from these problems:\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            <B>Complexity.</B> Server APIs introduce a steep learning curve, with increased implementation and\r
+            maintenance costs.\r
+         </LI>\r
+         <LI>\r
+            <B>Language dependence.</B> Applications have to be written in a language supported by the server API\r
+            (usually C/C++). Perl, the most popular language for CGI programs, can&#39;t be used with any existing\r
+            server API.\r
+         </LI>\r
+         <LI>\r
+            <B>No process isolation.</B> Since the applications run in the server&#39;s address space, buggy\r
+            applications can corrupt the core server (or each other). A malicious or buggy application can compromise\r
+            server security, and bugs in the core server can corrupt applications.\r
+         </LI>\r
+         <LI>\r
+            <B>Proprietary.</B> Coding your application to a particular API locks you into a particular server.\r
+         </LI>\r
+         <LI>\r
+            <B>Tie-in to server architecture.</B> API applications have to share the same architecture as the server:\r
+            If the Web server is multi-threaded, the application has to be thread-safe. If the Web server has\r
+            single-threaded processes, multi-threaded applications don&#39;t gain any performance advantage. Also, when\r
+            the server&#39;s architecture changes, the API will usually have to change, and applications will have to\r
+            be adapted or rewritten.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         Web server APIs are suitable for applications that require an intimate connection to the core Web server, such\r
+         as security protocols. But using a Web server API for a Web business application would be much like using an\r
+         old-fashioned TP monitor, which required linking applications right into the monitor, for a modern business\r
+         transaction processing application. The old-fashioned solution suffers a huge development and maintenance cost\r
+         penalty because it ignores 30 years of progress in computing technology, and may end up providing inferior\r
+         performance to boot. Nobody uses the old technology unless they are already locked into it.\r
+      </P>\r
+      <P>\r
+         FastCGI is best viewed as a new implementation of CGI, designed to overcome CGI&#39;s performance problems.\r
+         The major implementation differences are:\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            FastCGI processes are persistent: after finishing a request, they wait for a new request instead of\r
+            exiting.\r
+         </LI>\r
+         <LI>\r
+            Instead of using operating system environment variables and pipes, the FastCGI protocol multiplexes the\r
+            environment information, standard input, output, and error over a single full-duplex connection. This\r
+            allows FastCGI programs to run on remote machines, using TCP connections between the Web server and the\r
+            FastCGI application.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         FastCGI communicates the exact same information as CGI in a different way. Because FastCGI <I>is</I> CGI, and\r
+         like CGI runs applications in separate processes, it suffers none of the server API problems listed above.\r
+      </P>\r
+      <H3>\r
+         2. Migration from CGI\r
+      </H3>\r
+      <P>\r
+         Open Market has developed a FastCGI application library that implements the FastCGI protocol, hiding the\r
+         protocol details from the developer. This library, which is freely available, makes writing FastCGI programs\r
+         as easy as writing CGI applications.\r
+      </P>\r
+      <P>\r
+         The application library provides replacements for the C language standard I/O (stdio) routines such as\r
+         <TT>printf()</TT> and <TT>gets()</TT>. The library converts references to environment variables, standard\r
+         input, standard output, and standard error to the FastCGI protocol. References to other files &quot;fall\r
+         through&quot; to the underlying operating system standard I/O routines. This approach has several benefits:\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            Developers don&#39;t have to learn a new API to develop FastCGI applications.\r
+         </LI>\r
+         <LI>\r
+            Existing CGI programs can be migrated with minimal source changes.\r
+         </LI>\r
+         <LI>\r
+            FastCGI interpreters for Perl, Tcl, and other interpreted languages can be built without modifying the\r
+            interpreter source code.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         Here&#39;s a simple FastCGI application:\r
+      </P>\r
+      <BR>\r
+      <BR>\r
+<PRE>\r
+    #include &lt;fcgi_stdio.h&gt;\r
+\r
+    void main(void)\r
+    {\r
+        int count = 0;\r
+        while(FCGI_Accept() &gt;= 0) {\r
+            printf(&quot;Content-type: text/html\r\n&quot;);\r
+            printf(&quot;\r\n&quot;);\r
+            printf(&quot;Hello world!&lt;br&gt;\r\n&quot;);\r
+            printf(&quot;Request number %d.&quot;, count++);\r
+        }\r
+        exit(0);\r
+    }\r
+</PRE>\r
+      <P>\r
+         This application returns a &quot;Hello world&quot; HTML response to the client. It also keeps a counter of the\r
+         number of times it has been accessed, displaying the value of the counter at each request. The\r
+         <TT>fcgi_stdio.h</TT> header file provides the FastCGI replacement routines for the C standard I/O library.\r
+         The <TT>FCGI_Accept()</TT> routine accepts a new request from the Web server.\r
+      </P>\r
+      <P>\r
+         The application library was designed to make migration of existing CGI programs as simple as possible. Many\r
+         applications can be converted by adding a loop around the main request processing code and recompiling with\r
+         the FastCGI application library. To ease migration to FastCGI, executables built with the application library\r
+         can run as either CGI or FastCGI programs, depending on how they are invoked. The library detects the\r
+         execution environment and automatically selects FastCGI or regular I/O routines, as appropriate.\r
+      </P>\r
+      <P>\r
+         Applications written in Perl, Tcl, and other scripting languages can be migrated by using a language\r
+         interpreter built with the application library. FastCGI-integrated Tcl and Perl interpreters for popular Unix\r
+         platforms are available from the <I>www.fastcgi.com</I> Web site. The interpreters are backward-compatible:\r
+         They can run standard Tcl and Perl applications.\r
+      </P>\r
+      <H3>\r
+         3. Single-threaded and multi-threaded applications\r
+      </H3>\r
+      <P>\r
+         FastCGI gives developers a free choice of whether to develop applications in a single-threaded or\r
+         multi-threaded style. The FastCGI interface supports multi-threading in two ways:\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            Applications can accept concurrent Web server connections to provide concurrent requests to multiple\r
+            application threads.\r
+         </LI>\r
+         <LI>\r
+            Applications can accept multiplexed Web server connections, in which concurrent requests are communicated\r
+            over a single connection to multiple application threads.\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         Multi-threaded programming is complex -- concurrency makes programs difficult to test and debug -- so many\r
+         developers will prefer to program in the familiar single-threaded style. By having several concurrent\r
+         processes running the same application it is often possible to achieve high performance with single-threaded\r
+         programming.\r
+      </P>\r
+      <P>\r
+         The FastCGI interface allows Web servers to implement <I>session affinity</I>, a feature that allows\r
+         applications to maintain caches of user-related data. With session affinity, when several concurrent processes\r
+         are running the same application, the Web server routes all requests from a particular user to the same\r
+         application process. Web server APIs don&#39;t provide this functionality to single-threaded applications, so\r
+         the performance of an API-based application is often inferior to the performance of the corresponding FastCGI\r
+         application.\r
+      </P>\r
+      <H3>\r
+         4. Distributed FastCGI\r
+      </H3>\r
+      <P>\r
+         Because FastCGI can communicate over TCP/IP connections, it supports configurations in which applications run\r
+         remotely from the Web server. This can provide scaling, load balancing, high availability, and connections to\r
+         systems that don&#39;t have Web servers.\r
+      </P>\r
+      <P>\r
+         Distributed FastCGI can also provide security advantages. A Web server outside a corporate firewall can\r
+         communicate through the firewall to internal databases. For instance, an application might need to\r
+         authenticate incoming users as customers in order to give access to certain documents on the external Web\r
+         site. With FastCGI this authentication can be done without replicating data and without compromising security.\r
+      </P>\r
+      <H3>\r
+         5. Roles\r
+      </H3>\r
+      <P>\r
+         A problem with CGI is its limited functionality: CGI programs can only provide responses to requests. FastCGI\r
+         provides expanded functionality with support for three different application &quot;roles&quot;:\r
+      </P>\r
+      <UL>\r
+         <LI>\r
+            <B>Responder.</B> This is the basic FastCGI role, and corresponds to the simple functionality offered by\r
+            CGI today.\r
+         </LI>\r
+         <LI>\r
+            <B>Filter.</B> The FastCGI application filters the requested Web server file before sending it to the\r
+            client.\r
+         </LI>\r
+         <LI>\r
+            <B>Authorizer.</B> The FastCGI program performs an access control decision for the request (such as\r
+            performing a username/password database lookup).\r
+         </LI>\r
+      </UL>\r
+      <P>\r
+         Other roles will be defined in the future. For instance, a &quot;logger&quot; role would be useful, where the\r
+         FastCGI program would receive the server&#39;s log entries for real-time processing and analysis.\r
+      </P>\r
+      <H3>\r
+         6. Conclusions\r
+      </H3>\r
+      <P>\r
+         Today&#39;s Web business applications need a platform that&#39;s fast, open, maintainable, straightforward,\r
+         stable, and secure. FastCGI&#39;s design meets these requirements, and provides a logical migration path from\r
+         the proven and widely deployed CGI technology. This allows developers to take advantage of FastCGI&#39;s\r
+         benefits without losing their existing investment in CGI applications.\r
+      </P>\r
+      <P>\r
+         For more information about FastCGI, visit the <A HREF="http://www.fastcgi.com/">www.fastcgi.com Web site</A>.\r
+      </P>\r
+   </BODY>\r
+</HTML>\r
+\r