remove dos eols
robs [Mon, 25 Feb 2002 00:42:59 +0000 (00:42 +0000)]
17 files changed:
doc/fastcgi-prog-guide/ap_guida.htm
doc/fastcgi-prog-guide/ap_guide.htm
doc/fastcgi-prog-guide/apaman.htm
doc/fastcgi-prog-guide/ch1intro.htm
doc/fastcgi-prog-guide/ch2c.htm
doc/fastcgi-prog-guide/ch3perl.htm
doc/fastcgi-prog-guide/ch4tcl.htm
doc/fastcgi-prog-guide/cover.htm
doc/fastcgi-whitepaper/fastcgi.htm
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 2d3459f..77d8c17 100755 (executable)
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
-   <HEAD>\r
-      <TITLE>\r
-         FastCGI Application Programmer&#39;s Guide - Index\r
-      </TITLE>\r
-<STYLE TYPE="text/css">\r
- body {\r
-  background-color: #ffffff;\r
- }\r
- div.c1 {text-align: center}\r
-</STYLE>\r
-   </HEAD>\r
-   <BODY>\r
-      <A HREF="cover.htm">[Top]</A> <A HREF="apaman.htm">[Prev]</A>\r
-      <P>\r
-         [Next] [Bottom]\r
-      </P>\r
-      <HR>\r
-      <BR>\r
-       <A NAME="801"></A>\r
-      <DIV CLASS="c1">\r
-         <H1>\r
-            Index<BR>\r
-         </H1>\r
-      </DIV>\r
-      <A NAME="1384"></A>\r
-      <DIV CLASS="c1">\r
-         <H2>\r
-            A\r
-         </H2>\r
-      </DIV>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="1388"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch4tcl.htm#4835">applications in Tcl 19</A> <A NAME="1390"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch1intro.htm#8428">Authorizer applications 4</A> \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="1392"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#9483">environment variables 6</A> <A NAME="1394"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#8437">stdin and stderr 4</A>\r
-               </DD>\r
-            </DL>\r
-         </DD>\r
-      </DL>\r
-      <A NAME="1396"></A>\r
-      <DIV CLASS="c1">\r
-         <H2>\r
-            C\r
-         </H2>\r
-      </DIV>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="1399"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch2c.htm#917">C language, writing FastCGI applications in 11</A>\r
-         </DD>\r
-      </DL>\r
-      <A NAME="1401"></A>\r
-      <DIV CLASS="c1">\r
-         <H2>\r
-            E\r
-         </H2>\r
-      </DIV>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="1404"></A>\r
-         </DD>\r
-         <DD>\r
-            environment variables \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="1405"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#9483">differences from CGI 6</A> <A NAME="1407"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#8431">returned from Authorizer applications 4</A>\r
-               </DD>\r
-            </DL>\r
-            <A NAME="1409"></A>\r
-         </DD>\r
-         <DD>\r
-            examples \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="1410"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch2c.htm#4182">responder application in C 13</A> <A NAME="1412"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch3perl.htm#5002">responder application in perl 18</A> <A NAME="1414"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch4tcl.htm#4343">responder application in Tcl 20</A>\r
-               </DD>\r
-            </DL>\r
-            <A NAME="1416"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="apaman.htm#95796">exit status, of FastCGI application 24</A>\r
-         </DD>\r
-      </DL>\r
-      <A NAME="1418"></A>\r
-      <DIV CLASS="c1">\r
-         <H2>\r
-            F\r
-         </H2>\r
-      </DIV>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="1420"></A>\r
-         </DD>\r
-         <DD>\r
-            FastCGI \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="1421"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch4tcl.htm#4835">19</A> <A NAME="1423"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch2c.htm#917">applications in C 11</A> <A NAME="1425"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch3perl.htm#917">applications in Perl 17</A> <A NAME="1427"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#7995">differences from CGI 1</A>\r
-               </DD>\r
-            </DL>\r
-            <A NAME="1429"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="apaman.htm#95732">FCGI_DATA_LAST_MOD 23</A> <A NAME="1431"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="apaman.htm#95731">FCGI_DATA_LENGTH 23</A> <A NAME="1433"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch1intro.htm#9488">FCGI_DATA_LENGTH (in Filter applications) 6</A> <A NAME="1435"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch1intro.htm#9490">FCGI_ROLE 6,</A> <A HREF="apaman.htm#95661">22</A> <A NAME="1438"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="apaman.htm#95846">FCGI_SetExitStatus 24</A> <A NAME="1440"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="apaman.htm#95309">FCGI_StartFilterData 22</A> <A NAME="1442"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch2c.htm#4199">fcgi_stdio library 11</A> \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="1444"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch2c.htm#4629">location of 15</A> <A NAME="1446"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95882">manpages for 21</A>\r
-               </DD>\r
-            </DL>\r
-            <A NAME="1448"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="apaman.htm#95663">FCGI_ToFcgiStream 22</A> <A NAME="1450"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="apaman.htm#95663">FCGI_ToFILE 22</A> <A NAME="1452"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch2c.htm#4199">fcgiapp library 11</A> <A NAME="1454"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch1intro.htm#9486">FILE_LAST_MOD (in Filter applications) 6</A> <A NAME="1456"></A>\r
-         </DD>\r
-         <DD>\r
-            Filter applications \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="1457"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95732">last modification time 23</A> <A NAME="1459"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95728">reading from stdin 23</A>\r
-               </DD>\r
-            </DL>\r
-         </DD>\r
-      </DL>\r
-      <A NAME="1461"></A>\r
-      <DIV CLASS="c1">\r
-         <H2>\r
-            G\r
-         </H2>\r
-      </DIV>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="1463"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch2c.htm#4785">Great Circle (C garbage collector) 16</A>\r
-         </DD>\r
-      </DL>\r
-      <A NAME="1465"></A>\r
-      <DIV CLASS="c1">\r
-         <H2>\r
-            I\r
-         </H2>\r
-      </DIV>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="1468"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch1intro.htm#9480">Initial Environment Variables 5</A>\r
-         </DD>\r
-      </DL>\r
-      <A NAME="1470"></A>\r
-      <DIV CLASS="c1">\r
-         <H2>\r
-            M\r
-         </H2>\r
-      </DIV>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="1475"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="apaman.htm#95882">manpages 21</A> <A NAME="1477"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch2c.htm#4190">memory leaks 16</A>\r
-         </DD>\r
-      </DL>\r
-      <A NAME="1479"></A>\r
-      <DIV CLASS="c1">\r
-         <H2>\r
-            P\r
-         </H2>\r
-      </DIV>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="1483"></A>\r
-         </DD>\r
-         <DD>\r
-            Perl \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="1484"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch3perl.htm#917">writing FastCGI applications in 17</A>\r
-               </DD>\r
-            </DL>\r
-            <A NAME="1486"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch2c.htm#4785">Purify (for checking storage leaks) 16</A>\r
-         </DD>\r
-      </DL>\r
-      <A NAME="1488"></A>\r
-      <DIV CLASS="c1">\r
-         <H2>\r
-            R\r
-         </H2>\r
-      </DIV>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="1491"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch1intro.htm#9477">response loop 5</A> \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="1493"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch2c.htm#4202">in C 12</A> <A NAME="1495"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch3perl.htm#4243">in Perl 17</A> <A NAME="1497"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch4tcl.htm#4228">in TCL 19</A>\r
-               </DD>\r
-            </DL>\r
-         </DD>\r
-      </DL>\r
-      <HR>\r
-      <BR>\r
-       <A HREF="cover.htm">[Top]</A> <A HREF="apaman.htm">[Prev]</A>\r
-      <P>\r
-         [Next] [Bottom]\r
-      </P>\r
-      <HR>\r
-      <BR>\r
-       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->\r
-      <!-- -->\r
-      <!-- For more information on how this document, and how the rest of -->\r
-      <!-- this server was created, email yourEmail@xyzcorp.com -->\r
-      <!-- -->\r
-      <!-- Last updated: 04/15/96 08:00:22 -->\r
-   </BODY>\r
-</HTML>\r
-\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         FastCGI Application Programmer&#39;s Guide - Index
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #ffffff;
+ }
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <A HREF="cover.htm">[Top]</A> <A HREF="apaman.htm">[Prev]</A>
+      <P>
+         [Next] [Bottom]
+      </P>
+      <HR>
+      <BR>
+       <A NAME="801"></A>
+      <DIV CLASS="c1">
+         <H1>
+            Index<BR>
+         </H1>
+      </DIV>
+      <A NAME="1384"></A>
+      <DIV CLASS="c1">
+         <H2>
+            A
+         </H2>
+      </DIV>
+      <DL>
+         <DD>
+            <A NAME="1388"></A>
+         </DD>
+         <DD>
+            <A HREF="ch4tcl.htm#4835">applications in Tcl 19</A> <A NAME="1390"></A>
+         </DD>
+         <DD>
+            <A HREF="ch1intro.htm#8428">Authorizer applications 4</A> 
+            <DL>
+               <DD>
+                  <A NAME="1392"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#9483">environment variables 6</A> <A NAME="1394"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#8437">stdin and stderr 4</A>
+               </DD>
+            </DL>
+         </DD>
+      </DL>
+      <A NAME="1396"></A>
+      <DIV CLASS="c1">
+         <H2>
+            C
+         </H2>
+      </DIV>
+      <DL>
+         <DD>
+            <A NAME="1399"></A>
+         </DD>
+         <DD>
+            <A HREF="ch2c.htm#917">C language, writing FastCGI applications in 11</A>
+         </DD>
+      </DL>
+      <A NAME="1401"></A>
+      <DIV CLASS="c1">
+         <H2>
+            E
+         </H2>
+      </DIV>
+      <DL>
+         <DD>
+            <A NAME="1404"></A>
+         </DD>
+         <DD>
+            environment variables 
+            <DL>
+               <DD>
+                  <A NAME="1405"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#9483">differences from CGI 6</A> <A NAME="1407"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#8431">returned from Authorizer applications 4</A>
+               </DD>
+            </DL>
+            <A NAME="1409"></A>
+         </DD>
+         <DD>
+            examples 
+            <DL>
+               <DD>
+                  <A NAME="1410"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch2c.htm#4182">responder application in C 13</A> <A NAME="1412"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch3perl.htm#5002">responder application in perl 18</A> <A NAME="1414"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch4tcl.htm#4343">responder application in Tcl 20</A>
+               </DD>
+            </DL>
+            <A NAME="1416"></A>
+         </DD>
+         <DD>
+            <A HREF="apaman.htm#95796">exit status, of FastCGI application 24</A>
+         </DD>
+      </DL>
+      <A NAME="1418"></A>
+      <DIV CLASS="c1">
+         <H2>
+            F
+         </H2>
+      </DIV>
+      <DL>
+         <DD>
+            <A NAME="1420"></A>
+         </DD>
+         <DD>
+            FastCGI 
+            <DL>
+               <DD>
+                  <A NAME="1421"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch4tcl.htm#4835">19</A> <A NAME="1423"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch2c.htm#917">applications in C 11</A> <A NAME="1425"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch3perl.htm#917">applications in Perl 17</A> <A NAME="1427"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#7995">differences from CGI 1</A>
+               </DD>
+            </DL>
+            <A NAME="1429"></A>
+         </DD>
+         <DD>
+            <A HREF="apaman.htm#95732">FCGI_DATA_LAST_MOD 23</A> <A NAME="1431"></A>
+         </DD>
+         <DD>
+            <A HREF="apaman.htm#95731">FCGI_DATA_LENGTH 23</A> <A NAME="1433"></A>
+         </DD>
+         <DD>
+            <A HREF="ch1intro.htm#9488">FCGI_DATA_LENGTH (in Filter applications) 6</A> <A NAME="1435"></A>
+         </DD>
+         <DD>
+            <A HREF="ch1intro.htm#9490">FCGI_ROLE 6,</A> <A HREF="apaman.htm#95661">22</A> <A NAME="1438"></A>
+         </DD>
+         <DD>
+            <A HREF="apaman.htm#95846">FCGI_SetExitStatus 24</A> <A NAME="1440"></A>
+         </DD>
+         <DD>
+            <A HREF="apaman.htm#95309">FCGI_StartFilterData 22</A> <A NAME="1442"></A>
+         </DD>
+         <DD>
+            <A HREF="ch2c.htm#4199">fcgi_stdio library 11</A> 
+            <DL>
+               <DD>
+                  <A NAME="1444"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch2c.htm#4629">location of 15</A> <A NAME="1446"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95882">manpages for 21</A>
+               </DD>
+            </DL>
+            <A NAME="1448"></A>
+         </DD>
+         <DD>
+            <A HREF="apaman.htm#95663">FCGI_ToFcgiStream 22</A> <A NAME="1450"></A>
+         </DD>
+         <DD>
+            <A HREF="apaman.htm#95663">FCGI_ToFILE 22</A> <A NAME="1452"></A>
+         </DD>
+         <DD>
+            <A HREF="ch2c.htm#4199">fcgiapp library 11</A> <A NAME="1454"></A>
+         </DD>
+         <DD>
+            <A HREF="ch1intro.htm#9486">FILE_LAST_MOD (in Filter applications) 6</A> <A NAME="1456"></A>
+         </DD>
+         <DD>
+            Filter applications 
+            <DL>
+               <DD>
+                  <A NAME="1457"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95732">last modification time 23</A> <A NAME="1459"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95728">reading from stdin 23</A>
+               </DD>
+            </DL>
+         </DD>
+      </DL>
+      <A NAME="1461"></A>
+      <DIV CLASS="c1">
+         <H2>
+            G
+         </H2>
+      </DIV>
+      <DL>
+         <DD>
+            <A NAME="1463"></A>
+         </DD>
+         <DD>
+            <A HREF="ch2c.htm#4785">Great Circle (C garbage collector) 16</A>
+         </DD>
+      </DL>
+      <A NAME="1465"></A>
+      <DIV CLASS="c1">
+         <H2>
+            I
+         </H2>
+      </DIV>
+      <DL>
+         <DD>
+            <A NAME="1468"></A>
+         </DD>
+         <DD>
+            <A HREF="ch1intro.htm#9480">Initial Environment Variables 5</A>
+         </DD>
+      </DL>
+      <A NAME="1470"></A>
+      <DIV CLASS="c1">
+         <H2>
+            M
+         </H2>
+      </DIV>
+      <DL>
+         <DD>
+            <A NAME="1475"></A>
+         </DD>
+         <DD>
+            <A HREF="apaman.htm#95882">manpages 21</A> <A NAME="1477"></A>
+         </DD>
+         <DD>
+            <A HREF="ch2c.htm#4190">memory leaks 16</A>
+         </DD>
+      </DL>
+      <A NAME="1479"></A>
+      <DIV CLASS="c1">
+         <H2>
+            P
+         </H2>
+      </DIV>
+      <DL>
+         <DD>
+            <A NAME="1483"></A>
+         </DD>
+         <DD>
+            Perl 
+            <DL>
+               <DD>
+                  <A NAME="1484"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch3perl.htm#917">writing FastCGI applications in 17</A>
+               </DD>
+            </DL>
+            <A NAME="1486"></A>
+         </DD>
+         <DD>
+            <A HREF="ch2c.htm#4785">Purify (for checking storage leaks) 16</A>
+         </DD>
+      </DL>
+      <A NAME="1488"></A>
+      <DIV CLASS="c1">
+         <H2>
+            R
+         </H2>
+      </DIV>
+      <DL>
+         <DD>
+            <A NAME="1491"></A>
+         </DD>
+         <DD>
+            <A HREF="ch1intro.htm#9477">response loop 5</A> 
+            <DL>
+               <DD>
+                  <A NAME="1493"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch2c.htm#4202">in C 12</A> <A NAME="1495"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch3perl.htm#4243">in Perl 17</A> <A NAME="1497"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch4tcl.htm#4228">in TCL 19</A>
+               </DD>
+            </DL>
+         </DD>
+      </DL>
+      <HR>
+      <BR>
+       <A HREF="cover.htm">[Top]</A> <A HREF="apaman.htm">[Prev]</A>
+      <P>
+         [Next] [Bottom]
+      </P>
+      <HR>
+      <BR>
+       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->
+      <!-- -->
+      <!-- For more information on how this document, and how the rest of -->
+      <!-- this server was created, email yourEmail@xyzcorp.com -->
+      <!-- -->
+      <!-- Last updated: 04/15/96 08:00:22 -->
+   </BODY>
+</HTML>
+
index e11ced4..f049120 100755 (executable)
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
-   <HEAD>\r
-      <TITLE>\r
-         FastCGI Programmer&#39;s Guide - Table of Contents\r
-      </TITLE>\r
-<STYLE TYPE="text/css">\r
- body {\r
-  background-color: #ffffff;\r
- }\r
-</STYLE>\r
-   </HEAD>\r
-   <BODY>\r
-      <A HREF="cover.htm">[Top]</A> <A HREF="cover.htm">[Prev]</A> <A HREF="ch1intro.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       \r
-      <H4>\r
-         1. <A HREF="ch1intro.htm#9432">The Fast Common Gateway Interface 1</A>\r
-      </H4>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="4880"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch1intro.htm#8485">Advantages of FastCGI 1</A> \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="4882"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#8396">Long-lived Applications 1</A> <A NAME="4884"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#8445">Separating Application and Server 2</A> <A NAME="4886"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#8406">FastCGI &quot;Roles&quot; 2</A>\r
-               </DD>\r
-            </DL>\r
-            <A NAME="4888"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch1intro.htm#4207">Writing FastCGI Applications 4</A> \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="4890"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#9469">Code Structure 5</A> <A NAME="4892"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#9480">Initial Environment Variables 5</A> <A NAME="4894"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#9785">Per-Request Environment Variables 6</A> <A NAME="4896"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#9048">Building FastCGI Applications in C 6</A> <A NAME="4898"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#9570">Building FastCGI Applications in Perl 7</A> <A NAME="4900"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#9562">Building FastCGI Applications in Tcl 7</A>\r
-               </DD>\r
-            </DL>\r
-            <A NAME="4902"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch1intro.htm#8360">Implementation Details 7</A> \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="4904"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#7874">The fcgi_stdio Library: I/O Compatibility 9</A> <A NAME="4906"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="ch1intro.htm#9678">The fcgi_stdio Library: Binary compatibility 10</A>\r
-               </DD>\r
-            </DL>\r
-         </DD>\r
-      </DL>\r
-      <H4>\r
-         2. <A HREF="ch2c.htm#3659">Developing FastCGI Applications in C 11</A>\r
-      </H4>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="4910"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch2c.htm#5371">The I/O Libraries 11</A> <A NAME="4912"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch2c.htm#5847">Code Structure 12</A> <A NAME="4914"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch2c.htm#5373">Example 1: TinyFastCGI 12</A> <A NAME="4916"></A>\r
-         </DD>\r
-         <DT>\r
-         </DT>\r
-         <DD>\r
-            <A HREF="ch2c.htm#4182">Example 2: Prime Number Generator 13</A> <A NAME="4918"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch2c.htm#5151">Building 15</A> <A NAME="4920"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch2c.htm#4190">Memory Leaks 16</A>\r
-         </DD>\r
-      </DL>\r
-      <H4>\r
-         3. <A HREF="ch3perl.htm#3659">Developing FastCGI Applications in Perl 17</A>\r
-      </H4>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="4924"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch3perl.htm#4183">Getting Started 17</A> <A NAME="4926"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch3perl.htm#5002">Example: TinyFastCGI 18</A>\r
-         </DD>\r
-      </DL>\r
-      <H4>\r
-         4. <A HREF="ch4tcl.htm#3659">Developing FastCGI Applications in Tcl 19</A>\r
-      </H4>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="4930"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch4tcl.htm#4222">Getting Started 19</A> <A NAME="4932"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="ch4tcl.htm#4853">Example: TinyFastCGI 20</A>\r
-         </DD>\r
-      </DL>\r
-      <H4>\r
-         A. <A HREF="apaman.htm#3601">FastCGI Reference Pages 21</A>\r
-      </H4>\r
-      <DL>\r
-         <DD>\r
-            <A NAME="4936"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="apaman.htm#95860">FCGI_Accept (3) 21</A> \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="4938"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95861">Name 21</A> <A NAME="4940"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95652">Synopsis 21</A> <A NAME="4942"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95656">Description 21</A> <A NAME="4944"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95664">Return Values 22</A>\r
-               </DD>\r
-            </DL>\r
-            <A NAME="4946"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="apaman.htm#95309">FCGI_StartFilterData (3) 22</A> \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="4948"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95310">Name 22</A> <A NAME="4950"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95312">Synopsis 22</A> <A NAME="4952"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95315">Description 23</A> <A NAME="4954"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95733">Return Values 23</A> <A NAME="4956"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95323">Example 23</A>\r
-               </DD>\r
-            </DL>\r
-            <A NAME="4958"></A>\r
-         </DD>\r
-         <DD>\r
-            <A HREF="apaman.htm#95846">FCGI_SetExitStatus(3) 24</A> \r
-            <DL>\r
-               <DD>\r
-                  <A NAME="4960"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95793">Name 24</A> <A NAME="4962"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95786">Synopsis 24</A> <A NAME="4964"></A>\r
-               </DD>\r
-               <DD>\r
-                  <A HREF="apaman.htm#95788">Description 24</A>\r
-               </DD>\r
-            </DL>\r
-         </DD>\r
-      </DL>\r
-      <HR>\r
-      <BR>\r
-       <A HREF="cover.htm">[Top]</A> <A HREF="cover.htm">[Prev]</A> <A HREF="ch1intro.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->\r
-      <!-- -->\r
-      <!-- For more information on how this document, and how the rest of -->\r
-      <!-- this server was created, email yourEmail@xyzcorp.com -->\r
-      <!-- -->\r
-      <!-- Last updated: 04/15/96 08:00:12 -->\r
-   </BODY>\r
-</HTML>\r
-\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         FastCGI Programmer&#39;s Guide - Table of Contents
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #ffffff;
+ }
+</STYLE>
+   </HEAD>
+   <BODY>
+      <A HREF="cover.htm">[Top]</A> <A HREF="cover.htm">[Prev]</A> <A HREF="ch1intro.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       
+      <H4>
+         1. <A HREF="ch1intro.htm#9432">The Fast Common Gateway Interface 1</A>
+      </H4>
+      <DL>
+         <DD>
+            <A NAME="4880"></A>
+         </DD>
+         <DD>
+            <A HREF="ch1intro.htm#8485">Advantages of FastCGI 1</A> 
+            <DL>
+               <DD>
+                  <A NAME="4882"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#8396">Long-lived Applications 1</A> <A NAME="4884"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#8445">Separating Application and Server 2</A> <A NAME="4886"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#8406">FastCGI &quot;Roles&quot; 2</A>
+               </DD>
+            </DL>
+            <A NAME="4888"></A>
+         </DD>
+         <DD>
+            <A HREF="ch1intro.htm#4207">Writing FastCGI Applications 4</A> 
+            <DL>
+               <DD>
+                  <A NAME="4890"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#9469">Code Structure 5</A> <A NAME="4892"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#9480">Initial Environment Variables 5</A> <A NAME="4894"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#9785">Per-Request Environment Variables 6</A> <A NAME="4896"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#9048">Building FastCGI Applications in C 6</A> <A NAME="4898"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#9570">Building FastCGI Applications in Perl 7</A> <A NAME="4900"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#9562">Building FastCGI Applications in Tcl 7</A>
+               </DD>
+            </DL>
+            <A NAME="4902"></A>
+         </DD>
+         <DD>
+            <A HREF="ch1intro.htm#8360">Implementation Details 7</A> 
+            <DL>
+               <DD>
+                  <A NAME="4904"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#7874">The fcgi_stdio Library: I/O Compatibility 9</A> <A NAME="4906"></A>
+               </DD>
+               <DD>
+                  <A HREF="ch1intro.htm#9678">The fcgi_stdio Library: Binary compatibility 10</A>
+               </DD>
+            </DL>
+         </DD>
+      </DL>
+      <H4>
+         2. <A HREF="ch2c.htm#3659">Developing FastCGI Applications in C 11</A>
+      </H4>
+      <DL>
+         <DD>
+            <A NAME="4910"></A>
+         </DD>
+         <DD>
+            <A HREF="ch2c.htm#5371">The I/O Libraries 11</A> <A NAME="4912"></A>
+         </DD>
+         <DD>
+            <A HREF="ch2c.htm#5847">Code Structure 12</A> <A NAME="4914"></A>
+         </DD>
+         <DD>
+            <A HREF="ch2c.htm#5373">Example 1: TinyFastCGI 12</A> <A NAME="4916"></A>
+         </DD>
+         <DT>
+         </DT>
+         <DD>
+            <A HREF="ch2c.htm#4182">Example 2: Prime Number Generator 13</A> <A NAME="4918"></A>
+         </DD>
+         <DD>
+            <A HREF="ch2c.htm#5151">Building 15</A> <A NAME="4920"></A>
+         </DD>
+         <DD>
+            <A HREF="ch2c.htm#4190">Memory Leaks 16</A>
+         </DD>
+      </DL>
+      <H4>
+         3. <A HREF="ch3perl.htm#3659">Developing FastCGI Applications in Perl 17</A>
+      </H4>
+      <DL>
+         <DD>
+            <A NAME="4924"></A>
+         </DD>
+         <DD>
+            <A HREF="ch3perl.htm#4183">Getting Started 17</A> <A NAME="4926"></A>
+         </DD>
+         <DD>
+            <A HREF="ch3perl.htm#5002">Example: TinyFastCGI 18</A>
+         </DD>
+      </DL>
+      <H4>
+         4. <A HREF="ch4tcl.htm#3659">Developing FastCGI Applications in Tcl 19</A>
+      </H4>
+      <DL>
+         <DD>
+            <A NAME="4930"></A>
+         </DD>
+         <DD>
+            <A HREF="ch4tcl.htm#4222">Getting Started 19</A> <A NAME="4932"></A>
+         </DD>
+         <DD>
+            <A HREF="ch4tcl.htm#4853">Example: TinyFastCGI 20</A>
+         </DD>
+      </DL>
+      <H4>
+         A. <A HREF="apaman.htm#3601">FastCGI Reference Pages 21</A>
+      </H4>
+      <DL>
+         <DD>
+            <A NAME="4936"></A>
+         </DD>
+         <DD>
+            <A HREF="apaman.htm#95860">FCGI_Accept (3) 21</A> 
+            <DL>
+               <DD>
+                  <A NAME="4938"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95861">Name 21</A> <A NAME="4940"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95652">Synopsis 21</A> <A NAME="4942"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95656">Description 21</A> <A NAME="4944"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95664">Return Values 22</A>
+               </DD>
+            </DL>
+            <A NAME="4946"></A>
+         </DD>
+         <DD>
+            <A HREF="apaman.htm#95309">FCGI_StartFilterData (3) 22</A> 
+            <DL>
+               <DD>
+                  <A NAME="4948"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95310">Name 22</A> <A NAME="4950"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95312">Synopsis 22</A> <A NAME="4952"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95315">Description 23</A> <A NAME="4954"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95733">Return Values 23</A> <A NAME="4956"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95323">Example 23</A>
+               </DD>
+            </DL>
+            <A NAME="4958"></A>
+         </DD>
+         <DD>
+            <A HREF="apaman.htm#95846">FCGI_SetExitStatus(3) 24</A> 
+            <DL>
+               <DD>
+                  <A NAME="4960"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95793">Name 24</A> <A NAME="4962"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95786">Synopsis 24</A> <A NAME="4964"></A>
+               </DD>
+               <DD>
+                  <A HREF="apaman.htm#95788">Description 24</A>
+               </DD>
+            </DL>
+         </DD>
+      </DL>
+      <HR>
+      <BR>
+       <A HREF="cover.htm">[Top]</A> <A HREF="cover.htm">[Prev]</A> <A HREF="ch1intro.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->
+      <!-- -->
+      <!-- For more information on how this document, and how the rest of -->
+      <!-- this server was created, email yourEmail@xyzcorp.com -->
+      <!-- -->
+      <!-- Last updated: 04/15/96 08:00:12 -->
+   </BODY>
+</HTML>
+
index dc65789..8ff40cd 100755 (executable)
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
-   <HEAD>\r
-      <TITLE>\r
-         FCGI_Accept(2) Man Page\r
-      </TITLE>\r
-<STYLE TYPE="text/css">\r
- body {\r
-  background-color: #ffffff;\r
- }\r
- li.c2 {list-style: none}\r
- div.c1 {text-align: center}\r
-</STYLE>\r
-   </HEAD>\r
-   <BODY>\r
-      <A HREF="cover.htm">[Top]</A> <A HREF="ch4tcl.htm">[Prev]</A> <A HREF="ap_guida.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       <A NAME="3601"></A>\r
-      <DIV CLASS="c1">\r
-         <H1>\r
-            A FastCGI<BR>\r
-            Reference Pages\r
-         </H1>\r
-      </DIV>\r
-      <A NAME="95882"></A>\r
-      <P>\r
-         This appendix contains reference pages for the following FastCGI routines from the <CODE>fcgi_stdio</CODE>\r
-         library:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <UL>\r
-         <LI CLASS="c2">\r
-            <A NAME="95884"></A>\r
-         </LI>\r
-         <LI>\r
-            <CODE>FCGI_Accept</CODE> <A NAME="95885"></A>\r
-         </LI>\r
-         <LI>\r
-            <CODE>FCGI_Start_Filter_Data</CODE> <A NAME="95859"></A>\r
-         </LI>\r
-         <LI>\r
-            <CODE>FCGI_SetExitStatus</CODE>\r
-         </LI>\r
-      </UL>\r
-      <H1>\r
-         FCGI_Accept (3)\r
-      </H1>\r
-      <H2>\r
-         Name\r
-      </H2>\r
-      <A NAME="95637"></A> <CODE>FCGI_Accept, FCGI_ToFILE, FCGI_ToFcgiStream</CODE>\r
-      <P>\r
-         - fcgi_stdio compatibility library\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Synopsis\r
-      </H2>\r
-<PRE>\r
-<A NAME="95669">#include &lt;fcgi_stdio.h&gt;\r
-</A>\r
-<A NAME="95653">int<BR>\r
- FCGI_Accept(void);\r
-</A>\r
-<A NAME="95654">FILE *<BR>\r
- FCGI_ToFILE(FCGI_FILE *);\r
-</A>\r
-<A NAME="95655">FCGI_Stream *<BR>\r
- FCGI_ToFcgiStream(FCGI_FILE *);\r
-</A>\r
-</PRE>\r
-      <H2>\r
-         Description\r
-      </H2>\r
-      <A NAME="95683"></A>\r
-      <P>\r
-         The FCGI_Accept function accepts a new request from the HTTP server and creates a CGI-compatible execution\r
-         environment for the request.\r
-      </P>\r
-      <P>\r
-         <A NAME="95657"></A> If the application was invoked as a CGI program, the first call to FCGI_Accept is\r
-         essentially a no-op and the second call returns -1. This causes a correctly coded FastCGI application to run a\r
-         single request and exit, giving CGI behavior.\r
-      </P>\r
-      <P>\r
-         <A NAME="95658"></A> If the application was invoked as a FastCGI server, the first call to FCGI_Accept\r
-         indicates that the application has completed its initialization and is ready to accept its first request.\r
-         Subsequent calls to FCGI_Accept indicate that the application has completed processing its current request and\r
-         is ready to accept a new request.\r
-      </P>\r
-      <P>\r
-         <A NAME="95659"></A> In completing the current request, FCGI_Accept may detect errors, such as a broken pipe\r
-         to a client who has disconnected early. FCGI_Accept ignores such errors. An application that wishes to handle\r
-         such errors should explicitly call fclose(stderr), then fclose(stdout); an EOF return from either one\r
-         indicates an error.\r
-      </P>\r
-      <P>\r
-         <A NAME="95660"></A> After accepting a new request, FCGI_Accept assigns new values to the global variables\r
-         stdin, stdout, stderr, and environ. After FCGI_Accept returns, these variables have the same interpretation as\r
-         on entry to a CGI program.\r
-      </P>\r
-      <P>\r
-         <A NAME="95661"></A> In addition to the standard CGI environment variables, the environment variable\r
-         <CODE>FCGI_ROLE</CODE> is always set to the role of the current request. The roles currently defined are\r
-         <CODE>RESPONDER, AUTHORIZER</CODE>, and <CODE>FILTER</CODE>.\r
-      </P>\r
-      <P>\r
-         <A NAME="95662"></A> In the <CODE>FILTER</CODE> role, the additional variables <CODE>FCGI_DATA_LENGTH</CODE>\r
-         and <CODE>FCGI_DATA_LAST_MOD</CODE> are also defined. See <CODE>FCGI_StartFilterData</CODE><CODE>(3</CODE>)\r
-         for complete information.\r
-      </P>\r
-      <P>\r
-         <A NAME="95663"></A> The macros <CODE>FCGI_ToFILE</CODE> and <CODE>FCGI_ToFcgiStream</CODE> are provided to\r
-         allow escape to native functions that use the types <CODE>FILE</CODE> or <CODE>FCGI_Stream</CODE>. In the case\r
-         of <CODE>FILE</CODE>, functions would have to be separately compiled, since <CODE>fcgi_stdio.h</CODE> replaces\r
-         the standard <CODE>FILE</CODE> with <CODE>FCGI_FILE</CODE>.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Return Values\r
-      </H2>\r
-      <A NAME="95686"></A>\r
-      <P>\r
-         0 for successful call, -1 for error (application should exit).\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         FCGI_StartFilterData (3)\r
-      </H1>\r
-      <H2>\r
-         Name\r
-      </H2>\r
-      <A NAME="95311"></A> <CODE>FCGI_StartFilterData</CODE>\r
-      <P>\r
-         -<CODE>fcgi_stdio</CODE> compatibility library\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Synopsis\r
-      </H2>\r
-<PRE>\r
-<A NAME="95313">#include &lt;fcgi_stdio.h&gt;\r
-</A>\r
-<A NAME="95314">int FCGI_StartFilterData(void)\r
-</A>\r
-</PRE>\r
-      <H2>\r
-         Description\r
-      </H2>\r
-      <A NAME="95728"></A>\r
-      <P>\r
-         Enables a FastCGI Filter application to begin reading its filter input data from <CODE>stdin</CODE>.\r
-      </P>\r
-      <P>\r
-         <A NAME="95729"></A> In order to call <CODE>FCGI_StartFilterData</CODE>, the FastCGI application should have\r
-         been invoked in the filter role (<CODE>getenv(&quot;FCGI_ROLE&quot;) == &quot;FILTER&quot;</CODE>), and should\r
-         have read <CODE>stdin</CODE> to EOF, consuming the entire <CODE>FCGI_STDIN</CODE> data stream. The call to\r
-         <CODE>FCGI_StartFilterData</CODE> positions stdin at the start of <CODE>FCGI_DATA</CODE>.\r
-      </P>\r
-      <P>\r
-         <A NAME="95730"></A> If the preconditions are not met (e.g., the application has not read <CODE>stdin</CODE>\r
-         to EOF), <CODE>FCGI_StartFilterData</CODE> returns a negative result, and the application will get EOF on\r
-         attempts to read from <CODE>stdin</CODE>.\r
-      </P>\r
-      <P>\r
-         <A NAME="95731"></A> The application can determine the number of bytes available on <CODE>FCGI_DATA</CODE> by\r
-         performing <CODE>atoi(getenv(&quot;FCGI_DATA_LENGTH&quot;)</CODE>. If fewer than this many bytes are delivered\r
-         on <CODE>stdin</CODE> after calling <CODE>FCGI_StartFilterData</CODE>, the application should perform an\r
-         application-specific error response. If the application normally makes an update, most likely it should abort\r
-         the update.\r
-      </P>\r
-      <P>\r
-         <A NAME="95732"></A> The application can determine last modification time of the filter input data by\r
-         performing <CODE>getenv(&quot;FCGI_DATA_LAST_MOD&quot;).</CODE> This allows applications to perform caching\r
-         based on last modification time.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Return Values\r
-      </H2>\r
-      <A NAME="95322"></A>\r
-      <P>\r
-         Returns 0 on success and a negative integer on failure.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Example\r
-      </H2>\r
-      <A NAME="95363"></A>\r
-      <P>\r
-         The following example reads in all the client data, but ignores it. Then, the code calls\r
-         <CODE>FCGI_StartFilterData</CODE>. Finally, the code reads in the file to be filtered and simply echos it back\r
-         to the client.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="95324">while (FCGI_Accept() &gt;= 0) {\r
-</A>\r
-<A NAME="95325">...\r
-</A>\r
- <A NAME="95364">/* Read data passed by client. */\r
-</A>\r
- <A NAME="95358"> while (getchar () != OF) \r
-</A>\r
-<A NAME="95935">{\r
-</A>\r
-<A NAME="95930">}\r
-</A>\r
-<A NAME="95359">\r
-</A>\r
- <A NAME="95367">/* Adjust standard input stream. */\r
-</A>\r
- <A NAME="95366"> status = FCGI_StartFilterData();\r
-</A>\r
-<A NAME="95369">\r
-</A>\r
- <A NAME="95360">/* Read in filter data and echo it back to client. */\r
-</A>\r
- <A NAME="95368"> while ((len = fread(tempBuffer, 1, 1024, stdin)) &gt; 0) \r
-</A>\r
- <A NAME="95361">   fwrite(tempBuffer, 1, len, stdout);\r
-</A>\r
-<A NAME="95844">\r
-</A>\r
-<A NAME="95845">} /* End FCGI_Accept loop */\r
-</A>\r
-</PRE>\r
-      <H1>\r
-         FCGI_SetExitStatus(3)\r
-      </H1>\r
-      <H2>\r
-         Name\r
-      </H2>\r
-      <A NAME="95794"></A> <CODE>FCGI_SetExitStatus</CODE>\r
-      <P>\r
-         - <CODE>fcgi_stdio</CODE> compatibility library\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Synopsis\r
-      </H2>\r
-<PRE>\r
-<A NAME="95795">#include &lt;fcgi_stdio.h&gt;\r
-</A>\r
-<A NAME="95787">void FCGI_SetExitStatus(int status);\r
-</A>\r
-</PRE>\r
-      <H2>\r
-         Description\r
-      </H2>\r
-      <A NAME="95796"></A>\r
-      <P>\r
-         Sets the exit status for the current FastCGI request. The exit status is the status code the request would\r
-         have exited with, had the request been run as a CGI program.\r
-      </P>\r
-      <P>\r
-         <A NAME="95789"></A> You can call <CODE>FCGI_SetExitStatus</CODE> several times during a request; the last\r
-         call before the request ends determines the value.\r
-      </P>\r
-      <P>\r
-         <A NAME="95797"></A>\r
-      </P>\r
-      <P>\r
-      </P>\r
-      <HR>\r
-      <BR>\r
-       <A HREF="cover.htm">[Top]</A> <A HREF="ch4tcl.htm">[Prev]</A> <A HREF="ap_guida.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->\r
-      <!-- -->\r
-      <!-- For more information on how this document, and how the rest of -->\r
-      <!-- this server was created, email yourEmail@xyzcorp.com -->\r
-      <!-- -->\r
-      <!-- Last updated: 04/15/96 08:00:20 -->\r
-   </BODY>\r
-</HTML>\r
-\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         FCGI_Accept(2) Man Page
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #ffffff;
+ }
+ li.c2 {list-style: none}
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <A HREF="cover.htm">[Top]</A> <A HREF="ch4tcl.htm">[Prev]</A> <A HREF="ap_guida.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       <A NAME="3601"></A>
+      <DIV CLASS="c1">
+         <H1>
+            A FastCGI<BR>
+            Reference Pages
+         </H1>
+      </DIV>
+      <A NAME="95882"></A>
+      <P>
+         This appendix contains reference pages for the following FastCGI routines from the <CODE>fcgi_stdio</CODE>
+         library:
+      </P>
+      <BR>
+      <BR>
+      <UL>
+         <LI CLASS="c2">
+            <A NAME="95884"></A>
+         </LI>
+         <LI>
+            <CODE>FCGI_Accept</CODE> <A NAME="95885"></A>
+         </LI>
+         <LI>
+            <CODE>FCGI_Start_Filter_Data</CODE> <A NAME="95859"></A>
+         </LI>
+         <LI>
+            <CODE>FCGI_SetExitStatus</CODE>
+         </LI>
+      </UL>
+      <H1>
+         FCGI_Accept (3)
+      </H1>
+      <H2>
+         Name
+      </H2>
+      <A NAME="95637"></A> <CODE>FCGI_Accept, FCGI_ToFILE, FCGI_ToFcgiStream</CODE>
+      <P>
+         - fcgi_stdio compatibility library
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Synopsis
+      </H2>
+<PRE>
+<A NAME="95669">#include &lt;fcgi_stdio.h&gt;
+</A>
+<A NAME="95653">int<BR>
+ FCGI_Accept(void);
+</A>
+<A NAME="95654">FILE *<BR>
+ FCGI_ToFILE(FCGI_FILE *);
+</A>
+<A NAME="95655">FCGI_Stream *<BR>
+ FCGI_ToFcgiStream(FCGI_FILE *);
+</A>
+</PRE>
+      <H2>
+         Description
+      </H2>
+      <A NAME="95683"></A>
+      <P>
+         The FCGI_Accept function accepts a new request from the HTTP server and creates a CGI-compatible execution
+         environment for the request.
+      </P>
+      <P>
+         <A NAME="95657"></A> If the application was invoked as a CGI program, the first call to FCGI_Accept is
+         essentially a no-op and the second call returns -1. This causes a correctly coded FastCGI application to run a
+         single request and exit, giving CGI behavior.
+      </P>
+      <P>
+         <A NAME="95658"></A> If the application was invoked as a FastCGI server, the first call to FCGI_Accept
+         indicates that the application has completed its initialization and is ready to accept its first request.
+         Subsequent calls to FCGI_Accept indicate that the application has completed processing its current request and
+         is ready to accept a new request.
+      </P>
+      <P>
+         <A NAME="95659"></A> In completing the current request, FCGI_Accept may detect errors, such as a broken pipe
+         to a client who has disconnected early. FCGI_Accept ignores such errors. An application that wishes to handle
+         such errors should explicitly call fclose(stderr), then fclose(stdout); an EOF return from either one
+         indicates an error.
+      </P>
+      <P>
+         <A NAME="95660"></A> After accepting a new request, FCGI_Accept assigns new values to the global variables
+         stdin, stdout, stderr, and environ. After FCGI_Accept returns, these variables have the same interpretation as
+         on entry to a CGI program.
+      </P>
+      <P>
+         <A NAME="95661"></A> In addition to the standard CGI environment variables, the environment variable
+         <CODE>FCGI_ROLE</CODE> is always set to the role of the current request. The roles currently defined are
+         <CODE>RESPONDER, AUTHORIZER</CODE>, and <CODE>FILTER</CODE>.
+      </P>
+      <P>
+         <A NAME="95662"></A> In the <CODE>FILTER</CODE> role, the additional variables <CODE>FCGI_DATA_LENGTH</CODE>
+         and <CODE>FCGI_DATA_LAST_MOD</CODE> are also defined. See <CODE>FCGI_StartFilterData</CODE><CODE>(3</CODE>)
+         for complete information.
+      </P>
+      <P>
+         <A NAME="95663"></A> The macros <CODE>FCGI_ToFILE</CODE> and <CODE>FCGI_ToFcgiStream</CODE> are provided to
+         allow escape to native functions that use the types <CODE>FILE</CODE> or <CODE>FCGI_Stream</CODE>. In the case
+         of <CODE>FILE</CODE>, functions would have to be separately compiled, since <CODE>fcgi_stdio.h</CODE> replaces
+         the standard <CODE>FILE</CODE> with <CODE>FCGI_FILE</CODE>.
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Return Values
+      </H2>
+      <A NAME="95686"></A>
+      <P>
+         0 for successful call, -1 for error (application should exit).
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         FCGI_StartFilterData (3)
+      </H1>
+      <H2>
+         Name
+      </H2>
+      <A NAME="95311"></A> <CODE>FCGI_StartFilterData</CODE>
+      <P>
+         -<CODE>fcgi_stdio</CODE> compatibility library
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Synopsis
+      </H2>
+<PRE>
+<A NAME="95313">#include &lt;fcgi_stdio.h&gt;
+</A>
+<A NAME="95314">int FCGI_StartFilterData(void)
+</A>
+</PRE>
+      <H2>
+         Description
+      </H2>
+      <A NAME="95728"></A>
+      <P>
+         Enables a FastCGI Filter application to begin reading its filter input data from <CODE>stdin</CODE>.
+      </P>
+      <P>
+         <A NAME="95729"></A> In order to call <CODE>FCGI_StartFilterData</CODE>, the FastCGI application should have
+         been invoked in the filter role (<CODE>getenv(&quot;FCGI_ROLE&quot;) == &quot;FILTER&quot;</CODE>), and should
+         have read <CODE>stdin</CODE> to EOF, consuming the entire <CODE>FCGI_STDIN</CODE> data stream. The call to
+         <CODE>FCGI_StartFilterData</CODE> positions stdin at the start of <CODE>FCGI_DATA</CODE>.
+      </P>
+      <P>
+         <A NAME="95730"></A> If the preconditions are not met (e.g., the application has not read <CODE>stdin</CODE>
+         to EOF), <CODE>FCGI_StartFilterData</CODE> returns a negative result, and the application will get EOF on
+         attempts to read from <CODE>stdin</CODE>.
+      </P>
+      <P>
+         <A NAME="95731"></A> The application can determine the number of bytes available on <CODE>FCGI_DATA</CODE> by
+         performing <CODE>atoi(getenv(&quot;FCGI_DATA_LENGTH&quot;)</CODE>. If fewer than this many bytes are delivered
+         on <CODE>stdin</CODE> after calling <CODE>FCGI_StartFilterData</CODE>, the application should perform an
+         application-specific error response. If the application normally makes an update, most likely it should abort
+         the update.
+      </P>
+      <P>
+         <A NAME="95732"></A> The application can determine last modification time of the filter input data by
+         performing <CODE>getenv(&quot;FCGI_DATA_LAST_MOD&quot;).</CODE> This allows applications to perform caching
+         based on last modification time.
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Return Values
+      </H2>
+      <A NAME="95322"></A>
+      <P>
+         Returns 0 on success and a negative integer on failure.
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Example
+      </H2>
+      <A NAME="95363"></A>
+      <P>
+         The following example reads in all the client data, but ignores it. Then, the code calls
+         <CODE>FCGI_StartFilterData</CODE>. Finally, the code reads in the file to be filtered and simply echos it back
+         to the client.
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="95324">while (FCGI_Accept() &gt;= 0) {
+</A>
+<A NAME="95325">...
+</A>
+ <A NAME="95364">/* Read data passed by client. */
+</A>
+ <A NAME="95358"> while (getchar () != OF) 
+</A>
+<A NAME="95935">{
+</A>
+<A NAME="95930">}
+</A>
+<A NAME="95359">
+</A>
+ <A NAME="95367">/* Adjust standard input stream. */
+</A>
+ <A NAME="95366"> status = FCGI_StartFilterData();
+</A>
+<A NAME="95369">
+</A>
+ <A NAME="95360">/* Read in filter data and echo it back to client. */
+</A>
+ <A NAME="95368"> while ((len = fread(tempBuffer, 1, 1024, stdin)) &gt; 0) 
+</A>
+ <A NAME="95361">   fwrite(tempBuffer, 1, len, stdout);
+</A>
+<A NAME="95844">
+</A>
+<A NAME="95845">} /* End FCGI_Accept loop */
+</A>
+</PRE>
+      <H1>
+         FCGI_SetExitStatus(3)
+      </H1>
+      <H2>
+         Name
+      </H2>
+      <A NAME="95794"></A> <CODE>FCGI_SetExitStatus</CODE>
+      <P>
+         - <CODE>fcgi_stdio</CODE> compatibility library
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Synopsis
+      </H2>
+<PRE>
+<A NAME="95795">#include &lt;fcgi_stdio.h&gt;
+</A>
+<A NAME="95787">void FCGI_SetExitStatus(int status);
+</A>
+</PRE>
+      <H2>
+         Description
+      </H2>
+      <A NAME="95796"></A>
+      <P>
+         Sets the exit status for the current FastCGI request. The exit status is the status code the request would
+         have exited with, had the request been run as a CGI program.
+      </P>
+      <P>
+         <A NAME="95789"></A> You can call <CODE>FCGI_SetExitStatus</CODE> several times during a request; the last
+         call before the request ends determines the value.
+      </P>
+      <P>
+         <A NAME="95797"></A>
+      </P>
+      <P>
+      </P>
+      <HR>
+      <BR>
+       <A HREF="cover.htm">[Top]</A> <A HREF="ch4tcl.htm">[Prev]</A> <A HREF="ap_guida.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->
+      <!-- -->
+      <!-- For more information on how this document, and how the rest of -->
+      <!-- this server was created, email yourEmail@xyzcorp.com -->
+      <!-- -->
+      <!-- Last updated: 04/15/96 08:00:20 -->
+   </BODY>
+</HTML>
+
index 6799b7c..0132ffa 100755 (executable)
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
-   <HEAD>\r
-      <TITLE>\r
-         FastCGI Programmer&#39;s Guide - Chapter 1, The Fast Common Gateway Interface\r
-      </TITLE>\r
-<STYLE TYPE="text/css">\r
- body {\r
-  background-color: #ffffff;\r
- }\r
- li.c2 {list-style: none}\r
- div.c1 {text-align: center}\r
-</STYLE>\r
-   </HEAD>\r
-   <BODY>\r
-      <A HREF="cover.htm">[Top]</A> <A HREF="ap_guide.htm">[Prev]</A> <A HREF="ch2c.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       <A NAME="9432"></A>\r
-      <DIV CLASS="c1">\r
-         <H1>\r
-            1 The Fast Common<BR>\r
-            Gateway Interface\r
-         </H1>\r
-      </DIV>\r
-      <A NAME="7982"></A>\r
-      <P>\r
-         The Fast Common Gateway Interface (FastCGI) is an enhancement to the existing CGI (Common Gateway Interface),\r
-         which is a standard for interfacing external applications with Web servers.\r
-      </P>\r
-      <P>\r
-         <A NAME="8373"></A> FastCGI is a proposed open standard and we expect both free and commercial Web servers to\r
-         support it. FastCGI is included in Open Market WebServer and Secure WebServer, versions 2.0 and greater.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         Advantages of FastCGI\r
-      </H1>\r
-      <A NAME="8369"></A>\r
-      <P>\r
-         FastCGI extends and enhances the CGI model in several ways:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <UL>\r
-         <LI CLASS="c2">\r
-            <A NAME="7832"></A>\r
-         </LI>\r
-         <LI>\r
-            FastCGI enables applications to persist between client requests, eliminating application start up overhead\r
-            and allowing the application to maintain state between client calls. <A NAME="7995"></A>\r
-         </LI>\r
-         <LI>\r
-            FastCGI enables applications to reside on remote systems (rather than having to reside on the same system\r
-            as the Web server) <A NAME="7997"></A>\r
-         </LI>\r
-         <LI>\r
-            FastCGI enables additional flexibility in application functionality, with explicit support for applications\r
-            that do client authentication and filtering of input.\r
-         </LI>\r
-      </UL>\r
-      <H2>\r
-         Long-lived Applications\r
-      </H2>\r
-      <A NAME="8458"></A>\r
-      <P>\r
-         CGI applications are ephemeral and short-lived: each time a client requests a CGI application, the server asks\r
-         the operating system to spawn a new CGI process. After the CGI process satisfies the request, the server kills\r
-         it. The server spawns and subsequently kills a new process for each client request.\r
-      </P>\r
-      <P>\r
-         <A NAME="8459"></A> FastCGI applications are long-lived, and can persist between client calls. The server\r
-         spawns the FastCGI process once and it continues to run and satisfy client requests until it is explicitly\r
-         terminated. You can also ask the Web server to start multiple copies of a FastCGI application, if you expect\r
-         that concurrent processing will improve the application&#39;s performance.\r
-      </P>\r
-      <P>\r
-         <A NAME="5761"></A> Long-lived applications have two important advantages over short-lived applications:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <UL>\r
-         <LI CLASS="c2">\r
-            <A NAME="7138"></A>\r
-         </LI>\r
-         <LI>\r
-            A short-lived application pays start up overhead on every request; a long-lived application spreads the\r
-            overhead over many requests. For an application that has a heavy start up cost, such as opening a database,\r
-            doing initialization on every call can be very inefficient. Reinitializing for every client is also very\r
-            inefficient for Perl programs, where the interpreter reads through the entire program before executing any\r
-            of it. <A NAME="9204"></A>\r
-         </LI>\r
-         <LI>\r
-            A long-lived application can cache information in memory between requests, allowing it to respond more\r
-            quickly to later requests.\r
-         </LI>\r
-      </UL>\r
-      <A NAME="8733"></A>\r
-      <P>\r
-         FastCGI is not the only way to get a long-lived application on the Web, however. For example, there are many\r
-         existing search engines that are implemented as long-lived applications.\r
-      </P>\r
-      <P>\r
-         <A NAME="8734"></A> In most cases, these applications rely on customized Web servers. In other words, since\r
-         most Web servers do not support long-lived applications, a programmer must code this support into a Web\r
-         server. This approach requires a tremendous amount of work and also ties the application to a particular\r
-         server.\r
-      </P>\r
-      <P>\r
-         <A NAME="8735"></A> Another way to get a long-lived application is to write code that calls routines from the\r
-         Web server&#39;s API. This alternative involves a lot of extra coding, ties the application to a particular\r
-         Web server, and introduces problems of maintainability, scalability, and security.\r
-      </P>\r
-      <P>\r
-         <A NAME="8736"></A> We believe that FastCGI is the most general and flexible strategy for building long-lived\r
-         Web applications.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Separating Application and Server\r
-      </H2>\r
-      <A NAME="8446"></A>\r
-      <P>\r
-         CGI applications must run on the same node as the Web server; FastCGI applications can run on any node that\r
-         can be reached from your Web server using TCP/IP protocols. For example, you might want to run the FastCGI\r
-         application on a high-speed computer server or database engine, and run the Web server on a different node.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         FastCGI &quot;Roles&quot;\r
-      </H2>\r
-      <A NAME="8777"></A>\r
-      <P>\r
-         CGI and FastCGI applications are effective ways to allow an application to act as an extension to the Web\r
-         server. CGI provides no explicit support for different kinds of applications: under CGI, every application\r
-         receives an HTTP request, does something with it, and generates an HTTP response. FastCGI provides explicit\r
-         support for several common &quot;roles&quot; that applications can play.\r
-      </P>\r
-      <P>\r
-         <A NAME="8769"></A> The three roles supported by the WebServer 2.0 are:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <UL>\r
-         <LI CLASS="c2">\r
-            <A NAME="8409"></A>\r
-         </LI>\r
-         <LI>\r
-            Responder <A NAME="8410"></A>\r
-         </LI>\r
-         <LI>\r
-            Filter <A NAME="8411"></A>\r
-         </LI>\r
-         <LI>\r
-            Authorizer\r
-         </LI>\r
-      </UL>\r
-      <H3>\r
-         Responder Applications\r
-      </H3>\r
-      <A NAME="8679"></A>\r
-      <P>\r
-         A <EM>responder</EM> application is the most basic kind of FastCGI application: it receives the information\r
-         associated with an HTTP request and generates an HTTP response. Responder is the role most similar to\r
-         traditional CGI programming, and most FastCGI applications are responders.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H3>\r
-         Filter Applications\r
-      </H3>\r
-      <A NAME="8681"></A>\r
-      <P>\r
-         A <EM>filter</EM> FastCGI application receives 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 NAME="8421"></A> With filter applications, the system administrator maps a particular MIME-type to a\r
-         particular filter FastCGI application. When a client requests a URL with that MIME-type, the Web server\r
-         invokes the filter application, which processes the file at the specified URL and sends a response (usually\r
-         HTML text) back to the client.\r
-      </P>\r
-      <P>\r
-         <A NAME="8422"></A> For example, suppose you write a filter FastCGI application that converts SGML text to\r
-         HTML, and map the extension .sgml (MIME-type SGML) to your filter FastCGI application. Now, suppose that a\r
-         user requests the following URL:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="8423">/www.aerjug.com/docs/chap1.sgml\r
-</A>\r
-</PRE>\r
-      <A NAME="8424"></A>\r
-      <P>\r
-         Given this URL, the Web server passes <CODE>chap1.sgml</CODE> as input to your filter FastCGI application,\r
-         which processes <CODE>chap1.sgml</CODE> and returns an HTML version of it to the requesting client.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H3>\r
-         Authorizer Applications\r
-      </H3>\r
-      <A NAME="8426"></A>\r
-      <P>\r
-         An <EM>authorizer</EM> FastCGI application receives the information in an HTTP request header and generates a\r
-         decision whether to authorize the request.\r
-      </P>\r
-      <P>\r
-         <A NAME="8428"></A> To mark a FastCGI application as having the authorizer role, the system administrator\r
-         names the application inside the server configuration file, using a directive called\r
-         <CODE>AuthorizeRegion</CODE>. (See the Open Market Web Server manual for information on server configuration\r
-         directives.)\r
-      </P>\r
-      <P>\r
-         <A NAME="8429"></A> When a client requests a URL that meets the <CODE>AuthorizeRegion</CODE> criteria, the Web\r
-         server calls your authorizer FastCGI application. If your application grants authorization (by returning a\r
-         response code of 200), the Web server resumes execution of commands in the <CODE>AuthorizeRegion</CODE>\r
-         section. If your application denies authorization (by returning any other response code), the Web server stops\r
-         processing subsequent commands in the <CODE>AuthorizeRegion</CODE> section, and returns the response from your\r
-         FastCGI application to the client.\r
-      </P>\r
-      <P>\r
-         <A NAME="8431"></A> Authorizer applications can return headers containing environment variables. Other CGI or\r
-         FastCGI programs accessing this request (including other authorizers) can access these environment variables.\r
-         The headers must have the following format:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="8432">Variable-<EM>name</EM>: <EM>value</EM>\r
-</A>\r
-</PRE>\r
-      <A NAME="8433"></A>\r
-      <P>\r
-         For example, the following header\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="8434">Variable-AUTH_METHOD: database lookup\r
-</A>\r
-</PRE>\r
-      <A NAME="8435"></A>\r
-      <P>\r
-         causes the environment variable <CODE>AUTH_METHOD</CODE> to be set to <CODE>&quot;database lookup&quot;</CODE>\r
-         for this request. Other CGI or FastCGI applications running on this request can access the value of\r
-         <CODE>AUTH_METHOD</CODE>.\r
-      </P>\r
-      <P>\r
-         <A NAME="8437"></A> Authorizer applications cannot successfully read from standard input. Any attempts to read\r
-         from standard input result in an immediate EOF.\r
-      </P>\r
-      <P>\r
-         <A NAME="8438"></A> All data that authorizer applications write to standard error will get written to the\r
-         traditional server error logs.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         Writing FastCGI Applications\r
-      </H1>\r
-      <A NAME="9301"></A>\r
-      <P>\r
-         The work involved in writing a FastCGI application depends in large part on the I/O libraries that you use.\r
-         This manual describes how to write FastCGI applications in terms of the Open Market libraries, which are\r
-         available for C, Perl, and Tcl. FastCGI is an open standard and you are welcome to build your own libraries\r
-         for other languages as well, but this manual focuses on building FastCGI applications in the context of the\r
-         Open Market libraries.\r
-      </P>\r
-      <P>\r
-         <A NAME="9443"></A>\r
-      </P>\r
-      <P>\r
-         <A NAME="9450"></A> In general, the goal of the libraries is to make the job of writing a FastCGI application\r
-         as much like writing a CGI application as possible. For example, you use the same techniques for query string\r
-         decoding, HTML output to stdout, use of environment variables, and so on. When you use our libraries, porting\r
-         CGI applications to FastCGI is mostly a matter of restructuring the code to take advantage of FastCGI features\r
-         and libraries.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Code Structure\r
-      </H2>\r
-      <A NAME="9470"></A>\r
-      <P>\r
-         The main task of converting a CGI program into a FastCGI program is separating the initialization code from\r
-         the code that needs to run for each request. The structure should look something like this:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="9471">Initialization code\r
-</A>\r
-<A NAME="9472">Start of response loop\r
-</A>\r
- <A NAME="9473">  body of response loop\r
-</A>\r
-<A NAME="9474">End of response loop\r
-</A>\r
-</PRE>\r
-      <A NAME="9475"></A>\r
-      <P>\r
-         The <EM>initialization code</EM> is run exactly once, when the application is initialized. Initialization code\r
-         usually performs time-consuming operations such as opening databases or calculating values for tables or\r
-         bitmaps.\r
-      </P>\r
-      <P>\r
-         <A NAME="9477"></A> The <EM>response loop</EM> runs continuously, waiting for client requests to arrive. The\r
-         loop starts with a call to <CODE>FCGI_Accept</CODE>, a routine in the FastCGI library. The\r
-         <CODE>FCGI_Accept</CODE> routine blocks program execution until a client requests the FastCGI application.\r
-         When a client request comes in, <CODE>FCGI_Accept</CODE> unblocks, runs one iteration of the response loop\r
-         body, and then blocks again waiting for another client request. The loop terminates only when the system\r
-         administrator or the Web server kills the FastCGI application.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Initial Environment Variables\r
-      </H2>\r
-      <A NAME="9786"></A>\r
-      <P>\r
-         When a FastCGI process starts up, it has not yet accepted a request, and therefore none of the CGI environment\r
-         variables are set.\r
-      </P>\r
-      <P>\r
-         <A NAME="9787"></A> You set the initial environment of a FastCGI process started by the <CODE>AppClass</CODE>\r
-         directive using the <CODE>-initial-env</CODE> option. The process would use this environment to configure its\r
-         options and locate files or databases.\r
-      </P>\r
-      <P>\r
-         <A NAME="9829"></A> In FastCGI processes started by the <CODE>AppClass</CODE> directive with the -affinity\r
-         option, the <CODE>FCGI_PROCESS_ID</CODE> variable is set in the initial environment (not in the environment of\r
-         a request). <CODE>FCGI_PROCESS_ID</CODE> is a decimal number in the range 0 to N - 1 where N is the number of\r
-         processes (argument to the <CODE>-processes</CODE> option to <CODE>AppClass</CODE>). The process would use\r
-         <CODE>FCGI_PROCESS_ID</CODE> in conjunction with other variables to locate session-related files or databases\r
-         during restart.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Per-Request Environment Variables\r
-      </H2>\r
-      <A NAME="9481"></A>\r
-      <P>\r
-         In general, FastCGI uses the same per-request environment variables as CGI, and you access the values of\r
-         environment variables in FastCGI applications just as you would in CGI applications. The only differences are\r
-         as follows:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <UL>\r
-         <LI CLASS="c2">\r
-            <A NAME="9483"></A>\r
-         </LI>\r
-         <LI>\r
-            In Authorizer FastCGI applications, the Web server unsets the <CODE>PATH_INFO</CODE>,\r
-            <CODE>PATH_TRANSLATED</CODE>, and <CODE>CONTENT_LENGTH</CODE> variables. <A NAME="9484"></A>\r
-         </LI>\r
-         <LI>\r
-            In Filter FastCGI applications, the Web server sets two additional environment variables: \r
-            <UL>\r
-               <LI CLASS="c2">\r
-                  <A NAME="9486"></A>\r
-               </LI>\r
-               <LI>\r
-                  <CODE>FILE_LAST_MOD</CODE>: The Web server sets <CODE>FILE_LAST_MOD</CODE> to the date and time that\r
-                  filter input file was last modified. The format is the number of seconds since midnight (UTC),\r
-                  January 1, 1970. <A NAME="9488"></A>\r
-               </LI>\r
-               <LI>\r
-                  <CODE>FCGI_DATA_LENGTH</CODE>: The application reads at most <CODE>FCGI_DATA_LENGTH</CODE> bytes from\r
-                  the data stream before receiving the end-of-stream indication.\r
-               </LI>\r
-            </UL>\r
-            <A NAME="9490"></A>\r
-         </LI>\r
-         <LI>\r
-            FastCGI sets <CODE>FCGI_ROLE</CODE> for each request to <CODE>RESPONDER</CODE>, <CODE>AUTHORIZER</CODE>, or\r
-            <CODE>FILTER</CODE>.\r
-         </LI>\r
-      </UL>\r
-      <H2>\r
-         Building FastCGI Applications in C\r
-      </H2>\r
-      <A NAME="9049"></A>\r
-      <P>\r
-         The Software Development Toolkit that accompanies WebServer 2.0 contains two libraries, fcgi_stdio and\r
-         fcgiapp, for building FastCGI applications in C.\r
-      </P>\r
-      <P>\r
-         <A NAME="9723"></A> The fcgi_stdio library implements our philosophy of making FastCGI applications similar to\r
-         CGI applications, and provides full binary compatibility between FastCGI applications and CGI applications:\r
-         you can run the same C binary as either CGI or FastCGI.\r
-      </P>\r
-      <P>\r
-         <A NAME="9545"></A> The fcgiapp library is more specific to FastCGI, and doesn&#39;t attempt the veneer of\r
-         CGI.\r
-      </P>\r
-      <P>\r
-         <A NAME="9731"></A> We recommend that you use the fcgi_stdio library, and this manual describes the routines\r
-         in that library. The documentation for the fcgiapp library is in the code in the development kit.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Building FastCGI Applications in Perl\r
-      </H2>\r
-      <A NAME="9581"></A>\r
-      <P>\r
-         To build FastCGI applications in Perl, you need a FastCGI-savvy version of Perl, plus the FastCGI extension to\r
-         Perl. We build FastCGI-savvy versions of the Perl interpreter for several common platforms and make them\r
-         available on our Website. For details and examples, see Chapter <A HREF="ch3perl.htm#3659">3, &quot;Developing\r
-         FastCGI Applications in Perl,&quot; on page 17</A>.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         Building FastCGI Applications in Tcl\r
-      </H2>\r
-      <A NAME="9586"></A>\r
-      <P>\r
-         To build FastCGI applications in Tcl, you need a FastCGI-savvy version of Tcl. We build FastCGI-savvy versions\r
-         of the Tcl interpreter for several common platforms and make them available on our Website. For details and\r
-         examples, see Chapter <A HREF="ch4tcl.htm#3659">4, &quot;Developing FastCGI Applications in Tcl,&quot; on page\r
-         19</A>.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         Implementation Details\r
-      </H1>\r
-      <A NAME="8066"></A>\r
-      <P>\r
-         The FastCGI application libraries are designed to shield you from the details of the FastCGI design. This\r
-         section is designed for the curious reader who would like some low-level understanding. If you are not curious\r
-         about the implementation, you can happily skip this section.\r
-      </P>\r
-      <P>\r
-         <A NAME="8554"></A> As shown in the following figure, CGI applications use the three standard POSIX streams\r
-         (<CODE>stdin</CODE>, <CODE>stdout</CODE>, and <CODE>stderr</CODE>), plus environment variables, to communicate\r
-         with an HTTP server.\r
-      </P>\r
-      <P>\r
-         <A NAME="8359"></A> <IMG ALT="error-file:TidyOut.log" SRC="ch1intra.gif">\r
-      </P>\r
-      <P>\r
-         <A NAME="4295"></A>\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H5>\r
-         Figure 1:  Flow of Data in CGI\r
-      </H5>\r
-      <A NAME="9001"></A>\r
-      <P>\r
-         The fundamental difference between FastCGI and CGI is that FastCGI applications are long-lived, which means\r
-         that the Web Server needs to rendezvous with a running application, rather than starting the application in\r
-         order to explicitly communicate with it.\r
-      </P>\r
-      <P>\r
-         <A NAME="9110"></A> The FastCGI implementation basically creates a bidirectional connection between two\r
-         processes that have no relationship. FastCGI uses a single connection for all the data associated with an\r
-         application -- stdin, stdout, stderr, and environment variables. The data on the connection is encapsulated\r
-         using a FastCGI protocol that allows stdin and the environment variables to share the same half connection (on\r
-         the way in) and stdout and stderr to share the half connection (on the way out).\r
-      </P>\r
-      <P>\r
-         <A NAME="9020"></A> On the input side, the FastCGI application receives data on the connection, unpacks it to\r
-         separate stdin from the environment variables and then invokes the application. On the output side, FastCGI\r
-         wraps stdout and stderr with appropriate protocol headers, and sends the encapsulated data out to the server.\r
-      </P>\r
-      <P>\r
-         <A NAME="9032"></A> Since a FastCGI application does not always run on the same node as the HTTP server, we\r
-         support two implementations of the connection: a <EM>stream pipe</EM><A HREF="#9645"><SUP>1</SUP></A>, for\r
-         communications on the same machine, and TCP streams, for communication when the client and the server are on\r
-         different machines.\r
-      </P>\r
-      <P>\r
-         <A NAME="8576"></A> <IMG ALT="error-file:TidyOut.log" SRC="ch1inta1.gif">\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H5>\r
-         Figure 2:  Flow of Data in FastCGI when server and application are on different machines\r
-      </H5>\r
-      <H2>\r
-         The fcgi_stdio Library: I/O Compatibility\r
-      </H2>\r
-      <A NAME="8977"></A>\r
-      <P>\r
-         The implementation for I/O compatibility is that the library <CODE>fcgi_stdio.h</CODE> contains macros to\r
-         translate the types and procedures defined in stdio.h into the appropriate FastCGI calls. For example,\r
-         consider a FastCGI program written in C containing the following line of code:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="5877">fprintf(stdout, &quot;&lt;H2&gt;Aerobic Juggling&lt;/H2&gt;/n&quot;);\r
-</A>\r
-</PRE>\r
-      <A NAME="9659"></A> <CODE>fcgi_stdio.h</CODE>\r
-      <P>\r
-         header file contains the macro\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="6403">#define fprintf FCGI_fprintf\r
-</A>\r
-</PRE>\r
-      <A NAME="6402"></A>\r
-      <P>\r
-         So the preprocessor translates the <CODE>fprintf</CODE> call into the following call:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="6411">FCGI_fprintf(stdout, &quot;&lt;H2&gt;Aerobic Juggling&lt;/H2&gt;/n&quot;);\r
-</A>\r
-</PRE>\r
-      <A NAME="5888"></A> <CODE>FCGI_fprintf</CODE>\r
-      <P>\r
-         takes the same arguments as <CODE>fprintf</CODE>.\r
-      </P>\r
-      <P>\r
-         <A NAME="9664"></A> The implementation of FCGI_fprintf tests the file to see if it is a normal C stream or a\r
-         FastCGI stream, and calls the appropriate implementation.\r
-      </P>\r
-      <P>\r
-         <A NAME="6463"></A> The <CODE>fcgi_stdio.h</CODE> header file contains macros to translate calls to all ISO\r
-         stdio.h routines (and all conventional Posix additions, such as <CODE>fileno</CODE>, <CODE>fdopen</CODE>,\r
-         <CODE>popen</CODE>, and <CODE>pclose</CODE>) into their FastCGI equivalents.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H2>\r
-         The fcgi_stdio Library: Binary compatibility\r
-      </H2>\r
-      <A NAME="9579"></A>\r
-      <P>\r
-         The fcgi_stdio library provides full binary compatibility between FastCGI applications and CGI applications:\r
-         you can run the same C binary as either CGI or FastCGI.\r
-      </P>\r
-      <P>\r
-         <A NAME="9580"></A> The implementation is in FCGI_Accept: the FCGI_Accept function tests its environment to\r
-         determine whether the application was invoked as a CGI program or an FastCGI program. If it was invoked as a\r
-         CGI program, the request loop will satisfy a single client request and then exit, producing CGI behavior.\r
-      </P>\r
-      <P>\r
-         <A NAME="8957"></A>\r
-      </P>\r
-      <P>\r
-      </P>\r
-      <HR>\r
-      <BR>\r
-       <A HREF="cover.htm">[Top]</A> <A HREF="ap_guide.htm">[Prev]</A> <A HREF="ch2c.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       <SUP>1</SUP><A NAME="9645"></A>\r
-      <P>\r
-         UNIX Network Programming, W. Richard Stevens, 1990 Prentice-Hall, Section 7.9\r
-      </P>\r
-      <P>\r
-         <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->\r
-         <!-- -->\r
-         <!-- For more information on how this document, and how the rest of -->\r
-         <!-- this server was created, email yourEmail@xyzcorp.com -->\r
-         <!-- -->\r
-         <!-- Last updated: 04/15/96 08:00:13 -->\r
-      </P>\r
-   </BODY>\r
-</HTML>\r
-\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         FastCGI Programmer&#39;s Guide - Chapter 1, The Fast Common Gateway Interface
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #ffffff;
+ }
+ li.c2 {list-style: none}
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <A HREF="cover.htm">[Top]</A> <A HREF="ap_guide.htm">[Prev]</A> <A HREF="ch2c.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       <A NAME="9432"></A>
+      <DIV CLASS="c1">
+         <H1>
+            1 The Fast Common<BR>
+            Gateway Interface
+         </H1>
+      </DIV>
+      <A NAME="7982"></A>
+      <P>
+         The Fast Common Gateway Interface (FastCGI) is an enhancement to the existing CGI (Common Gateway Interface),
+         which is a standard for interfacing external applications with Web servers.
+      </P>
+      <P>
+         <A NAME="8373"></A> FastCGI is a proposed open standard and we expect both free and commercial Web servers to
+         support it. FastCGI is included in Open Market WebServer and Secure WebServer, versions 2.0 and greater.
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         Advantages of FastCGI
+      </H1>
+      <A NAME="8369"></A>
+      <P>
+         FastCGI extends and enhances the CGI model in several ways:
+      </P>
+      <BR>
+      <BR>
+      <UL>
+         <LI CLASS="c2">
+            <A NAME="7832"></A>
+         </LI>
+         <LI>
+            FastCGI enables applications to persist between client requests, eliminating application start up overhead
+            and allowing the application to maintain state between client calls. <A NAME="7995"></A>
+         </LI>
+         <LI>
+            FastCGI enables applications to reside on remote systems (rather than having to reside on the same system
+            as the Web server) <A NAME="7997"></A>
+         </LI>
+         <LI>
+            FastCGI enables additional flexibility in application functionality, with explicit support for applications
+            that do client authentication and filtering of input.
+         </LI>
+      </UL>
+      <H2>
+         Long-lived Applications
+      </H2>
+      <A NAME="8458"></A>
+      <P>
+         CGI applications are ephemeral and short-lived: each time a client requests a CGI application, the server asks
+         the operating system to spawn a new CGI process. After the CGI process satisfies the request, the server kills
+         it. The server spawns and subsequently kills a new process for each client request.
+      </P>
+      <P>
+         <A NAME="8459"></A> FastCGI applications are long-lived, and can persist between client calls. The server
+         spawns the FastCGI process once and it continues to run and satisfy client requests until it is explicitly
+         terminated. You can also ask the Web server to start multiple copies of a FastCGI application, if you expect
+         that concurrent processing will improve the application&#39;s performance.
+      </P>
+      <P>
+         <A NAME="5761"></A> Long-lived applications have two important advantages over short-lived applications:
+      </P>
+      <BR>
+      <BR>
+      <UL>
+         <LI CLASS="c2">
+            <A NAME="7138"></A>
+         </LI>
+         <LI>
+            A short-lived application pays start up overhead on every request; a long-lived application spreads the
+            overhead over many requests. For an application that has a heavy start up cost, such as opening a database,
+            doing initialization on every call can be very inefficient. Reinitializing for every client is also very
+            inefficient for Perl programs, where the interpreter reads through the entire program before executing any
+            of it. <A NAME="9204"></A>
+         </LI>
+         <LI>
+            A long-lived application can cache information in memory between requests, allowing it to respond more
+            quickly to later requests.
+         </LI>
+      </UL>
+      <A NAME="8733"></A>
+      <P>
+         FastCGI is not the only way to get a long-lived application on the Web, however. For example, there are many
+         existing search engines that are implemented as long-lived applications.
+      </P>
+      <P>
+         <A NAME="8734"></A> In most cases, these applications rely on customized Web servers. In other words, since
+         most Web servers do not support long-lived applications, a programmer must code this support into a Web
+         server. This approach requires a tremendous amount of work and also ties the application to a particular
+         server.
+      </P>
+      <P>
+         <A NAME="8735"></A> Another way to get a long-lived application is to write code that calls routines from the
+         Web server&#39;s API. This alternative involves a lot of extra coding, ties the application to a particular
+         Web server, and introduces problems of maintainability, scalability, and security.
+      </P>
+      <P>
+         <A NAME="8736"></A> We believe that FastCGI is the most general and flexible strategy for building long-lived
+         Web applications.
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Separating Application and Server
+      </H2>
+      <A NAME="8446"></A>
+      <P>
+         CGI applications must run on the same node as the Web server; FastCGI applications can run on any node that
+         can be reached from your Web server using TCP/IP protocols. For example, you might want to run the FastCGI
+         application on a high-speed computer server or database engine, and run the Web server on a different node.
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         FastCGI &quot;Roles&quot;
+      </H2>
+      <A NAME="8777"></A>
+      <P>
+         CGI and FastCGI applications are effective ways to allow an application to act as an extension to the Web
+         server. CGI provides no explicit support for different kinds of applications: under CGI, every application
+         receives an HTTP request, does something with it, and generates an HTTP response. FastCGI provides explicit
+         support for several common &quot;roles&quot; that applications can play.
+      </P>
+      <P>
+         <A NAME="8769"></A> The three roles supported by the WebServer 2.0 are:
+      </P>
+      <BR>
+      <BR>
+      <UL>
+         <LI CLASS="c2">
+            <A NAME="8409"></A>
+         </LI>
+         <LI>
+            Responder <A NAME="8410"></A>
+         </LI>
+         <LI>
+            Filter <A NAME="8411"></A>
+         </LI>
+         <LI>
+            Authorizer
+         </LI>
+      </UL>
+      <H3>
+         Responder Applications
+      </H3>
+      <A NAME="8679"></A>
+      <P>
+         A <EM>responder</EM> application is the most basic kind of FastCGI application: it receives the information
+         associated with an HTTP request and generates an HTTP response. Responder is the role most similar to
+         traditional CGI programming, and most FastCGI applications are responders.
+      </P>
+      <BR>
+      <BR>
+      <H3>
+         Filter Applications
+      </H3>
+      <A NAME="8681"></A>
+      <P>
+         A <EM>filter</EM> FastCGI application receives the information associated with an HTTP request, plus an extra
+         stream of data from a file stored on the Web server, and generates a &quot;filtered&quot; version of the data
+         stream as an HTTP response.
+      </P>
+      <P>
+         <A NAME="8421"></A> With filter applications, the system administrator maps a particular MIME-type to a
+         particular filter FastCGI application. When a client requests a URL with that MIME-type, the Web server
+         invokes the filter application, which processes the file at the specified URL and sends a response (usually
+         HTML text) back to the client.
+      </P>
+      <P>
+         <A NAME="8422"></A> For example, suppose you write a filter FastCGI application that converts SGML text to
+         HTML, and map the extension .sgml (MIME-type SGML) to your filter FastCGI application. Now, suppose that a
+         user requests the following URL:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="8423">/www.aerjug.com/docs/chap1.sgml
+</A>
+</PRE>
+      <A NAME="8424"></A>
+      <P>
+         Given this URL, the Web server passes <CODE>chap1.sgml</CODE> as input to your filter FastCGI application,
+         which processes <CODE>chap1.sgml</CODE> and returns an HTML version of it to the requesting client.
+      </P>
+      <BR>
+      <BR>
+      <H3>
+         Authorizer Applications
+      </H3>
+      <A NAME="8426"></A>
+      <P>
+         An <EM>authorizer</EM> FastCGI application receives the information in an HTTP request header and generates a
+         decision whether to authorize the request.
+      </P>
+      <P>
+         <A NAME="8428"></A> To mark a FastCGI application as having the authorizer role, the system administrator
+         names the application inside the server configuration file, using a directive called
+         <CODE>AuthorizeRegion</CODE>. (See the Open Market Web Server manual for information on server configuration
+         directives.)
+      </P>
+      <P>
+         <A NAME="8429"></A> When a client requests a URL that meets the <CODE>AuthorizeRegion</CODE> criteria, the Web
+         server calls your authorizer FastCGI application. If your application grants authorization (by returning a
+         response code of 200), the Web server resumes execution of commands in the <CODE>AuthorizeRegion</CODE>
+         section. If your application denies authorization (by returning any other response code), the Web server stops
+         processing subsequent commands in the <CODE>AuthorizeRegion</CODE> section, and returns the response from your
+         FastCGI application to the client.
+      </P>
+      <P>
+         <A NAME="8431"></A> Authorizer applications can return headers containing environment variables. Other CGI or
+         FastCGI programs accessing this request (including other authorizers) can access these environment variables.
+         The headers must have the following format:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="8432">Variable-<EM>name</EM>: <EM>value</EM>
+</A>
+</PRE>
+      <A NAME="8433"></A>
+      <P>
+         For example, the following header
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="8434">Variable-AUTH_METHOD: database lookup
+</A>
+</PRE>
+      <A NAME="8435"></A>
+      <P>
+         causes the environment variable <CODE>AUTH_METHOD</CODE> to be set to <CODE>&quot;database lookup&quot;</CODE>
+         for this request. Other CGI or FastCGI applications running on this request can access the value of
+         <CODE>AUTH_METHOD</CODE>.
+      </P>
+      <P>
+         <A NAME="8437"></A> Authorizer applications cannot successfully read from standard input. Any attempts to read
+         from standard input result in an immediate EOF.
+      </P>
+      <P>
+         <A NAME="8438"></A> All data that authorizer applications write to standard error will get written to the
+         traditional server error logs.
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         Writing FastCGI Applications
+      </H1>
+      <A NAME="9301"></A>
+      <P>
+         The work involved in writing a FastCGI application depends in large part on the I/O libraries that you use.
+         This manual describes how to write FastCGI applications in terms of the Open Market libraries, which are
+         available for C, Perl, and Tcl. FastCGI is an open standard and you are welcome to build your own libraries
+         for other languages as well, but this manual focuses on building FastCGI applications in the context of the
+         Open Market libraries.
+      </P>
+      <P>
+         <A NAME="9443"></A>
+      </P>
+      <P>
+         <A NAME="9450"></A> In general, the goal of the libraries is to make the job of writing a FastCGI application
+         as much like writing a CGI application as possible. For example, you use the same techniques for query string
+         decoding, HTML output to stdout, use of environment variables, and so on. When you use our libraries, porting
+         CGI applications to FastCGI is mostly a matter of restructuring the code to take advantage of FastCGI features
+         and libraries.
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Code Structure
+      </H2>
+      <A NAME="9470"></A>
+      <P>
+         The main task of converting a CGI program into a FastCGI program is separating the initialization code from
+         the code that needs to run for each request. The structure should look something like this:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="9471">Initialization code
+</A>
+<A NAME="9472">Start of response loop
+</A>
+ <A NAME="9473">  body of response loop
+</A>
+<A NAME="9474">End of response loop
+</A>
+</PRE>
+      <A NAME="9475"></A>
+      <P>
+         The <EM>initialization code</EM> is run exactly once, when the application is initialized. Initialization code
+         usually performs time-consuming operations such as opening databases or calculating values for tables or
+         bitmaps.
+      </P>
+      <P>
+         <A NAME="9477"></A> The <EM>response loop</EM> runs continuously, waiting for client requests to arrive. The
+         loop starts with a call to <CODE>FCGI_Accept</CODE>, a routine in the FastCGI library. The
+         <CODE>FCGI_Accept</CODE> routine blocks program execution until a client requests the FastCGI application.
+         When a client request comes in, <CODE>FCGI_Accept</CODE> unblocks, runs one iteration of the response loop
+         body, and then blocks again waiting for another client request. The loop terminates only when the system
+         administrator or the Web server kills the FastCGI application.
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Initial Environment Variables
+      </H2>
+      <A NAME="9786"></A>
+      <P>
+         When a FastCGI process starts up, it has not yet accepted a request, and therefore none of the CGI environment
+         variables are set.
+      </P>
+      <P>
+         <A NAME="9787"></A> You set the initial environment of a FastCGI process started by the <CODE>AppClass</CODE>
+         directive using the <CODE>-initial-env</CODE> option. The process would use this environment to configure its
+         options and locate files or databases.
+      </P>
+      <P>
+         <A NAME="9829"></A> In FastCGI processes started by the <CODE>AppClass</CODE> directive with the -affinity
+         option, the <CODE>FCGI_PROCESS_ID</CODE> variable is set in the initial environment (not in the environment of
+         a request). <CODE>FCGI_PROCESS_ID</CODE> is a decimal number in the range 0 to N - 1 where N is the number of
+         processes (argument to the <CODE>-processes</CODE> option to <CODE>AppClass</CODE>). The process would use
+         <CODE>FCGI_PROCESS_ID</CODE> in conjunction with other variables to locate session-related files or databases
+         during restart.
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Per-Request Environment Variables
+      </H2>
+      <A NAME="9481"></A>
+      <P>
+         In general, FastCGI uses the same per-request environment variables as CGI, and you access the values of
+         environment variables in FastCGI applications just as you would in CGI applications. The only differences are
+         as follows:
+      </P>
+      <BR>
+      <BR>
+      <UL>
+         <LI CLASS="c2">
+            <A NAME="9483"></A>
+         </LI>
+         <LI>
+            In Authorizer FastCGI applications, the Web server unsets the <CODE>PATH_INFO</CODE>,
+            <CODE>PATH_TRANSLATED</CODE>, and <CODE>CONTENT_LENGTH</CODE> variables. <A NAME="9484"></A>
+         </LI>
+         <LI>
+            In Filter FastCGI applications, the Web server sets two additional environment variables: 
+            <UL>
+               <LI CLASS="c2">
+                  <A NAME="9486"></A>
+               </LI>
+               <LI>
+                  <CODE>FILE_LAST_MOD</CODE>: The Web server sets <CODE>FILE_LAST_MOD</CODE> to the date and time that
+                  filter input file was last modified. The format is the number of seconds since midnight (UTC),
+                  January 1, 1970. <A NAME="9488"></A>
+               </LI>
+               <LI>
+                  <CODE>FCGI_DATA_LENGTH</CODE>: The application reads at most <CODE>FCGI_DATA_LENGTH</CODE> bytes from
+                  the data stream before receiving the end-of-stream indication.
+               </LI>
+            </UL>
+            <A NAME="9490"></A>
+         </LI>
+         <LI>
+            FastCGI sets <CODE>FCGI_ROLE</CODE> for each request to <CODE>RESPONDER</CODE>, <CODE>AUTHORIZER</CODE>, or
+            <CODE>FILTER</CODE>.
+         </LI>
+      </UL>
+      <H2>
+         Building FastCGI Applications in C
+      </H2>
+      <A NAME="9049"></A>
+      <P>
+         The Software Development Toolkit that accompanies WebServer 2.0 contains two libraries, fcgi_stdio and
+         fcgiapp, for building FastCGI applications in C.
+      </P>
+      <P>
+         <A NAME="9723"></A> The fcgi_stdio library implements our philosophy of making FastCGI applications similar to
+         CGI applications, and provides full binary compatibility between FastCGI applications and CGI applications:
+         you can run the same C binary as either CGI or FastCGI.
+      </P>
+      <P>
+         <A NAME="9545"></A> The fcgiapp library is more specific to FastCGI, and doesn&#39;t attempt the veneer of
+         CGI.
+      </P>
+      <P>
+         <A NAME="9731"></A> We recommend that you use the fcgi_stdio library, and this manual describes the routines
+         in that library. The documentation for the fcgiapp library is in the code in the development kit.
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Building FastCGI Applications in Perl
+      </H2>
+      <A NAME="9581"></A>
+      <P>
+         To build FastCGI applications in Perl, you need a FastCGI-savvy version of Perl, plus the FastCGI extension to
+         Perl. We build FastCGI-savvy versions of the Perl interpreter for several common platforms and make them
+         available on our Website. For details and examples, see Chapter <A HREF="ch3perl.htm#3659">3, &quot;Developing
+         FastCGI Applications in Perl,&quot; on page 17</A>.
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         Building FastCGI Applications in Tcl
+      </H2>
+      <A NAME="9586"></A>
+      <P>
+         To build FastCGI applications in Tcl, you need a FastCGI-savvy version of Tcl. We build FastCGI-savvy versions
+         of the Tcl interpreter for several common platforms and make them available on our Website. For details and
+         examples, see Chapter <A HREF="ch4tcl.htm#3659">4, &quot;Developing FastCGI Applications in Tcl,&quot; on page
+         19</A>.
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         Implementation Details
+      </H1>
+      <A NAME="8066"></A>
+      <P>
+         The FastCGI application libraries are designed to shield you from the details of the FastCGI design. This
+         section is designed for the curious reader who would like some low-level understanding. If you are not curious
+         about the implementation, you can happily skip this section.
+      </P>
+      <P>
+         <A NAME="8554"></A> As shown in the following figure, CGI applications use the three standard POSIX streams
+         (<CODE>stdin</CODE>, <CODE>stdout</CODE>, and <CODE>stderr</CODE>), plus environment variables, to communicate
+         with an HTTP server.
+      </P>
+      <P>
+         <A NAME="8359"></A> <IMG ALT="error-file:TidyOut.log" SRC="ch1intra.gif">
+      </P>
+      <P>
+         <A NAME="4295"></A>
+      </P>
+      <BR>
+      <BR>
+      <H5>
+         Figure 1:  Flow of Data in CGI
+      </H5>
+      <A NAME="9001"></A>
+      <P>
+         The fundamental difference between FastCGI and CGI is that FastCGI applications are long-lived, which means
+         that the Web Server needs to rendezvous with a running application, rather than starting the application in
+         order to explicitly communicate with it.
+      </P>
+      <P>
+         <A NAME="9110"></A> The FastCGI implementation basically creates a bidirectional connection between two
+         processes that have no relationship. FastCGI uses a single connection for all the data associated with an
+         application -- stdin, stdout, stderr, and environment variables. The data on the connection is encapsulated
+         using a FastCGI protocol that allows stdin and the environment variables to share the same half connection (on
+         the way in) and stdout and stderr to share the half connection (on the way out).
+      </P>
+      <P>
+         <A NAME="9020"></A> On the input side, the FastCGI application receives data on the connection, unpacks it to
+         separate stdin from the environment variables and then invokes the application. On the output side, FastCGI
+         wraps stdout and stderr with appropriate protocol headers, and sends the encapsulated data out to the server.
+      </P>
+      <P>
+         <A NAME="9032"></A> Since a FastCGI application does not always run on the same node as the HTTP server, we
+         support two implementations of the connection: a <EM>stream pipe</EM><A HREF="#9645"><SUP>1</SUP></A>, for
+         communications on the same machine, and TCP streams, for communication when the client and the server are on
+         different machines.
+      </P>
+      <P>
+         <A NAME="8576"></A> <IMG ALT="error-file:TidyOut.log" SRC="ch1inta1.gif">
+      </P>
+      <BR>
+      <BR>
+      <H5>
+         Figure 2:  Flow of Data in FastCGI when server and application are on different machines
+      </H5>
+      <H2>
+         The fcgi_stdio Library: I/O Compatibility
+      </H2>
+      <A NAME="8977"></A>
+      <P>
+         The implementation for I/O compatibility is that the library <CODE>fcgi_stdio.h</CODE> contains macros to
+         translate the types and procedures defined in stdio.h into the appropriate FastCGI calls. For example,
+         consider a FastCGI program written in C containing the following line of code:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="5877">fprintf(stdout, &quot;&lt;H2&gt;Aerobic Juggling&lt;/H2&gt;/n&quot;);
+</A>
+</PRE>
+      <A NAME="9659"></A> <CODE>fcgi_stdio.h</CODE>
+      <P>
+         header file contains the macro
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="6403">#define fprintf FCGI_fprintf
+</A>
+</PRE>
+      <A NAME="6402"></A>
+      <P>
+         So the preprocessor translates the <CODE>fprintf</CODE> call into the following call:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="6411">FCGI_fprintf(stdout, &quot;&lt;H2&gt;Aerobic Juggling&lt;/H2&gt;/n&quot;);
+</A>
+</PRE>
+      <A NAME="5888"></A> <CODE>FCGI_fprintf</CODE>
+      <P>
+         takes the same arguments as <CODE>fprintf</CODE>.
+      </P>
+      <P>
+         <A NAME="9664"></A> The implementation of FCGI_fprintf tests the file to see if it is a normal C stream or a
+         FastCGI stream, and calls the appropriate implementation.
+      </P>
+      <P>
+         <A NAME="6463"></A> The <CODE>fcgi_stdio.h</CODE> header file contains macros to translate calls to all ISO
+         stdio.h routines (and all conventional Posix additions, such as <CODE>fileno</CODE>, <CODE>fdopen</CODE>,
+         <CODE>popen</CODE>, and <CODE>pclose</CODE>) into their FastCGI equivalents.
+      </P>
+      <BR>
+      <BR>
+      <H2>
+         The fcgi_stdio Library: Binary compatibility
+      </H2>
+      <A NAME="9579"></A>
+      <P>
+         The fcgi_stdio library provides full binary compatibility between FastCGI applications and CGI applications:
+         you can run the same C binary as either CGI or FastCGI.
+      </P>
+      <P>
+         <A NAME="9580"></A> The implementation is in FCGI_Accept: the FCGI_Accept function tests its environment to
+         determine whether the application was invoked as a CGI program or an FastCGI program. If it was invoked as a
+         CGI program, the request loop will satisfy a single client request and then exit, producing CGI behavior.
+      </P>
+      <P>
+         <A NAME="8957"></A>
+      </P>
+      <P>
+      </P>
+      <HR>
+      <BR>
+       <A HREF="cover.htm">[Top]</A> <A HREF="ap_guide.htm">[Prev]</A> <A HREF="ch2c.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       <SUP>1</SUP><A NAME="9645"></A>
+      <P>
+         UNIX Network Programming, W. Richard Stevens, 1990 Prentice-Hall, Section 7.9
+      </P>
+      <P>
+         <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->
+         <!-- -->
+         <!-- For more information on how this document, and how the rest of -->
+         <!-- this server was created, email yourEmail@xyzcorp.com -->
+         <!-- -->
+         <!-- Last updated: 04/15/96 08:00:13 -->
+      </P>
+   </BODY>
+</HTML>
+
index fd06499..ebbd421 100755 (executable)
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
-   <HEAD>\r
-      <TITLE>\r
-         FastCGI Programmer&#39;s Guide - Chapter 2, Developing FastCGI Applications in C\r
-      </TITLE>\r
-<STYLE TYPE="text/css">\r
- body {\r
-  background-color: #ffffff;\r
- }\r
- li.c2 {list-style: none}\r
- div.c1 {text-align: center}\r
-</STYLE>\r
-   </HEAD>\r
-   <BODY>\r
-      <A HREF="cover.htm">[Top]</A> <A HREF="ch1intro.htm">[Prev]</A> <A HREF="ch3perl.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       <A NAME="3659"></A>\r
-      <DIV CLASS="c1">\r
-         <H1>\r
-            2 Developing FastCGI<BR>\r
-            Applications in C\r
-         </H1>\r
-      </DIV>\r
-      <A NAME="917"></A>\r
-      <P>\r
-         This chapter explains how to code FastCGI applications in C and how to build them into executables.\r
-      </P>\r
-      <P>\r
-         <A NAME="4230"></A> If you are converting a CGI application into a FastCGI application, in many cases you will\r
-         only need to add a few lines of code. For more complex applications, you may also need to rearrange some code.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         The I/O Libraries\r
-      </H1>\r
-      <A NAME="5384"></A>\r
-      <P>\r
-         The FastCGI Software Development Kit that accompanies Open Market WebServer 2.0 includes I/O libraries to\r
-         simplify the job of converting existing CGI applications to FastCGI or writing new FastCGI applications. There\r
-         are two libraries in the kit: fcgi_stdio and fcgiapp. You must include one of these header files in your\r
-         program:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <UL>\r
-         <LI CLASS="c2">\r
-            <A NAME="5386"></A>\r
-         </LI>\r
-         <LI>\r
-            <CODE>fcgi_stdio.h</CODE> <A NAME="4237"></A>\r
-         </LI>\r
-         <LI>\r
-            <CODE>fcgiapp.h</CODE>\r
-         </LI>\r
-      </UL>\r
-      <A NAME="4199"></A>\r
-      <P>\r
-         The <CODE>fcgi_stdio</CODE> library is a layer on top of the <CODE>fcgiapp</CODE> library, and we recommend\r
-         strongly that you use it, both for converting existing CGI applications and for writing new FastCGI\r
-         applications. The fcgi_stdio library offers several advantages:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <UL>\r
-         <LI CLASS="c2">\r
-            <A NAME="5811"></A>\r
-         </LI>\r
-         <LI>\r
-            Simplicity: there are only 3 new API calls to learn <A NAME="5828"></A>\r
-         </LI>\r
-         <LI>\r
-            Familiarity: If you are converting a CGI application to FastCGI, you will find few changes between CGI and\r
-            FastCGI. We designed our library to make the job of building a FastCGI application as similar as possible\r
-            to that of building a FastCGI application: you use the same environment variables, same techniques for\r
-            parsing query strings, the same I/O routines, and so on. <A NAME="5817"></A>\r
-         </LI>\r
-         <LI>\r
-            Convenience: the library provides full binary compatibility between CGI and FastCGI. That is, you can run\r
-            the same binary as either CGI or FastCGI.\r
-         </LI>\r
-      </UL>\r
-      <A NAME="5399"></A>\r
-      <P>\r
-         The fcgiapp library is more specific to FastCGI, without trying to provide the veneer of familiarity with CGI.\r
-         This manual describes the fcgi_stdio library; the fcgiapp library is documented in the header files that\r
-         accompany the development kit.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         Code Structure\r
-      </H1>\r
-      <A NAME="4240"></A>\r
-      <P>\r
-         To structure code for FastCGI, you separate your code into two sections:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <UL>\r
-         <LI CLASS="c2">\r
-            <A NAME="4200"></A>\r
-         </LI>\r
-         <LI>\r
-            Initialization section, which is executed only once. <A NAME="4201"></A>\r
-         </LI>\r
-         <LI>\r
-            Response loop section, which gets executed every time the FastCGI script gets called.\r
-         </LI>\r
-      </UL>\r
-      <A NAME="4202"></A>\r
-      <P>\r
-         A response loop typically has the following format:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="4203">while (FCGI_Accept() &gt;= 0) {\r
-</A>\r
-<A NAME="4204"># body of response loop\r
-</A>\r
-<A NAME="4205">}\r
-</A>\r
-</PRE>\r
-      <A NAME="4206"></A>\r
-      <P>\r
-         The <CODE>FCGI_Accept</CODE> blocks until a client request comes in, and then returns 0. If there is a system\r
-         failure, or the system administrator terminates the process, Accept will return -1.\r
-      </P>\r
-      <P>\r
-         <A NAME="5852"></A> If the application was invoked as a CGI program, the first call to Accept returns 0 and\r
-         the second always returns -1, producing CGI behavior. (See <A HREF="apaman.htm#95683">&quot;FCGI_Accept\r
-         (3)&quot; on page  21</A> for details.)\r
-      </P>\r
-      <P>\r
-         <A NAME="5909"></A> Also note that the CGI world encourages small scripts, whereas FastCGI encourages\r
-         combining scripts. You may choose to rethink the overall structure of your applications to take better\r
-         advantage of FastCGI performance gains.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         Example 1: TinyFastCGI\r
-      </H1>\r
-      <A NAME="4263">Here is a simple example of a responder FastCGI application written in C:</A><BR>\r
-      <BR>\r
-<PRE>\r
-#include &quot;fcgi_stdio.h&quot; /* fcgi library; put it first*/<BR>\r
-#include &lt;stdlib.h&gt;\r
-\r
-int count;\r
-\r
-void initialize(void)\r
-{\r
-  count=0;\r
-}\r
-\r
-void main(void)\r
-{\r
-/* Initialization. */  \r
-  initialize();\r
-\r
-/* Response loop. */\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! (C, fcgi_stdio library)&lt;/title&gt;&quot;\r
-           &quot;&lt;h1&gt;FastCGI Hello! (C, fcgi_stdio library)&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_HOSTNAME&quot;));\r
-  }\r
-}\r
-</PRE>\r
-      <H1>\r
-         Example 2: Prime Number Generator\r
-      </H1>\r
-      <A NAME="4182"></A>\r
-      <P>\r
-         Consider a responder application that generates the n-th prime number.\r
-      </P>\r
-      <P>\r
-         <A NAME="5217"></A> A CGI application would have no efficient way of solving this problem. For example, if the\r
-         user asks for the 50,000th prime number, a CGI application would have to calculate the first prime number,\r
-         then the second, and so on, up until the 50,000th. The application would then terminate, taking with it all\r
-         its hard-earned calculations. If a client then asks for the 49,000th prime number, the server will have to\r
-         spawn a new CGI application which will have to start calculating prime numbers from scratch.\r
-      </P>\r
-      <P>\r
-         <A NAME="4315"></A> FastCGI applications can be much more efficient at this sort of problem, since they can\r
-         maintain state. A FastCGI application can calculate an extensive table of prime numbers in its initialization\r
-         phase and then keep the table around indefinitely. Whenever a client requests a particular prime number, the\r
-         response loop merely needs to look it up in the table.\r
-      </P>\r
-      <P>\r
-         <A NAME="4343"></A> Here is the code for the prime number example:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-#include &quot;fcgi_stdio.h&quot;\r
-#include &lt;stdlib.h&gt;\r
-#include &lt;string.h&gt;\r
-\r
-#define POTENTIALLY_PRIME 0\r
-#define COMPOSITE 1\r
-#define VALS_IN_SIEVE_TABLE 1000000\r
-#define MAX_NUMBER_OF_PRIME_NUMBERS 78600 \r
-\r
-/* All initialized to POTENTIALLY_PRIME */\r
-long int  sieve_table[VALS_IN_SIEVE_TABLE]; \r
-long int  prime_table[MAX_NUMBER_OF_PRIME_NUMBERS];  \r
-/* Use Sieve of Erastothenes method of building \r
-   a prime number table. */\r
-void\r
-initialize_prime_table(void)\r
-{\r
- long int prime_counter=1;\r
- long int current_prime=2, c, d; \r
-  \r
-  prime_table[prime_counter]=current_prime;\r
-\r
-  while (current_prime &lt; VALS_IN_SIEVE_TABLE)   {\r
-   /* Mark off composite numbers. */\r
-     for (c = current_prime; c &lt;= VALS_IN_SIEVE_TABLE; \r
-          c += current_prime)  {\r
-        sieve_table[c] = COMPOSITE;  \r
-     }\r
-\r
-   /* Find the next prime number. */\r
-     for (d=current_prime+1; sieve_table[d] == COMPOSITE; d++); \r
-   /* Put the new prime number into the table. */ \r
-     prime_table[++prime_counter]=d; \r
-     current_prime=d;\r
-  }\r
-}\r
-\r
-\r
-void main(void)\r
-{\r
-    char *query_string;\r
-    long int n;\r
-\r
-    initialize_prime_table();\r
-\r
-    while(FCGI_Accept() &gt;= 0) {\r
-        /*\r
-         * Produce the necessary HTTP header.\r
-         */\r
-        printf(&quot;Content-type: text/html\r\n&quot;\r
-               &quot;\r\n&quot;);\r
-        /*\r
-         * Produce the constant part of the HTML document.\r
-         */\r
-        printf(&quot;&lt;title&gt;Prime FastCGI&lt;/title&gt;\n&quot;\r
-               &quot;&lt;h1&gt;Prime FastCGI&lt;/h1&gt;\n&quot;);\r
-        /*\r
-         * Read the query string and produce the variable part\r
-         * of the HTML document.\r
-         */\r
-        query_string = getenv(&quot;QUERY_STRING&quot;);\r
-        if(query_string == NULL) {\r
-            printf(&quot;Usage: Specify a positive number in the query string.\n&quot;);\r
-        } else {\r
-            query_string = strchr(query_string, `=&#39;) + 1;\r
-            n = strtol(query_string);\r
-            if(n &lt; 1) {\r
-                printf(&quot;The query string `%s&#39; is not a positive number.\n&quot;,\r
-                       query_string);\r
-            } else if(n &gt; MAX_NUMBER_OF_PRIME_NUMBERS) {\r
-                printf(&quot;The number %d is too large for this program.\n&quot;, n);\r
-            } else\r
-                printf(&quot;The %ldth prime number is %ld.\n&quot;, prime_table[n]);\r
-            }\r
-        }\r
-    } /* while FCGI_Accept */\r
-}\r
-</PRE>\r
-      <A NAME="5349"></A>\r
-      <P>\r
-         This application has a noticeable start up cost while it initializes the table, but subsequent accesses are\r
-         fast.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         Building\r
-      </H1>\r
-      <A NAME="4630"></A>\r
-      <P>\r
-         This section explains how to build and debug FastCGI applications written in C.\r
-      </P>\r
-      <P>\r
-         <A NAME="4629"></A> The C preprocessor needs to know the location of the <CODE>fcgi_stdio.h</CODE> header\r
-         file, which is at the following pathname:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="4642"><EM>$toolkit</EM>/include/fcgi_stdio.h\r
-</A>\r
-</PRE>\r
-      <A NAME="4645"></A>\r
-      <P>\r
-         where <EM>$toolkit</EM> symbolizes the directory in which you have installed the Software Development Kit for\r
-         FastCGI.\r
-      </P>\r
-      <P>\r
-         <A NAME="4760"></A> The linker needs to know the location of the <CODE>libfcgi.a</CODE> library file, which is\r
-         at the following pathname:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="4647"><EM>$toolkit</EM>/libfcgi/libfcgi.a \r
-</A>\r
-</PRE>\r
-      <A NAME="4648"></A>\r
-      <P>\r
-         If your linker does not search the Berkeley socket library, then you must add linker directives to force this\r
-         search.\r
-      </P>\r
-      <P>\r
-         <A NAME="4773"></A> We provide a sample application <CODE>Makefile</CODE> at the following pathname:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="4649"><EM>$toolkit</EM>/examples/Makefile\r
-</A>\r
-</PRE>\r
-      <A NAME="4652"></A>\r
-      <P>\r
-         This <CODE>Makefile</CODE> contains the necessary rules and pathnames to build the C FastCGI applications\r
-         accompanying the toolkit. To build all the applications, type:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="4653">$ ./configure<BR>\r
-$ make \r
-</A>\r
-</PRE>\r
-      <H1>\r
-         Memory Leaks\r
-      </H1>\r
-      <A NAME="4178"></A>\r
-      <P>\r
-         Memory leaks are seldom a problem in CGI programming because CGI applications rarely run long enough to be\r
-         concerned with leaks. However, memory leaks can become a problem in FastCGI applications, particularly if each\r
-         call to a popular FastCGI application causes additional memory to leak.\r
-      </P>\r
-      <P>\r
-         <A NAME="4785"></A> When converting to FastCGI, you can either use a tool such as Purify from Pure Software to\r
-         discover and fix storage leaks or you can run a C garbage collector such as Great Circle from Geodesic\r
-         Systems.\r
-      </P>\r
-      <P>\r
-         <A NAME="4972"></A>\r
-      </P>\r
-      <P>\r
-      </P>\r
-      <HR>\r
-      <BR>\r
-       <A HREF="cover.htm">[Top]</A> <A HREF="ch1intro.htm">[Prev]</A> <A HREF="ch3perl.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->\r
-      <!-- -->\r
-      <!-- For more information on how this document, and how the rest of -->\r
-      <!-- this server was created, email yourEmail@xyzcorp.com -->\r
-      <!-- -->\r
-      <!-- Last updated: 04/15/96 08:00:16 -->\r
-   </BODY>\r
-</HTML>\r
-\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         FastCGI Programmer&#39;s Guide - Chapter 2, Developing FastCGI Applications in C
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #ffffff;
+ }
+ li.c2 {list-style: none}
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <A HREF="cover.htm">[Top]</A> <A HREF="ch1intro.htm">[Prev]</A> <A HREF="ch3perl.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       <A NAME="3659"></A>
+      <DIV CLASS="c1">
+         <H1>
+            2 Developing FastCGI<BR>
+            Applications in C
+         </H1>
+      </DIV>
+      <A NAME="917"></A>
+      <P>
+         This chapter explains how to code FastCGI applications in C and how to build them into executables.
+      </P>
+      <P>
+         <A NAME="4230"></A> If you are converting a CGI application into a FastCGI application, in many cases you will
+         only need to add a few lines of code. For more complex applications, you may also need to rearrange some code.
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         The I/O Libraries
+      </H1>
+      <A NAME="5384"></A>
+      <P>
+         The FastCGI Software Development Kit that accompanies Open Market WebServer 2.0 includes I/O libraries to
+         simplify the job of converting existing CGI applications to FastCGI or writing new FastCGI applications. There
+         are two libraries in the kit: fcgi_stdio and fcgiapp. You must include one of these header files in your
+         program:
+      </P>
+      <BR>
+      <BR>
+      <UL>
+         <LI CLASS="c2">
+            <A NAME="5386"></A>
+         </LI>
+         <LI>
+            <CODE>fcgi_stdio.h</CODE> <A NAME="4237"></A>
+         </LI>
+         <LI>
+            <CODE>fcgiapp.h</CODE>
+         </LI>
+      </UL>
+      <A NAME="4199"></A>
+      <P>
+         The <CODE>fcgi_stdio</CODE> library is a layer on top of the <CODE>fcgiapp</CODE> library, and we recommend
+         strongly that you use it, both for converting existing CGI applications and for writing new FastCGI
+         applications. The fcgi_stdio library offers several advantages:
+      </P>
+      <BR>
+      <BR>
+      <UL>
+         <LI CLASS="c2">
+            <A NAME="5811"></A>
+         </LI>
+         <LI>
+            Simplicity: there are only 3 new API calls to learn <A NAME="5828"></A>
+         </LI>
+         <LI>
+            Familiarity: If you are converting a CGI application to FastCGI, you will find few changes between CGI and
+            FastCGI. We designed our library to make the job of building a FastCGI application as similar as possible
+            to that of building a FastCGI application: you use the same environment variables, same techniques for
+            parsing query strings, the same I/O routines, and so on. <A NAME="5817"></A>
+         </LI>
+         <LI>
+            Convenience: the library provides full binary compatibility between CGI and FastCGI. That is, you can run
+            the same binary as either CGI or FastCGI.
+         </LI>
+      </UL>
+      <A NAME="5399"></A>
+      <P>
+         The fcgiapp library is more specific to FastCGI, without trying to provide the veneer of familiarity with CGI.
+         This manual describes the fcgi_stdio library; the fcgiapp library is documented in the header files that
+         accompany the development kit.
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         Code Structure
+      </H1>
+      <A NAME="4240"></A>
+      <P>
+         To structure code for FastCGI, you separate your code into two sections:
+      </P>
+      <BR>
+      <BR>
+      <UL>
+         <LI CLASS="c2">
+            <A NAME="4200"></A>
+         </LI>
+         <LI>
+            Initialization section, which is executed only once. <A NAME="4201"></A>
+         </LI>
+         <LI>
+            Response loop section, which gets executed every time the FastCGI script gets called.
+         </LI>
+      </UL>
+      <A NAME="4202"></A>
+      <P>
+         A response loop typically has the following format:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="4203">while (FCGI_Accept() &gt;= 0) {
+</A>
+<A NAME="4204"># body of response loop
+</A>
+<A NAME="4205">}
+</A>
+</PRE>
+      <A NAME="4206"></A>
+      <P>
+         The <CODE>FCGI_Accept</CODE> blocks until a client request comes in, and then returns 0. If there is a system
+         failure, or the system administrator terminates the process, Accept will return -1.
+      </P>
+      <P>
+         <A NAME="5852"></A> If the application was invoked as a CGI program, the first call to Accept returns 0 and
+         the second always returns -1, producing CGI behavior. (See <A HREF="apaman.htm#95683">&quot;FCGI_Accept
+         (3)&quot; on page  21</A> for details.)
+      </P>
+      <P>
+         <A NAME="5909"></A> Also note that the CGI world encourages small scripts, whereas FastCGI encourages
+         combining scripts. You may choose to rethink the overall structure of your applications to take better
+         advantage of FastCGI performance gains.
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         Example 1: TinyFastCGI
+      </H1>
+      <A NAME="4263">Here is a simple example of a responder FastCGI application written in C:</A><BR>
+      <BR>
+<PRE>
+#include &quot;fcgi_stdio.h&quot; /* fcgi library; put it first*/<BR>
+#include &lt;stdlib.h&gt;
+
+int count;
+
+void initialize(void)
+{
+  count=0;
+}
+
+void main(void)
+{
+/* Initialization. */  
+  initialize();
+
+/* Response loop. */
+  while (FCGI_Accept() &gt;= 0)   {
+    printf(&quot;Content-type: text/html\r\n&quot;
+           &quot;\r\n&quot;
+           &quot;&lt;title&gt;FastCGI Hello! (C, fcgi_stdio library)&lt;/title&gt;&quot;
+           &quot;&lt;h1&gt;FastCGI Hello! (C, fcgi_stdio library)&lt;/h1&gt;&quot;
+           &quot;Request number %d running on host &lt;i&gt;%s&lt;/i&gt;\n&quot;,
+            ++count, getenv(&quot;SERVER_HOSTNAME&quot;));
+  }
+}
+</PRE>
+      <H1>
+         Example 2: Prime Number Generator
+      </H1>
+      <A NAME="4182"></A>
+      <P>
+         Consider a responder application that generates the n-th prime number.
+      </P>
+      <P>
+         <A NAME="5217"></A> A CGI application would have no efficient way of solving this problem. For example, if the
+         user asks for the 50,000th prime number, a CGI application would have to calculate the first prime number,
+         then the second, and so on, up until the 50,000th. The application would then terminate, taking with it all
+         its hard-earned calculations. If a client then asks for the 49,000th prime number, the server will have to
+         spawn a new CGI application which will have to start calculating prime numbers from scratch.
+      </P>
+      <P>
+         <A NAME="4315"></A> FastCGI applications can be much more efficient at this sort of problem, since they can
+         maintain state. A FastCGI application can calculate an extensive table of prime numbers in its initialization
+         phase and then keep the table around indefinitely. Whenever a client requests a particular prime number, the
+         response loop merely needs to look it up in the table.
+      </P>
+      <P>
+         <A NAME="4343"></A> Here is the code for the prime number example:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+#include &quot;fcgi_stdio.h&quot;
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+
+#define POTENTIALLY_PRIME 0
+#define COMPOSITE 1
+#define VALS_IN_SIEVE_TABLE 1000000
+#define MAX_NUMBER_OF_PRIME_NUMBERS 78600 
+
+/* All initialized to POTENTIALLY_PRIME */
+long int  sieve_table[VALS_IN_SIEVE_TABLE]; 
+long int  prime_table[MAX_NUMBER_OF_PRIME_NUMBERS];  
+/* Use Sieve of Erastothenes method of building 
+   a prime number table. */
+void
+initialize_prime_table(void)
+{
+ long int prime_counter=1;
+ long int current_prime=2, c, d; 
+  
+  prime_table[prime_counter]=current_prime;
+
+  while (current_prime &lt; VALS_IN_SIEVE_TABLE)   {
+   /* Mark off composite numbers. */
+     for (c = current_prime; c &lt;= VALS_IN_SIEVE_TABLE; 
+          c += current_prime)  {
+        sieve_table[c] = COMPOSITE;  
+     }
+
+   /* Find the next prime number. */
+     for (d=current_prime+1; sieve_table[d] == COMPOSITE; d++); 
+   /* Put the new prime number into the table. */ 
+     prime_table[++prime_counter]=d; 
+     current_prime=d;
+  }
+}
+
+
+void main(void)
+{
+    char *query_string;
+    long int n;
+
+    initialize_prime_table();
+
+    while(FCGI_Accept() &gt;= 0) {
+        /*
+         * Produce the necessary HTTP header.
+         */
+        printf(&quot;Content-type: text/html\r\n&quot;
+               &quot;\r\n&quot;);
+        /*
+         * Produce the constant part of the HTML document.
+         */
+        printf(&quot;&lt;title&gt;Prime FastCGI&lt;/title&gt;\n&quot;
+               &quot;&lt;h1&gt;Prime FastCGI&lt;/h1&gt;\n&quot;);
+        /*
+         * Read the query string and produce the variable part
+         * of the HTML document.
+         */
+        query_string = getenv(&quot;QUERY_STRING&quot;);
+        if(query_string == NULL) {
+            printf(&quot;Usage: Specify a positive number in the query string.\n&quot;);
+        } else {
+            query_string = strchr(query_string, `=&#39;) + 1;
+            n = strtol(query_string);
+            if(n &lt; 1) {
+                printf(&quot;The query string `%s&#39; is not a positive number.\n&quot;,
+                       query_string);
+            } else if(n &gt; MAX_NUMBER_OF_PRIME_NUMBERS) {
+                printf(&quot;The number %d is too large for this program.\n&quot;, n);
+            } else
+                printf(&quot;The %ldth prime number is %ld.\n&quot;, prime_table[n]);
+            }
+        }
+    } /* while FCGI_Accept */
+}
+</PRE>
+      <A NAME="5349"></A>
+      <P>
+         This application has a noticeable start up cost while it initializes the table, but subsequent accesses are
+         fast.
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         Building
+      </H1>
+      <A NAME="4630"></A>
+      <P>
+         This section explains how to build and debug FastCGI applications written in C.
+      </P>
+      <P>
+         <A NAME="4629"></A> The C preprocessor needs to know the location of the <CODE>fcgi_stdio.h</CODE> header
+         file, which is at the following pathname:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="4642"><EM>$toolkit</EM>/include/fcgi_stdio.h
+</A>
+</PRE>
+      <A NAME="4645"></A>
+      <P>
+         where <EM>$toolkit</EM> symbolizes the directory in which you have installed the Software Development Kit for
+         FastCGI.
+      </P>
+      <P>
+         <A NAME="4760"></A> The linker needs to know the location of the <CODE>libfcgi.a</CODE> library file, which is
+         at the following pathname:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="4647"><EM>$toolkit</EM>/libfcgi/libfcgi.a 
+</A>
+</PRE>
+      <A NAME="4648"></A>
+      <P>
+         If your linker does not search the Berkeley socket library, then you must add linker directives to force this
+         search.
+      </P>
+      <P>
+         <A NAME="4773"></A> We provide a sample application <CODE>Makefile</CODE> at the following pathname:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="4649"><EM>$toolkit</EM>/examples/Makefile
+</A>
+</PRE>
+      <A NAME="4652"></A>
+      <P>
+         This <CODE>Makefile</CODE> contains the necessary rules and pathnames to build the C FastCGI applications
+         accompanying the toolkit. To build all the applications, type:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="4653">$ ./configure<BR>
+$ make 
+</A>
+</PRE>
+      <H1>
+         Memory Leaks
+      </H1>
+      <A NAME="4178"></A>
+      <P>
+         Memory leaks are seldom a problem in CGI programming because CGI applications rarely run long enough to be
+         concerned with leaks. However, memory leaks can become a problem in FastCGI applications, particularly if each
+         call to a popular FastCGI application causes additional memory to leak.
+      </P>
+      <P>
+         <A NAME="4785"></A> When converting to FastCGI, you can either use a tool such as Purify from Pure Software to
+         discover and fix storage leaks or you can run a C garbage collector such as Great Circle from Geodesic
+         Systems.
+      </P>
+      <P>
+         <A NAME="4972"></A>
+      </P>
+      <P>
+      </P>
+      <HR>
+      <BR>
+       <A HREF="cover.htm">[Top]</A> <A HREF="ch1intro.htm">[Prev]</A> <A HREF="ch3perl.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->
+      <!-- -->
+      <!-- For more information on how this document, and how the rest of -->
+      <!-- this server was created, email yourEmail@xyzcorp.com -->
+      <!-- -->
+      <!-- Last updated: 04/15/96 08:00:16 -->
+   </BODY>
+</HTML>
+
index 693b774..e2a20e3 100755 (executable)
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
-   <HEAD>\r
-      <TITLE>\r
-         FastCGI Programmer&#39;s Guide - Chapter 3, Developing FastCGI Applications in Perl\r
-      </TITLE>\r
-<STYLE TYPE="text/css">\r
- body {\r
-  background-color: #ffffff;\r
- }\r
- li.c2 {list-style: none}\r
- div.c1 {text-align: center}\r
-</STYLE>\r
-   </HEAD>\r
-   <BODY>\r
-      <A HREF="cover.htm">[Top]</A> <A HREF="ch2c.htm">[Prev]</A> <A HREF="ch4tcl.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       <A NAME="3659"></A>\r
-      <DIV CLASS="c1">\r
-         <H1>\r
-            3 Developing FastCGI<BR>\r
-            Applications in Perl\r
-         </H1>\r
-      </DIV>\r
-      <A NAME="917"></A>\r
-      <P>\r
-         This chapter explains how to code FastCGI applications in Perl. Before you can build FastCGI applications in\r
-         Perl, you must have a FastCGI-savvy version of the Perl interpreter. Open Market develops such Perl binaries\r
-         for popular platforms and makes them available with our developer&#39;s kit.\r
-      </P>\r
-      <P>\r
-         <A NAME="5008"></A> The FastCGI-savvy binaries are extensions of standard Perl, and are intended to replace\r
-         your existing Perl installation. There is no need to maintain two versions of Perl: the version that we supply\r
-         will work fine when invoked from a shell or a CGI program. There are also directions in the developer&#39;s\r
-         kit for how to make your own FastCGI-savvy Perl, if you need a version for some platform that we don&#39;t\r
-         supply.\r
-      </P>\r
-      <P>\r
-         <A NAME="4369"></A> FastCGI is ideal for applications written in Perl, because it provides a huge performance\r
-         gain. When you run a Perl script, the Perl interpreter analyzes the entire script before executing any of it.\r
-         With FastCGI, you can factor out this initialization cost and pay it only once, making execution of the actual\r
-         script much faster in response to client calls.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         Getting Started\r
-      </H1>\r
-      <A NAME="4234"></A>\r
-      <P>\r
-         The first line of any Perl script typically specifies the pathname of the Perl interpreter itself. You must\r
-         specify the pathname of a FastCGI-savvy Perl.\r
-      </P>\r
-      <P>\r
-         <A NAME="4235"></A> Next, you must tell Perl to load the FastCGI extension. To do so, place the following line\r
-         near the beginning of every FastCGI script:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="4210">use FCGI;\r
-</A>\r
-</PRE>\r
-      <A NAME="4212"></A>\r
-      <P>\r
-         Then, you have to divide FastCGI scripts into the following two sections:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <UL>\r
-         <LI CLASS="c2">\r
-            <A NAME="4242"></A>\r
-         </LI>\r
-         <LI>\r
-            Initialization section, which is executed only once. <A NAME="4243"></A>\r
-         </LI>\r
-         <LI>\r
-            Response loop section, which gets executed every time the FastCGI script gets called.\r
-         </LI>\r
-      </UL>\r
-      <A NAME="4248"></A>\r
-      <P>\r
-         A response loop typically has the following format:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="4255">while (FCGI::accept &gt;= 0) {\r
-</A>\r
-<A NAME="4256"># body of response loop\r
-</A>\r
-<A NAME="4257">}\r
-</A>\r
-</PRE>\r
-      <A NAME="4258"></A>\r
-      <P>\r
-         The <CODE>accept</CODE> call returns 0 whenever a client requests the FastCGI script. Otherwise, the\r
-         <CODE>accept</CODE> call returns -1.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         Example: TinyFastCGI\r
-      </H1>\r
-      <A NAME="4588"></A>\r
-      <P>\r
-         Here is a simple example of a FastCGI application written in Perl:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="4589"></A>\r
-#!fcgi-savvy-perl\r
-\r
-use FCGI; # Imports the library; required line\r
-\r
-# Initialization code\r
-\r
-$cnt = 0;\r
-\r
-# Response loop\r
-\r
-while (FCGI::accept &gt;= 0) {\r
-  print &quot;Content-type: text/html\r\n\r\n&quot;;\r
-  print &quot;&lt;head&gt;\n&lt;title&gt;FastCGI Demo Page (perl)&lt;/title&gt;\n&lt;/head&gt;\n&quot;;\r
-  print  &quot;&lt;h1&gt;FastCGI Demo Page (perl)&lt;/h1&gt;\n&quot;;\r
-  print &quot;This is coming from a FastCGI server.\n&lt;BR&gt;\n&quot;;\r
-  print &quot;Running on &lt;EM&gt;$ENV{SERVER_NAME}&lt;/EM&gt; to &lt;EM&gt;$ENV{REMOTE_HOST}&lt;/EM&gt;\n&lt;BR&gt;\n&quot;;\r
-   $cnt++;\r
-  print &quot;This is connection number $cnt\n&quot;;\r
-}\r
-</PRE>\r
-      <P>\r
-      </P>\r
-      <HR>\r
-      <BR>\r
-       <A HREF="cover.htm">[Top]</A> <A HREF="ch2c.htm">[Prev]</A> <A HREF="ch4tcl.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->\r
-      <!-- -->\r
-      <!-- For more information on how this document, and how the rest of -->\r
-      <!-- this server was created, email yourEmail@xyzcorp.com -->\r
-      <!-- -->\r
-      <!-- Last updated: 04/15/96 08:00:18 -->\r
-   </BODY>\r
-</HTML>\r
-\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         FastCGI Programmer&#39;s Guide - Chapter 3, Developing FastCGI Applications in Perl
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #ffffff;
+ }
+ li.c2 {list-style: none}
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <A HREF="cover.htm">[Top]</A> <A HREF="ch2c.htm">[Prev]</A> <A HREF="ch4tcl.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       <A NAME="3659"></A>
+      <DIV CLASS="c1">
+         <H1>
+            3 Developing FastCGI<BR>
+            Applications in Perl
+         </H1>
+      </DIV>
+      <A NAME="917"></A>
+      <P>
+         This chapter explains how to code FastCGI applications in Perl. Before you can build FastCGI applications in
+         Perl, you must have a FastCGI-savvy version of the Perl interpreter. Open Market develops such Perl binaries
+         for popular platforms and makes them available with our developer&#39;s kit.
+      </P>
+      <P>
+         <A NAME="5008"></A> The FastCGI-savvy binaries are extensions of standard Perl, and are intended to replace
+         your existing Perl installation. There is no need to maintain two versions of Perl: the version that we supply
+         will work fine when invoked from a shell or a CGI program. There are also directions in the developer&#39;s
+         kit for how to make your own FastCGI-savvy Perl, if you need a version for some platform that we don&#39;t
+         supply.
+      </P>
+      <P>
+         <A NAME="4369"></A> FastCGI is ideal for applications written in Perl, because it provides a huge performance
+         gain. When you run a Perl script, the Perl interpreter analyzes the entire script before executing any of it.
+         With FastCGI, you can factor out this initialization cost and pay it only once, making execution of the actual
+         script much faster in response to client calls.
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         Getting Started
+      </H1>
+      <A NAME="4234"></A>
+      <P>
+         The first line of any Perl script typically specifies the pathname of the Perl interpreter itself. You must
+         specify the pathname of a FastCGI-savvy Perl.
+      </P>
+      <P>
+         <A NAME="4235"></A> Next, you must tell Perl to load the FastCGI extension. To do so, place the following line
+         near the beginning of every FastCGI script:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="4210">use FCGI;
+</A>
+</PRE>
+      <A NAME="4212"></A>
+      <P>
+         Then, you have to divide FastCGI scripts into the following two sections:
+      </P>
+      <BR>
+      <BR>
+      <UL>
+         <LI CLASS="c2">
+            <A NAME="4242"></A>
+         </LI>
+         <LI>
+            Initialization section, which is executed only once. <A NAME="4243"></A>
+         </LI>
+         <LI>
+            Response loop section, which gets executed every time the FastCGI script gets called.
+         </LI>
+      </UL>
+      <A NAME="4248"></A>
+      <P>
+         A response loop typically has the following format:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="4255">while (FCGI::accept &gt;= 0) {
+</A>
+<A NAME="4256"># body of response loop
+</A>
+<A NAME="4257">}
+</A>
+</PRE>
+      <A NAME="4258"></A>
+      <P>
+         The <CODE>accept</CODE> call returns 0 whenever a client requests the FastCGI script. Otherwise, the
+         <CODE>accept</CODE> call returns -1.
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         Example: TinyFastCGI
+      </H1>
+      <A NAME="4588"></A>
+      <P>
+         Here is a simple example of a FastCGI application written in Perl:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="4589"></A>
+#!fcgi-savvy-perl
+
+use FCGI; # Imports the library; required line
+
+# Initialization code
+
+$cnt = 0;
+
+# Response loop
+
+while (FCGI::accept &gt;= 0) {
+  print &quot;Content-type: text/html\r\n\r\n&quot;;
+  print &quot;&lt;head&gt;\n&lt;title&gt;FastCGI Demo Page (perl)&lt;/title&gt;\n&lt;/head&gt;\n&quot;;
+  print  &quot;&lt;h1&gt;FastCGI Demo Page (perl)&lt;/h1&gt;\n&quot;;
+  print &quot;This is coming from a FastCGI server.\n&lt;BR&gt;\n&quot;;
+  print &quot;Running on &lt;EM&gt;$ENV{SERVER_NAME}&lt;/EM&gt; to &lt;EM&gt;$ENV{REMOTE_HOST}&lt;/EM&gt;\n&lt;BR&gt;\n&quot;;
+   $cnt++;
+  print &quot;This is connection number $cnt\n&quot;;
+}
+</PRE>
+      <P>
+      </P>
+      <HR>
+      <BR>
+       <A HREF="cover.htm">[Top]</A> <A HREF="ch2c.htm">[Prev]</A> <A HREF="ch4tcl.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->
+      <!-- -->
+      <!-- For more information on how this document, and how the rest of -->
+      <!-- this server was created, email yourEmail@xyzcorp.com -->
+      <!-- -->
+      <!-- Last updated: 04/15/96 08:00:18 -->
+   </BODY>
+</HTML>
+
index 8b78544..9a5f652 100755 (executable)
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
-   <HEAD>\r
-      <TITLE>\r
-         FastCGI Programmer&#39;s Guide - Chapter 4, Developing FastCGI Applications in Tcl\r
-      </TITLE>\r
-<STYLE TYPE="text/css">\r
- body {\r
-  background-color: #ffffff;\r
- }\r
- li.c2 {list-style: none}\r
- div.c1 {text-align: center}\r
-</STYLE>\r
-   </HEAD>\r
-   <BODY>\r
-      <A HREF="cover.htm">[Top]</A> <A HREF="ch3perl.htm">[Prev]</A> <A HREF="apaman.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       <A NAME="3659"></A>\r
-      <DIV CLASS="c1">\r
-         <H1>\r
-            4 Developing FastCGI<BR>\r
-            Applications in Tcl\r
-         </H1>\r
-      </DIV>\r
-      <A NAME="4835"></A>\r
-      <P>\r
-         This chapter explains how to code FastCGI applications in Tcl. Prior to creating a FastCGI application, you\r
-         must have a FastCGI-savvy version of the Tcl interpreter. Open Market develops Tcl binaries for popular\r
-         platforms and makes them available with our developer&#39;s kit.\r
-      </P>\r
-      <P>\r
-         <A NAME="4943"></A> The FastCGI-savvy binaries are extensions of standard Tcl, and are intended to replace\r
-         your existing Tcl installation. There is no need to maintain two versions of Tcl: the version that we supply\r
-         will work fine when invoked from a shell or a CGI program. There are also directions in the developer&#39;s\r
-         kit for how to make your own FastCGI-savvy Tcl, if you need a version for some platform that we don&#39;t\r
-         supply.\r
-      </P>\r
-      <P>\r
-         <A NAME="4221"></A> In many cases, you can convert a Tcl script from CGI to FastCGI by adding a few lines of\r
-         code to an existing script. For more complex scripts, you may also need to rearrange some existing code.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         Getting Started\r
-      </H1>\r
-      <A NAME="4223"></A>\r
-      <P>\r
-         The first line of any Tcl script typically specifies the pathname of the Tcl interpreter itself. You must\r
-         specify the pathname of a FastCGI-savvy Tcl.\r
-      </P>\r
-      <P>\r
-         <A NAME="4226"></A> Then, you have to divide FastCGI scripts into the following two sections:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <UL>\r
-         <LI CLASS="c2">\r
-            <A NAME="4227"></A>\r
-         </LI>\r
-         <LI>\r
-            Initialization section, which is executed only once. <A NAME="4228"></A>\r
-         </LI>\r
-         <LI>\r
-            Response loop section, which gets executed every time the FastCGI script gets called.\r
-         </LI>\r
-      </UL>\r
-      <A NAME="4229"></A>\r
-      <P>\r
-         A response loop typically has the following format:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="4923">while {[FCGI_Accept] &gt;= 0 } {\r
-</A>\r
-<A NAME="4925"># body of response loop\r
-</A>\r
-<A NAME="4367">}\r
-</A>\r
-</PRE>\r
-      <A NAME="4233"></A>\r
-      <P>\r
-         The <CODE>FCGI_Accept</CODE> call returns 0 whenever a client requests the FastCGI script. Otherwise, the\r
-         <CODE>FCGI_Accept</CODE> call returns -1.\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         Example: TinyFastCGI\r
-      </H1>\r
-      <A NAME="4343"></A>\r
-      <P>\r
-         Here is a simple example of a FastCGI application written in Tcl:\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-<PRE>\r
-<A NAME="4344"></A>\r
-#!fcgi-savvy-tcl\r
-\r
-set count 0\r
-\r
-# Response Loop\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
-      </P>\r
-      <HR>\r
-      <BR>\r
-       <A HREF="cover.htm">[Top]</A> <A HREF="ch3perl.htm">[Prev]</A> <A HREF="apaman.htm">[Next]</A> <A HREF=\r
-      "ap_guida.htm">[Bottom]</A> \r
-      <HR>\r
-      <BR>\r
-       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->\r
-      <!-- -->\r
-      <!-- For more information on how this document, and how the rest of -->\r
-      <!-- this server was created, email yourEmail@xyzcorp.com -->\r
-      <!-- -->\r
-      <!-- Last updated: 04/15/96 08:00:19 -->\r
-   </BODY>\r
-</HTML>\r
-\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         FastCGI Programmer&#39;s Guide - Chapter 4, Developing FastCGI Applications in Tcl
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #ffffff;
+ }
+ li.c2 {list-style: none}
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <A HREF="cover.htm">[Top]</A> <A HREF="ch3perl.htm">[Prev]</A> <A HREF="apaman.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       <A NAME="3659"></A>
+      <DIV CLASS="c1">
+         <H1>
+            4 Developing FastCGI<BR>
+            Applications in Tcl
+         </H1>
+      </DIV>
+      <A NAME="4835"></A>
+      <P>
+         This chapter explains how to code FastCGI applications in Tcl. Prior to creating a FastCGI application, you
+         must have a FastCGI-savvy version of the Tcl interpreter. Open Market develops Tcl binaries for popular
+         platforms and makes them available with our developer&#39;s kit.
+      </P>
+      <P>
+         <A NAME="4943"></A> The FastCGI-savvy binaries are extensions of standard Tcl, and are intended to replace
+         your existing Tcl installation. There is no need to maintain two versions of Tcl: the version that we supply
+         will work fine when invoked from a shell or a CGI program. There are also directions in the developer&#39;s
+         kit for how to make your own FastCGI-savvy Tcl, if you need a version for some platform that we don&#39;t
+         supply.
+      </P>
+      <P>
+         <A NAME="4221"></A> In many cases, you can convert a Tcl script from CGI to FastCGI by adding a few lines of
+         code to an existing script. For more complex scripts, you may also need to rearrange some existing code.
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         Getting Started
+      </H1>
+      <A NAME="4223"></A>
+      <P>
+         The first line of any Tcl script typically specifies the pathname of the Tcl interpreter itself. You must
+         specify the pathname of a FastCGI-savvy Tcl.
+      </P>
+      <P>
+         <A NAME="4226"></A> Then, you have to divide FastCGI scripts into the following two sections:
+      </P>
+      <BR>
+      <BR>
+      <UL>
+         <LI CLASS="c2">
+            <A NAME="4227"></A>
+         </LI>
+         <LI>
+            Initialization section, which is executed only once. <A NAME="4228"></A>
+         </LI>
+         <LI>
+            Response loop section, which gets executed every time the FastCGI script gets called.
+         </LI>
+      </UL>
+      <A NAME="4229"></A>
+      <P>
+         A response loop typically has the following format:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="4923">while {[FCGI_Accept] &gt;= 0 } {
+</A>
+<A NAME="4925"># body of response loop
+</A>
+<A NAME="4367">}
+</A>
+</PRE>
+      <A NAME="4233"></A>
+      <P>
+         The <CODE>FCGI_Accept</CODE> call returns 0 whenever a client requests the FastCGI script. Otherwise, the
+         <CODE>FCGI_Accept</CODE> call returns -1.
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         Example: TinyFastCGI
+      </H1>
+      <A NAME="4343"></A>
+      <P>
+         Here is a simple example of a FastCGI application written in Tcl:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+<A NAME="4344"></A>
+#!fcgi-savvy-tcl
+
+set count 0
+
+# Response Loop
+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>
+      </P>
+      <HR>
+      <BR>
+       <A HREF="cover.htm">[Top]</A> <A HREF="ch3perl.htm">[Prev]</A> <A HREF="apaman.htm">[Next]</A> <A HREF=
+      "ap_guida.htm">[Bottom]</A> 
+      <HR>
+      <BR>
+       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->
+      <!-- -->
+      <!-- For more information on how this document, and how the rest of -->
+      <!-- this server was created, email yourEmail@xyzcorp.com -->
+      <!-- -->
+      <!-- Last updated: 04/15/96 08:00:19 -->
+   </BODY>
+</HTML>
+
index 1c8090e..78c3006 100755 (executable)
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
-   <HEAD>\r
-      <TITLE>\r
-         FastCGI Programmer&#39;s Guide\r
-      </TITLE>\r
-<STYLE TYPE="text/css">\r
- body {\r
-  background-color: #ffffff;\r
- }\r
-</STYLE>\r
-   </HEAD>\r
-   <BODY>\r
-      <P>\r
-         [Top] [Prev] <A HREF="ap_guide.htm">[Next]</A> <A HREF="ap_guida.htm">[Bottom]</A>\r
-      </P>\r
-      <HR>\r
-      <BR>\r
-       \r
-      <H1>\r
-         Open Market FastCGI 1.0\r
-      </H1>\r
-      <A NAME="94"></A>\r
-      <P>\r
-         Open Market, Inc.<BR>\r
-         245 First Street, Cambridge, MA 02142<BR>\r
-         T: 617-621-9500 F: 617-252-3492\r
-      </P>\r
-      <BR>\r
-      <BR>\r
-      <H1>\r
-         <IMG ALT="error-file:TidyOut.log" SRC="covera.gif">\r
-      </H1>\r
-      <H2>\r
-         Programmer&#39;s Guide\r
-      </H2>\r
-      <H2>\r
-         April 15, 1996 s p/n 42-10530-001 Rev. A\r
-      </H2>\r
-      <HR>\r
-      <BR>\r
-       <A NAME="249"></A>\r
-      <P>\r
-         OPEN MARKET, INC., PROVIDES THIS PUBLICATION &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR\r
-         IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR\r
-         PURPOSE. In no event shall Open Market be liable for any loss of profits, loss of business, loss of use of\r
-         data, interruption of business, or for indirect, special, incidental, or consequential damages of any kind,\r
-         even if Open Market has been advised of the possibility of such damages arising from any defect or error in\r
-         this publication.\r
-      </P>\r
-      <P>\r
-         <A NAME="256"></A>\r
-      </P>\r
-      <P>\r
-         <A NAME="260"></A> Open Market may revise this publication from time to time without notice. Some states or\r
-         jurisdictions do not allow disclaimer of express or implied warranties in certain transactions; therefore,\r
-         this statement may not apply to you.\r
-      </P>\r
-      <P>\r
-         <A NAME="261"></A>\r
-      </P>\r
-      <P>\r
-         <A NAME="265"></A> Copyright &copy; 1996 Open Market, Inc.\r
-      </P>\r
-      <P>\r
-         <A NAME="266"></A>\r
-      </P>\r
-      <P>\r
-         <A NAME="267"></A> All rights reserved.\r
-      </P>\r
-      <P>\r
-         <A NAME="268"></A>\r
-      </P>\r
-      <P>\r
-         <A NAME="269"></A> <EM>Alpha/OSF</EM> is a trademark of Digital Equipment Corporation.\r
-      </P>\r
-      <P>\r
-         <A NAME="278"></A> <EM>Digital UNIX</EM> is a trademark of Digital Equipment Corporation.<BR>\r
-         <EM>BSD/386</EM> is a trademark of Berkeley Software Design, Inc.<BR>\r
-         <EM>BSD/OS</EM> is a trademark of Berkeley Software Design, Inc.\r
-      </P>\r
-      <P>\r
-         <A NAME="308"></A> <EM>Great Circle</EM> is a trademark of Geodesic Systems, Inc.<BR>\r
-         <EM>HP-UX</EM> is a trademark of Hewlett-Packard Co., Inc.<BR>\r
-         <EM>IBM AIX</EM> is a trademark of International Business Machines, Inc.<BR>\r
-         <EM>Word</EM> is a trademark of Microsoft Corporation.<BR>\r
-         <EM>Netscape</EM> is a trademark of Netscape Communications Company.<BR>\r
-         <EM>PostScript</EM> is a trademark of Adobe Systems Inc.\r
-      </P>\r
-      <P>\r
-         <A NAME="307"></A> <EM>Purify</EM> is a trademark of Pure Software, Inc.<BR>\r
-         <EM>SecureWeb</EM> is a trademark of Terisa Systems, Inc.<BR>\r
-         <EM>HylaFAX</EM> is a trademark of Silicon Graphics, Inc.<BR>\r
-         <EM>SGI IRIX</EM> is a trademark of Silicon Graphics, Inc.<BR>\r
-         <EM>Solaris</EM> is a trademark of Sun Microsystems, Inc.<BR>\r
-         <EM>SunOS</EM> is a trademark of Sun Microsystems, Inc.<BR>\r
-         <EM>UNIX</EM> is a trademark of UNIX Systems Laboratories, Inc.\r
-      </P>\r
-      <P>\r
-         <A NAME="270"></A>\r
-      </P>\r
-      <P>\r
-         <A NAME="271"></A> Any other trademarks and product names used herein may be the trademarks of their\r
-         respective companies.\r
-      </P>\r
-      <P>\r
-         [Top] [Prev] <A HREF="ap_guide.htm">[Next]</A> <A HREF="ap_guida.htm">[Bottom]</A>\r
-      </P>\r
-      <HR>\r
-      <BR>\r
-       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->\r
-      <!-- -->\r
-      <!-- For more information on how this document, and how the rest of -->\r
-      <!-- this server was created, email yourEmail@xyzcorp.com -->\r
-      <!-- -->\r
-      <!-- Last updated: 04/15/96 08:03:01 -->\r
-   </BODY>\r
-</HTML>\r
-\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         FastCGI Programmer&#39;s Guide
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #ffffff;
+ }
+</STYLE>
+   </HEAD>
+   <BODY>
+      <P>
+         [Top] [Prev] <A HREF="ap_guide.htm">[Next]</A> <A HREF="ap_guida.htm">[Bottom]</A>
+      </P>
+      <HR>
+      <BR>
+       
+      <H1>
+         Open Market FastCGI 1.0
+      </H1>
+      <A NAME="94"></A>
+      <P>
+         Open Market, Inc.<BR>
+         245 First Street, Cambridge, MA 02142<BR>
+         T: 617-621-9500 F: 617-252-3492
+      </P>
+      <BR>
+      <BR>
+      <H1>
+         <IMG ALT="error-file:TidyOut.log" SRC="covera.gif">
+      </H1>
+      <H2>
+         Programmer&#39;s Guide
+      </H2>
+      <H2>
+         April 15, 1996 s p/n 42-10530-001 Rev. A
+      </H2>
+      <HR>
+      <BR>
+       <A NAME="249"></A>
+      <P>
+         OPEN MARKET, INC., PROVIDES THIS PUBLICATION &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR
+         IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+         PURPOSE. In no event shall Open Market be liable for any loss of profits, loss of business, loss of use of
+         data, interruption of business, or for indirect, special, incidental, or consequential damages of any kind,
+         even if Open Market has been advised of the possibility of such damages arising from any defect or error in
+         this publication.
+      </P>
+      <P>
+         <A NAME="256"></A>
+      </P>
+      <P>
+         <A NAME="260"></A> Open Market may revise this publication from time to time without notice. Some states or
+         jurisdictions do not allow disclaimer of express or implied warranties in certain transactions; therefore,
+         this statement may not apply to you.
+      </P>
+      <P>
+         <A NAME="261"></A>
+      </P>
+      <P>
+         <A NAME="265"></A> Copyright &copy; 1996 Open Market, Inc.
+      </P>
+      <P>
+         <A NAME="266"></A>
+      </P>
+      <P>
+         <A NAME="267"></A> All rights reserved.
+      </P>
+      <P>
+         <A NAME="268"></A>
+      </P>
+      <P>
+         <A NAME="269"></A> <EM>Alpha/OSF</EM> is a trademark of Digital Equipment Corporation.
+      </P>
+      <P>
+         <A NAME="278"></A> <EM>Digital UNIX</EM> is a trademark of Digital Equipment Corporation.<BR>
+         <EM>BSD/386</EM> is a trademark of Berkeley Software Design, Inc.<BR>
+         <EM>BSD/OS</EM> is a trademark of Berkeley Software Design, Inc.
+      </P>
+      <P>
+         <A NAME="308"></A> <EM>Great Circle</EM> is a trademark of Geodesic Systems, Inc.<BR>
+         <EM>HP-UX</EM> is a trademark of Hewlett-Packard Co., Inc.<BR>
+         <EM>IBM AIX</EM> is a trademark of International Business Machines, Inc.<BR>
+         <EM>Word</EM> is a trademark of Microsoft Corporation.<BR>
+         <EM>Netscape</EM> is a trademark of Netscape Communications Company.<BR>
+         <EM>PostScript</EM> is a trademark of Adobe Systems Inc.
+      </P>
+      <P>
+         <A NAME="307"></A> <EM>Purify</EM> is a trademark of Pure Software, Inc.<BR>
+         <EM>SecureWeb</EM> is a trademark of Terisa Systems, Inc.<BR>
+         <EM>HylaFAX</EM> is a trademark of Silicon Graphics, Inc.<BR>
+         <EM>SGI IRIX</EM> is a trademark of Silicon Graphics, Inc.<BR>
+         <EM>Solaris</EM> is a trademark of Sun Microsystems, Inc.<BR>
+         <EM>SunOS</EM> is a trademark of Sun Microsystems, Inc.<BR>
+         <EM>UNIX</EM> is a trademark of UNIX Systems Laboratories, Inc.
+      </P>
+      <P>
+         <A NAME="270"></A>
+      </P>
+      <P>
+         <A NAME="271"></A> Any other trademarks and product names used herein may be the trademarks of their
+         respective companies.
+      </P>
+      <P>
+         [Top] [Prev] <A HREF="ap_guide.htm">[Next]</A> <A HREF="ap_guida.htm">[Bottom]</A>
+      </P>
+      <HR>
+      <BR>
+       <!-- This file was created with Quadralay WebWorks Publisher 3.0.3 -->
+      <!-- -->
+      <!-- For more information on how this document, and how the rest of -->
+      <!-- this server was created, email yourEmail@xyzcorp.com -->
+      <!-- -->
+      <!-- Last updated: 04/15/96 08:03:01 -->
+   </BODY>
+</HTML>
+
index 994129c..13b419b 100644 (file)
-<HTML>\r
-   <HEAD>\r
-      <TITLE>\r
-         FastCGI\r
-      </TITLE>\r
-      <META NAME="GENERATOR" CONTENT="Internet Assistant for Microsoft Word 2.0z">\r
-<STYLE TYPE="text/css">\r
- div.c5 {font-family: Arial Narrow; font-size: 80%; text-align: center}\r
- span.c4 {font-family: Courier}\r
- tt.c3 {font-family: Courier}\r
- div.c2 {text-align: center}\r
- div.c1 {color: #FFFFFF; font-family: Impact; font-size: 120%; text-align: center}\r
-</STYLE>\r
-   </HEAD>\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: fastcgi.htm,v 1.3 2001/11/27 01:13:29 robs Exp $ -->\r
-   <BODY>\r
-      <P>\r
-         Open Market, Inc.\r
-      </P>\r
-      <P>\r
-      </P>\r
-      <DIV CLASS="c1">\r
-         Technical White Paper<BR>\r
-      </DIV>\r
-      <H1>\r
-         FastCGI:<BR>\r
-          A High-Performance Web Server Interface\r
-      </H1>\r
-      <P>\r
-         April 1996<!--Please send comments to:-->\r
-      </P>\r
-      <HR>\r
-      <!-- payne@openmarket.com-->\r
-      <H2>\r
-         1. Introduction\r
-      </H2>\r
-      <P>\r
-         The surge in the use of the Web by business has created a tremendous need for server extension applications\r
-         that create dynamic content. These are the applications that will allow businesses to deliver products,\r
-         services, and messages whose shape and content are in part determined by the interaction with, and knowledge\r
-         of, the customers to which they are delivered.\r
-      </P>\r
-      <P>\r
-         This important movement away from static Web content is pushing the limits and exposing the weaknesses of the\r
-         environment in which these applications are currently bound: CGI (Common Gateway Interface). Most importantly\r
-         it does not offer the performance these applications require. A new communication infrastructure is needed to\r
-         connect Web servers with these new applications. This is what led Open Market to develop FastCGI.\r
-      </P>\r
-      <P>\r
-         FastCGI is a fast, open, and secure Web server interface that solves the performance problems inherent in CGI,\r
-         without introducing the overhead and complexity of proprietary APIs (Application Programming Interfaces).\r
-      </P>\r
-      <P>\r
-         This paper assumes that the reader has basic familiarity with Web technology and developing Web applications.\r
-      </P>\r
-      <H3>\r
-         Common Gateway Interface\r
-      </H3>\r
-      <P>\r
-         The de facto standard interface for Web server applications is CGI, which was first implemented in the NCSA\r
-         server. CGI has many benefits:\r
-      </P>\r
-      <UL>\r
-         <LI>\r
-            <B>Simplicity.</B> <SPAN>It is easy to understand.</SPAN>\r
-         </LI>\r
-         <LI>\r
-            <B>Language independence.</B> CGI applications can be written in nearly any language.\r
-         </LI>\r
-         <LI>\r
-            <B>Process isolation.</B> Since applications run in separate processes, buggy applications cannot crash the\r
-            Web server or access the server&#39;s private internal state.\r
-         </LI>\r
-         <LI>\r
-            <B>Open standard.</B> Some form of CGI has been implemented on every Web server.\r
-         </LI>\r
-         <LI>\r
-            <B>Architecture independence.</B> CGI is not tied to any particular server architecture (single threaded,\r
-            multi-threaded, etc.).\r
-         </LI>\r
-      </UL>\r
-      <P>\r
-         CGI also has some significant drawbacks. The leading problem is performance: Since a new process is created\r
-         for each request and thrown away when the request is done, efficiency is poor.\r
-      </P>\r
-      <P>\r
-         CGI also has limited functionality: It only supports a simple &quot;responder&quot; role, where the\r
-         application generates the response that is returned to the client. CGI programs can&#39;t link into other\r
-         stages of Web server request processing, such as authorization and logging.\r
-      </P>\r
-      <H3>\r
-         Server APIs\r
-      </H3>\r
-      <P>\r
-         In response to the performance problems for CGI, several vendors have developed APIs for their servers. The\r
-         two most notable are NSAPI from Netscape and ISAPI from Microsoft. The freely available Apache server also has\r
-         an API.\r
-      </P>\r
-      <P>\r
-         Applications linked into the server API may be significantly faster than CGI programs. The CGI\r
-         startup/initialization problem is improved, because the application runs in the server process and is\r
-         persistent across requests. Web server APIs also offer more functionality than CGI: you can write extensions\r
-         that perform access control, get access to the server&#39;s log file, and link in to other stages in the\r
-         server&#39;s request processing.\r
-      </P>\r
-      <P>\r
-         However, APIs sacrifice all of CGI&#39;s benefits. Vendor APIs have the following problems:\r
-      </P>\r
-      <UL>\r
-         <LI>\r
-            <B>Complexity.</B> Vendor 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 vendor API\r
-            (usually C/C++). Perl, the most popular language for CGI programs, can&#39;t be used with any existing\r
-            vendor API.\r
-         </LI>\r
-         <LI>\r
-            <B>No process isolation.</B> <SPAN>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.</SPAN>\r
-         </LI>\r
-         <LI>\r
-            <B>Proprietary.</B> Coding your application to a particular API locks you into a particular vendor&#39;s\r
-            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 vendor changes the server&#39;s architecture, the API will usually have to change, and applications\r
-            will have to be adapted or rewritten.\r
-         </LI>\r
-      </UL>\r
-      <H3>\r
-         FastCGI\r
-      </H3>\r
-      <P>\r
-         The FastCGI interface combines the best aspects of CGI and vendor APIs. Like CGI, FastCGI applications run in\r
-         separate, isolated processes. FastCGI&#39;s advantages include:\r
-      </P>\r
-      <UL>\r
-         <LI>\r
-            <B>Performance.</B> FastCGI processes are persistent-they are reused to handle multiple requests. This\r
-            solves the CGI performance problem of creating new processes for each request.\r
-         </LI>\r
-         <LI>\r
-            <B>Simplicity, with easy migration from CGI.</B> The FastCGI application library (described on page 9)\r
-            simplifies the migration of existing CGI applications. Applications built with the application library can\r
-            also run as CGI programs, for backward compatibility with old Web servers.\r
-         </LI>\r
-         <LI>\r
-            <B>Language independence.</B> Like CGI, FastCGI applications can be written in any language, not just\r
-            languages supported by the vendor API.\r
-         </LI>\r
-         <LI>\r
-            <B>Process isolation.</B> A buggy FastCGI application cannot crash or corrupt the core server or other\r
-            applications. A malicious FastCGI application cannot steal any secrets (such as session keys for\r
-            encryption) from the Web server.\r
-         </LI>\r
-         <LI>\r
-            <B>Non-proprietary.</B> FastCGI is supported in all of Open Market&#39;s server products, and support is\r
-            under development for other Web servers, including the freely available Apache and NCSA servers, as well as\r
-            commercial servers from Microsoft and Netscape.\r
-         </LI>\r
-         <LI>\r
-            <B>Architecture independence.</B> The FastCGI interface is not tied to a particular server architecture.\r
-            Any Web server can implement the FastCGI interface. Also, FastCGI does not impose any architecture on the\r
-            application: applications can be single or multi-threaded, regardless of the threading architecture of the\r
-            Web server.\r
-         </LI>\r
-         <LI>\r
-            <B>Support for distributed computing.</B> FastCGI provides the ability to run applications remotely, which\r
-            is useful for distributing load and managing external Web sites.\r
-         </LI>\r
-      </UL>\r
-      <P>\r
-         The following sections describe the FastCGI interface, protocol, application library, and support in Open\r
-         Market&#39;s WebServer products.\r
-      </P>\r
-      <H2>\r
-         2. FastCGI Interface\r
-      </H2>\r
-      <P>\r
-         The functionality provided by the FastCGI interface is very similar to that provided by CGI. To best\r
-         understand the FastCGI protocol, we review the CGI interface here. Basic CGI request processing proceeds as\r
-         follows:\r
-      </P>\r
-      <OL>\r
-         <LI>\r
-            For each request, the server creates a new process and the process initializes itself.\r
-         </LI>\r
-         <LI>\r
-            The Web server passes the request information (such as remote host, username, HTTP headers, etc.) to the\r
-            CGI program in environment variables.\r
-         </LI>\r
-         <LI>\r
-            The Web server sends any client input (such as user-entered field values from an HTML form) to the CGI\r
-            program&#39;s standard input.\r
-         </LI>\r
-         <LI>\r
-            The CGI program writes any output to be returned to the client on standard output. Error information\r
-            written to standard error is logged by the Web server.\r
-         </LI>\r
-         <LI>\r
-            When the CGI process exits, the request is complete.\r
-         </LI>\r
-      </OL>\r
-      <P>\r
-         FastCGI is conceptually very similar to CGI, with two major differences:\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 allows\r
-            FastCGI programs to run on remote machines, using TCP connections between the Web server and the FastCGI\r
-            application.\r
-         </LI>\r
-      </UL>\r
-      <P>\r
-         Request processing in a single-threaded FastCGI application proceeds as follows:\r
-      </P>\r
-      <OL>\r
-         <LI>\r
-            The Web server creates FastCGI application processes to handle requests. The processes may be created at\r
-            startup, or created on demand.\r
-         </LI>\r
-         <LI>\r
-            The FastCGI program initializes itself, and waits for a new connection from the Web server.\r
-         </LI>\r
-         <LI>\r
-            When a client request comes in, the Web server opens a connection to the FastCGI process. The server sends\r
-            the CGI environment variable information and standard input over the connection.\r
-         </LI>\r
-         <LI>\r
-            The FastCGI process sends the standard output and error information back to the server over the same\r
-            connection.\r
-         </LI>\r
-         <LI>\r
-            When the FastCGI process closes the connection, the request is complete. The FastCGI process then waits for\r
-            another connection from the Web server.\r
-         </LI>\r
-      </OL>\r
-      <P>\r
-         FastCGI applications can run locally (on the same machine as the Web server) or remotely. For local\r
-         applications, the server uses a full-duplex pipe to connect to the FastCGI application process. For remote\r
-         applications, the server uses a TCP connection.\r
-      </P>\r
-      <P>\r
-         FastCGI applications can be single-threaded or multi-threaded. For single threaded applications, the Web\r
-         server maintains a pool of processes (if the application is running locally) to handle client requests. The\r
-         size of the pool is user configurable. Multi-threaded FastCGI applications may accept multiple connections\r
-         from the Web server and handle them simultaneously in a single process. (For example, Java&#39;s built-in\r
-         multi-threading, garbage collection, synchronization primitives, and platform independence make it a natural\r
-         implementation language for multi-threaded FastCGI applications.)\r
-      </P>\r
-      <H3>\r
-         Remote FastCGI\r
-      </H3>\r
-      <P>\r
-         FastCGI&#39;s ability to run applications remotely (over a TCP connection) provides some major benefits. These\r
-         benefits are described in this section, along with some of the security issues that affect remote FastCGI\r
-         applications.\r
-      </P>\r
-      <H4>\r
-         FastCGI with Firewalls\r
-      </H4>\r
-      <P>\r
-         Applications that run on organizational (external) Web servers and depend on internal databases can be a\r
-         challenge to administer. Figure 1 shows a typical organization, with an external Web server, a firewall\r
-         restricting access to the internal network, and internal databases and applications.\r
-      </P>\r
-      <P>\r
-      </P>\r
-      <DIV CLASS="c2">\r
-         <IMG ALT="error-file:TidyOut.log" SRC="img00001.gif"><A NAME="_Ref352505891">Figure 1</A>\r
-      </DIV>\r
-      <P>\r
-         With CGI and vendor APIs, the application has to run on the Web server machine. This means the server\r
-         administrator has to replicate the necessary database information onto the system hosting the Web server\r
-         (which may be difficult to do in an automated way without compromising firewall security). Or, the\r
-         administrator may build a &quot;bridge&quot; that allows access through the Web server to internal databases\r
-         and applications (which is effectively re-inventing remote FastCGI).\r
-      </P>\r
-      <P>\r
-         With remote FastCGI, the applications can run on the internal network, simplifying the administrator&#39;s\r
-         job. When used with appropriate firewall configuration and auditing, this approach provides a secure,\r
-         high-performance, scalable way to bring internal applications and data to the external network.\r
-      </P>\r
-      <H4>\r
-         Load Distribution\r
-      </H4>\r
-      <P>\r
-         For resource-intensive CGI and API applications, the Web server machine quickly becomes the bottleneck for\r
-         overall throughput. The usual way to solve this performance problem is to buy a bigger, faster Web server\r
-         machine, or to partition the Web site across several Web servers.\r
-      </P>\r
-      <P>\r
-         With remote FastCGI, the resource-intensive applications can be moved off the Web server machine, giving the\r
-         server administrator additional flexibility in configuring the Web server. The administrator can configure\r
-         FastCGI applications &quot;behind the scenes&quot; without having to change any content links or the external\r
-         view of the Web site. The administrator can use several smaller, inexpensive server machines for applications,\r
-         and can tailor each machine to the application it is hosting.\r
-      </P>\r
-      <H4>\r
-         Security Issues with Remote FastCGI\r
-      </H4>\r
-      <P>\r
-         The two security issues with remote FastCGI connections are authentication and privacy. FastCGI applications\r
-         should only accept connections from Web servers that they trust (the application library includes support for\r
-         IP address validation). Future versions of the protocol will include support for applications authenticating\r
-         Web servers, as well as support for running remote connections over secure transport protocols such as SSL or\r
-         PCT.<!--This pargraph needs to be made stronger, going into the issues in a little more detail.-->\r
-      </P>\r
-      <H3>\r
-         The FastCGI Protocol\r
-      </H3>\r
-      <P>\r
-         This section offers a brief introduction to the protocol used on the connection between the Web server and\r
-         FastCGI application. Most application developers will use the FastCGI application library and won&#39;t have\r
-         to worry about the protocol details. However, specialized applications are free to implement the FastCGI\r
-         protocol directly.\r
-      </P>\r
-      <P>\r
-         FastCGI uses a simple packet record format on the connection between the application and the Web server. The\r
-         same record format is used in both directions and is outlined in Figure 2.\r
-      </P>\r
-      <P>\r
-      </P>\r
-      <DIV CLASS="c2">\r
-         <IMG ALT="error-file:TidyOut.log" SRC="img00002.gif"><A NAME="_Ref352404075">Figure 2</A>\r
-      </DIV>\r
-      <P>\r
-         The protocol version field specifies the version of the FastCGI protocol that is in use. The type field\r
-         specifies the type of the record (described in the following section). The request ID identifies this record\r
-         to a particular request, allowing multiple requests to be multiplexed over a single connection. The data\r
-         length field specifies the number of data bytes that follow.\r
-      </P>\r
-      <P>\r
-         The different FastCGI packet types are:\r
-      </P>\r
-      <TABLE>\r
-         <TR>\r
-            <TD WIDTH="186">\r
-               <TT CLASS="c3">FCGI_PARAMS</TT> \r
-            </TD>\r
-            <TD WIDTH="228">\r
-               Used for sending name/value pairs (CGI environment variables) from the Web server to the application.\r
-            </TD>\r
-         </TR>\r
-         <TR>\r
-            <TD WIDTH="186">\r
-               <TT CLASS="c3">FCGI_STDIN</TT> \r
-            </TD>\r
-            <TD WIDTH="228">\r
-               Used for sending the standard input from the Web server to the application.\r
-            </TD>\r
-         </TR>\r
-         <TR>\r
-            <TD WIDTH="186">\r
-               <TT CLASS="c3">FCGI_DATA</TT> \r
-            </TD>\r
-            <TD WIDTH="228">\r
-               Used for sending filter data to the application (for more information, see the filter role described on\r
-               page 7.)\r
-            </TD>\r
-         </TR>\r
-         <TR>\r
-            <TD WIDTH="186">\r
-               <TT CLASS="c3">FCGI_STDOUT</TT> \r
-            </TD>\r
-            <TD WIDTH="228">\r
-               Used to send standard output from the application to the Web server.\r
-            </TD>\r
-         </TR>\r
-         <TR>\r
-            <TD WIDTH="186">\r
-               <TT CLASS="c3">FCGI_STDERR</TT> \r
-            </TD>\r
-            <TD WIDTH="228">\r
-               Used to send standard error information from the application to the Web server.\r
-            </TD>\r
-         </TR>\r
-         <TR>\r
-            <TD WIDTH="186">\r
-               <TT CLASS="c3">FCGI_END_REQUEST</TT> \r
-            </TD>\r
-            <TD WIDTH="228">\r
-               Ends the request (can be sent by either the server or the application).\r
-            </TD>\r
-         </TR>\r
-      </TABLE>\r
-      <P>\r
-      </P>\r
-      <P>\r
-         For complete protocol details, see the <I>FastCGI Protocol Specification</I>, available from the Web site\r
-         listed at the end of this paper.\r
-      </P>\r
-      <H2>\r
-         3. Application Roles\r
-      </H2>\r
-      <P>\r
-         A major problem with CGI is its limited functionality: CGI programs can only provide simple responses to\r
-         requests. FastCGI provides expanded functionality with support for three different application\r
-         &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
-      <P>\r
-         The roles are described in more detail in the following sections.\r
-      </P>\r
-      <H3>\r
-         Responder Role\r
-      </H3>\r
-      <P>\r
-         FastCGI&#39;s Responder role is identical to the functionality provided by CGI today. When a request comes\r
-         into the server, the FastCGI program generates the response that&#39;s returned to the client (typically an\r
-         HTML page).\r
-      </P>\r
-      <H3>\r
-         <A NAME="_Ref352404524">Filter Role</A>\r
-      </H3>\r
-      <P>\r
-         The Filter role allows a FastCGI application to process a requested file before it is returned to the client.\r
-      </P>\r
-      <P>\r
-         Let&#39;s assume that the Web server is configured so that all files with the .<TT CLASS="c3">sgml</TT>\r
-         extension are processed by a SGML-to-HTML FastCGI filter application, and the user accesses the following URL:\r
-      </P>\r
-      <P>\r
-         <TT CLASS="c3">/document.sgml</TT>\r
-      </P>\r
-      <P>\r
-         After the Web server makes an access control decision and maps this URL to a content file, it invokes the\r
-         FastCGI filter application with this file available as input. The FastCGI program&#39;s HTML output is sent\r
-         back to the client, just as in the responder role. The process is outlined in Figure 3.\r
-      </P>\r
-      <P>\r
-      </P>\r
-      <DIV CLASS="c2">\r
-         <IMG ALT="error-file:TidyOut.log" SRC="img00003.gif"><A NAME="_Ref352560526">Figure 3</A>\r
-      </DIV>\r
-      <P>\r
-         Filter applications can significantly improve performance by caching filter results (the server provides the\r
-         modification time in the request information so that applications can flush the cache when the server file has\r
-         been modified).\r
-      </P>\r
-      <P>\r
-         The Filter role is useful for:\r
-      </P>\r
-      <UL>\r
-         <LI>\r
-            On-the-fly format conversions\r
-         </LI>\r
-         <LI>\r
-            Dynamic documents (such as documents with embedded SQL queries, or dynamic advertisement insertion)\r
-         </LI>\r
-         <LI>\r
-            Applying a standard template: headers, footers, and backgrounds\r
-         </LI>\r
-      </UL>\r
-      <H3>\r
-         Authorizer Role\r
-      </H3>\r
-      <P>\r
-         The Authorizer role allows a FastCGI application to make an access control decision for a request. The FastCGI\r
-         application is invoked with all of the request information, just as in the Responder role. If the authorizer\r
-         application generates a &quot;200 OK&quot; HTTP result, the Web server assumes that access is allowed and\r
-         proceeds with the request. (The Web server may process other access checks, including other FastCGI\r
-         authorizers, before access is ultimately allowed.) If the application generates any other response, that\r
-         response is returned to the client and the request is ended. The response can be any valid HTTP response,\r
-         including &quot;Access Denied&quot; or &quot;Redirect&quot;.\r
-      </P>\r
-      <P>\r
-         The Authorizer role is useful for:\r
-      </P>\r
-      <UL>\r
-         <LI>\r
-            Access control based on username and password, where the user information is looked up in an external\r
-            database.\r
-         </LI>\r
-         <LI>\r
-            Complex access policies, such as time-of-day based access.\r
-         </LI>\r
-         <LI>\r
-            Smart-card challenge/response authentication.\r
-         </LI>\r
-         <LI>\r
-            Dynamic redirects, where the user is sent to different pages based on the request profile.\r
-         </LI>\r
-      </UL>\r
-      <H2>\r
-         <A NAME="_Ref352251764">4. FastCGI Application Library</A>\r
-      </H2>\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 makes implementing FastCGI programs as easy as writing CGI\r
-         applications.\r
-      </P>\r
-      <P>\r
-         The application library provides a replacement for the C language standard I/O (stdio) routines, such as <TT\r
-         CLASS="c3">printf()</TT> and <TT CLASS="c3">gets()</TT>. The library converts references to standard input,\r
-         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.\r
-      </P>\r
-      <P>\r
-         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 (CGI migration is described in more\r
-            detail in the following section).\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.\r
-      </P>\r
-      <P>\r
-         The <TT>fcgi_stdio.h</TT> header file provides the FastCGI replacement routines for the C standard I/O\r
-         library. The <TT>FCGI_Accept()</TT> routine accepts a new request from the Web server.\r
-      </P>\r
-      <H3>\r
-         Migrating Existing CGI Programs\r
-      </H3>\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. FastCGI applications have the following structure, with an initialization\r
-         section and a request processing loop:\r
-      </P>\r
-      <P>\r
-         <I>Initialize application;<BR>\r
-         </I> <TT>while(FCGI_Accept() &gt;= 0) {</TT><BR>\r
-          <I>Process request</I>;<BR>\r
-          <TT>}</TT>\r
-      </P>\r
-      <P>\r
-         To ease migration to FastCGI, executables built with the application library can run as either CGI or FastCGI\r
-         programs, depending on how they are invoked. The library detects the execution environment and automatically\r
-         selects FastCGI or regular I/O routines, as appropriate.\r
-      </P>\r
-      <P>\r
-         After migration, developers can clean up their FastCGI applications for best performance:\r
-      </P>\r
-      <UL>\r
-         <LI>\r
-            Fix any resource leaks. Many CGI programs do not attempt to manage memory or close files, because they\r
-            assume the world is going to be cleaned up when they exit. (If you don&#39;t want to clean up your program,\r
-            you can just have your process assume that it is leaking memory and exit after processing some fixed number\r
-            of requests.) Purify from Pure Software is one of a number of excellent tools for finding leaks and other\r
-            memory use problems.\r
-         </LI>\r
-         <LI>\r
-            Fix any problems with retained application state. The application must ensure that any state that it\r
-            creates in processing one request has no unintended effects on later requests.\r
-         </LI>\r
-         <LI>\r
-            Collapse functionality. A common practice with CGI applications is to implement many small programs, with\r
-            one function per program. CGI encourages this, because smaller programs load faster. With FastCGI, it&#39;s\r
-            better to have related functionality in a single executable, so there are fewer processes to manage and\r
-            applications can take advantage of sharing cached information across functions.\r
-         </LI>\r
-      </UL>\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 Open Market. The interpreters are backward-compatible: They can run standard Tcl\r
-         and Perl applications.\r
-      </P>\r
-      <H2>\r
-         5. FastCGI in the Open Market WebServer\r
-      </H2>\r
-      <P>\r
-         This section describes the FastCGI support in the following Open Market server products:\r
-      </P>\r
-      <UL>\r
-         <LI>\r
-            Open Market WebServer V2.0\r
-         </LI>\r
-         <LI>\r
-            Open Market Secure WebServer V2.0\r
-         </LI>\r
-         <LI>\r
-            Open Market Secure WebServer (Global) V2.0\r
-         </LI>\r
-      </UL>\r
-      <P>\r
-         For more information about FastCGI support, see the <I>Open Market WebServer Installation and Configuration\r
-         Guide</I>.\r
-      </P>\r
-      <H3>\r
-         Server Configuration\r
-      </H3>\r
-      <P>\r
-         FastCGI applications are configured with the server&#39;s configuration file. Configuration has two parts.\r
-      </P>\r
-      <P>\r
-         First, the server administrator defines an <I>application class</I>. For local applications, the application\r
-         class specifies the details of running the FastCGI application, such as:\r
-      </P>\r
-      <UL>\r
-         <LI>\r
-            The pathname of the application executable.\r
-         </LI>\r
-         <LI>\r
-            Any arguments and environment variables to pass to the process at startup.\r
-         </LI>\r
-         <LI>\r
-            The number of processes to run.\r
-         </LI>\r
-      </UL>\r
-      <P>\r
-         For remote applications, the class configuration information includes the host and TCP port to connect to. The\r
-         Web server assumes that the FastCGI application has been started on the remote host. If a request comes in and\r
-         the server can&#39;t connect to the FastCGI TCP port, the server logs an error and returns an error page to\r
-         the client.\r
-      </P>\r
-      <P>\r
-         The second configuration step is mapping the application class to a role:\r
-      </P>\r
-      <UL>\r
-         <LI>\r
-            For responder roles, the administrator configures some part of the URL space to be handled by the FastCGI\r
-            application. For example, all URLs beginning with <SPAN CLASS="c4">/rollcall/</SPAN> might be handled by\r
-            the employee database application.\r
-         </LI>\r
-         <LI>\r
-            For filter roles, the administrator configures a file extension to be handled by a filter application. For\r
-            example, all files with the <SPAN CLASS="c4">.sql</SPAN> extension could be handled by a SQL query lookup\r
-            filter.\r
-         </LI>\r
-         <LI>\r
-            For authorizer roles, the administrator configures an authorizer application in the same manner as other\r
-            access methods (hostname, username/password, etc.) A request must pass <I>all</I> access control checks\r
-            (possibly including multiple FastCGI authorizers) before access is allowed.\r
-         </LI>\r
-      </UL>\r
-      <H3>\r
-         Basic FastCGI\r
-      </H3>\r
-      <P>\r
-         To simplify migration for existing CGI programs, the WebServer provides a simple way to install new FastCGI\r
-         programs without having to reconfigure the server. However, this approach doesn&#39;t offer all of the\r
-         performance benefits of FastCGI application classes.\r
-      </P>\r
-      <P>\r
-         The WebServer treats any file with the extension <SPAN CLASS="c4">.fcg</SPAN> as a FastCGI application. When a\r
-         request corresponds to such a file, the WebServer creates a new FastCGI process to handle the request, and\r
-         shuts down the process when the request is complete (just as in CGI). In this mode of operation performance is\r
-         comparable to CGI. Future versions of the WebServer will improve performance by automatically caching\r
-         processes and re-using them for subsequent requests.\r
-      </P>\r
-      <H3>\r
-         Session Affinity\r
-      </H3>\r
-      <P>\r
-         FastCGI programs can improve performance by caching information in the application process. For applications\r
-         that require frequent but expensive operations such as validating a username/password in an external database\r
-         for each request, this technique can significantly improve performance.\r
-      </P>\r
-      <P>\r
-         To improve the effectiveness of this technique, the WebServer implements <I>session affinity</I>. When session\r
-         affinity is enabled, the WebServer arranges for all requests in a user session to be handled by the same\r
-         FastCGI application process. What constitutes a &quot;session&quot; is configurable. The default configuration\r
-         uses the WebServer&#39;s built-in session tracking facility to identify user sessions. However, the server\r
-         administrator can use any part of the request information for the session affinity mapping: the URL path, the\r
-         client&#39;s hostname, the username, etc.\r
-         <!--Talk about applications that need to hold onto resources for the user (such as open connections to the database).-->\r
-      </P>\r
-      <H2>\r
-         6. FastCGI Performance Analysis\r
-      </H2>\r
-      <P>\r
-         How fast is FastCGI? The answer depends on the application. This section contains some real FastCGI\r
-         performance measurements, as well as guidelines for estimating the FastCGI speedup.\r
-      </P>\r
-      <H3>\r
-         FastCGI vs CGI\r
-      </H3>\r
-      <P>\r
-         We measured the relative performance of CGI, FastCGI, and static files on the Open Market WebServer, using a\r
-         simple application that generates a fixed number of output bytes. The following table shows the measured\r
-         request processing time for different request types on a typical platform. The times are measured from the\r
-         client perspective and include client, server, and application processing time.\r
-      </P>\r
-      <TABLE BORDERCOLOR="#000000" BORDER="2">\r
-         <TR>\r
-            <TD WIDTH="72">\r
-               <DIV CLASS="c5">\r
-                  Static file\r
-               </DIV>\r
-            </TD>\r
-            <TD WIDTH="180">\r
-               <DIV CLASS="c5">\r
-                  21ms + 0.19ms per Kbyte\r
-               </DIV>\r
-            </TD>\r
-         </TR>\r
-         <TR>\r
-            <TD WIDTH="72">\r
-               <DIV CLASS="c5">\r
-                  FastCGI\r
-               </DIV>\r
-            </TD>\r
-            <TD WIDTH="180">\r
-               <DIV CLASS="c5">\r
-                  22ms + 0.28ms per Kbyte\r
-               </DIV>\r
-            </TD>\r
-         </TR>\r
-         <TR>\r
-            <TD WIDTH="72">\r
-               <DIV CLASS="c5">\r
-                  CGI\r
-               </DIV>\r
-            </TD>\r
-            <TD WIDTH="180">\r
-               <DIV CLASS="c5">\r
-                  59ms + 0.37ms per Kbyte\r
-               </DIV>\r
-            </TD>\r
-         </TR>\r
-      </TABLE>\r
-      <P>\r
-         FastCGI performance is comparable to serving static files, and significantly better than CGI (clearly showing\r
-         the high overhead for process creation). Real applications have an additional time component: process\r
-         initialization, which should be added to overall request processing time.\r
-      </P>\r
-      <P>\r
-         Let&#39;s use this data to estimate the speedup from migrating a typical database CGI application to FastCGI.\r
-         Assume the application takes 50ms to initialize the database connection and generates 5K of output data.\r
-         Request performance can be computed as follows:\r
-      </P>\r
-      <TABLE>\r
-         <TR>\r
-            <TD WIDTH="108">\r
-               CGI\r
-            </TD>\r
-            <TD WIDTH="331">\r
-               59ms + 50ms + (0.37ms)(5) = 111ms\r
-            </TD>\r
-         </TR>\r
-         <TR>\r
-            <TD WIDTH="108">\r
-               FastCGI\r
-            </TD>\r
-            <TD WIDTH="331">\r
-               22ms + (0.28ms)(5) = 23ms\r
-            </TD>\r
-         </TR>\r
-      </TABLE>\r
-      <P>\r
-         In this example, FastCGI has a 5x performance advantage over CGI, mostly due to savings from not having to\r
-         create and initialize new processes for each request.<!--Need to talk about FastCGI vs proprietary APIs.-->\r
-      </P>\r
-      <H2>\r
-         7. Conclusions\r
-      </H2>\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 for a logical extension from\r
-         proven and widely deployed CGI technology. This allows developers to take advantage of FastCGI&#39;s benefits\r
-         without losing their existing investment in CGI applications.<!--Need to talk about NT.-->\r
-          \r
-         <!--Need to give &quot;more punch&quot; to this conclusion: include info about uses for FastCGI (accessing legacy data in databases, access control, distributed applications, apps that have to run in multiple OS environments. -->\r
-      </P>\r
-      <H2>\r
-         8. For More Information\r
-      </H2>\r
-      <P>\r
-         For more information about Open Market and our products, visit our Web site at:<SPAN CLASS=\r
-         "c4">http://www.openmarket.com/</SPAN>\r
-      </P>\r
-      <P>\r
-         For more information about the FastCGI protocol and the developer&#39;s kit, and the latest information about\r
-         FastCGI standardization and support in other Web servers, visit the FastCGI project page at:<SPAN CLASS=\r
-         "c4">http://www.openmarket.com/fastcgi/</SPAN>\r
-      </P>\r
-   </BODY>\r
-</HTML>\r
-\r
+<HTML>
+   <HEAD>
+      <TITLE>
+         FastCGI
+      </TITLE>
+      <META NAME="GENERATOR" CONTENT="Internet Assistant for Microsoft Word 2.0z">
+<STYLE TYPE="text/css">
+ div.c5 {font-family: Arial Narrow; font-size: 80%; text-align: center}
+ span.c4 {font-family: Courier}
+ tt.c3 {font-family: Courier}
+ div.c2 {text-align: center}
+ div.c1 {color: #FFFFFF; font-family: Impact; font-size: 120%; text-align: center}
+</STYLE>
+   </HEAD>
+   <!--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: fastcgi.htm,v 1.4 2002/02/25 00:45:06 robs Exp $ -->
+   <BODY>
+      <P>
+         Open Market, Inc.
+      </P>
+      <P>
+      </P>
+      <DIV CLASS="c1">
+         Technical White Paper<BR>
+      </DIV>
+      <H1>
+         FastCGI:<BR>
+          A High-Performance Web Server Interface
+      </H1>
+      <P>
+         April 1996<!--Please send comments to:-->
+      </P>
+      <HR>
+      <!-- payne@openmarket.com-->
+      <H2>
+         1. Introduction
+      </H2>
+      <P>
+         The surge in the use of the Web by business has created a tremendous need for server extension applications
+         that create dynamic content. These are the applications that will allow businesses to deliver products,
+         services, and messages whose shape and content are in part determined by the interaction with, and knowledge
+         of, the customers to which they are delivered.
+      </P>
+      <P>
+         This important movement away from static Web content is pushing the limits and exposing the weaknesses of the
+         environment in which these applications are currently bound: CGI (Common Gateway Interface). Most importantly
+         it does not offer the performance these applications require. A new communication infrastructure is needed to
+         connect Web servers with these new applications. This is what led Open Market to develop FastCGI.
+      </P>
+      <P>
+         FastCGI is a fast, open, and secure Web server interface that solves the performance problems inherent in CGI,
+         without introducing the overhead and complexity of proprietary APIs (Application Programming Interfaces).
+      </P>
+      <P>
+         This paper assumes that the reader has basic familiarity with Web technology and developing Web applications.
+      </P>
+      <H3>
+         Common Gateway Interface
+      </H3>
+      <P>
+         The de facto standard interface for Web server applications is CGI, which was first implemented in the NCSA
+         server. CGI has many benefits:
+      </P>
+      <UL>
+         <LI>
+            <B>Simplicity.</B> <SPAN>It is easy to understand.</SPAN>
+         </LI>
+         <LI>
+            <B>Language independence.</B> CGI applications can be written in nearly any language.
+         </LI>
+         <LI>
+            <B>Process isolation.</B> Since applications run in separate processes, buggy applications cannot crash the
+            Web server or access the server&#39;s private internal state.
+         </LI>
+         <LI>
+            <B>Open standard.</B> Some form of CGI has been implemented on every Web server.
+         </LI>
+         <LI>
+            <B>Architecture independence.</B> CGI is not tied to any particular server architecture (single threaded,
+            multi-threaded, etc.).
+         </LI>
+      </UL>
+      <P>
+         CGI also has some significant drawbacks. The leading problem is performance: Since a new process is created
+         for each request and thrown away when the request is done, efficiency is poor.
+      </P>
+      <P>
+         CGI also has limited functionality: It only supports a simple &quot;responder&quot; role, where the
+         application generates the response that is returned to the client. CGI programs can&#39;t link into other
+         stages of Web server request processing, such as authorization and logging.
+      </P>
+      <H3>
+         Server APIs
+      </H3>
+      <P>
+         In response to the performance problems for CGI, several vendors have developed APIs for their servers. The
+         two most notable are NSAPI from Netscape and ISAPI from Microsoft. The freely available Apache server also has
+         an API.
+      </P>
+      <P>
+         Applications linked into the server API may be significantly faster than CGI programs. The CGI
+         startup/initialization problem is improved, because the application runs in the server process and is
+         persistent across requests. Web server APIs also offer more functionality than CGI: you can write extensions
+         that perform access control, get access to the server&#39;s log file, and link in to other stages in the
+         server&#39;s request processing.
+      </P>
+      <P>
+         However, APIs sacrifice all of CGI&#39;s benefits. Vendor APIs have the following problems:
+      </P>
+      <UL>
+         <LI>
+            <B>Complexity.</B> Vendor APIs introduce a steep learning curve, with increased implementation and
+            maintenance costs.
+         </LI>
+         <LI>
+            <B>Language dependence.</B> Applications have to be written in a language supported by the vendor API
+            (usually C/C++). Perl, the most popular language for CGI programs, can&#39;t be used with any existing
+            vendor API.
+         </LI>
+         <LI>
+            <B>No process isolation.</B> <SPAN>Since the applications run in the server&#39;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.</SPAN>
+         </LI>
+         <LI>
+            <B>Proprietary.</B> Coding your application to a particular API locks you into a particular vendor&#39;s
+            server.
+         </LI>
+         <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&#39;t gain any performance advantage. Also, when
+            the vendor changes the server&#39;s architecture, the API will usually have to change, and applications
+            will have to be adapted or rewritten.
+         </LI>
+      </UL>
+      <H3>
+         FastCGI
+      </H3>
+      <P>
+         The FastCGI interface combines the best aspects of CGI and vendor APIs. Like CGI, FastCGI applications run in
+         separate, isolated processes. FastCGI&#39;s advantages include:
+      </P>
+      <UL>
+         <LI>
+            <B>Performance.</B> FastCGI processes are persistent-they are reused to handle multiple requests. This
+            solves the CGI performance problem of creating new processes for each request.
+         </LI>
+         <LI>
+            <B>Simplicity, with easy migration from CGI.</B> The FastCGI application library (described on page 9)
+            simplifies the migration of existing CGI applications. Applications built with the application library can
+            also run as CGI programs, for backward compatibility with old Web servers.
+         </LI>
+         <LI>
+            <B>Language independence.</B> Like CGI, FastCGI applications can be written in any language, not just
+            languages supported by the vendor API.
+         </LI>
+         <LI>
+            <B>Process isolation.</B> A buggy FastCGI application cannot crash or corrupt the core server or other
+            applications. A malicious FastCGI application cannot steal any secrets (such as session keys for
+            encryption) from the Web server.
+         </LI>
+         <LI>
+            <B>Non-proprietary.</B> FastCGI is supported in all of Open Market&#39;s server products, and support is
+            under development for other Web servers, including the freely available Apache and NCSA servers, as well as
+            commercial servers from Microsoft and Netscape.
+         </LI>
+         <LI>
+            <B>Architecture independence.</B> The FastCGI interface is not tied to a particular server architecture.
+            Any Web server can implement the FastCGI interface. Also, FastCGI does not impose any architecture on the
+            application: applications can be single or multi-threaded, regardless of the threading architecture of the
+            Web server.
+         </LI>
+         <LI>
+            <B>Support for distributed computing.</B> FastCGI provides the ability to run applications remotely, which
+            is useful for distributing load and managing external Web sites.
+         </LI>
+      </UL>
+      <P>
+         The following sections describe the FastCGI interface, protocol, application library, and support in Open
+         Market&#39;s WebServer products.
+      </P>
+      <H2>
+         2. FastCGI Interface
+      </H2>
+      <P>
+         The functionality provided by the FastCGI interface is very similar to that provided by CGI. To best
+         understand the FastCGI protocol, we review the CGI interface here. Basic CGI request processing proceeds as
+         follows:
+      </P>
+      <OL>
+         <LI>
+            For each request, the server creates a new process and the process initializes itself.
+         </LI>
+         <LI>
+            The Web server passes the request information (such as remote host, username, HTTP headers, etc.) to the
+            CGI program in environment variables.
+         </LI>
+         <LI>
+            The Web server sends any client input (such as user-entered field values from an HTML form) to the CGI
+            program&#39;s standard input.
+         </LI>
+         <LI>
+            The CGI program writes any output to be returned to the client on standard output. Error information
+            written to standard error is logged by the Web server.
+         </LI>
+         <LI>
+            When the CGI process exits, the request is complete.
+         </LI>
+      </OL>
+      <P>
+         FastCGI is conceptually very similar to CGI, with two major differences:
+      </P>
+      <UL>
+         <LI>
+            FastCGI processes are persistent: after finishing a request, they wait for a new request instead of
+            exiting.
+         </LI>
+         <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.
+         </LI>
+      </UL>
+      <P>
+         Request processing in a single-threaded FastCGI application proceeds as follows:
+      </P>
+      <OL>
+         <LI>
+            The Web server creates FastCGI application processes to handle requests. The processes may be created at
+            startup, or created on demand.
+         </LI>
+         <LI>
+            The FastCGI program initializes itself, and waits for a new connection from the Web server.
+         </LI>
+         <LI>
+            When a client request comes in, the Web server opens a connection to the FastCGI process. The server sends
+            the CGI environment variable information and standard input over the connection.
+         </LI>
+         <LI>
+            The FastCGI process sends the standard output and error information back to the server over the same
+            connection.
+         </LI>
+         <LI>
+            When the FastCGI process closes the connection, the request is complete. The FastCGI process then waits for
+            another connection from the Web server.
+         </LI>
+      </OL>
+      <P>
+         FastCGI applications can run locally (on the same machine as the Web server) or remotely. For local
+         applications, the server uses a full-duplex pipe to connect to the FastCGI application process. For remote
+         applications, the server uses a TCP connection.
+      </P>
+      <P>
+         FastCGI applications can be single-threaded or multi-threaded. For single threaded applications, the Web
+         server maintains a pool of processes (if the application is running locally) to handle client requests. The
+         size of the pool is user configurable. Multi-threaded FastCGI applications may accept multiple connections
+         from the Web server and handle them simultaneously in a single process. (For example, Java&#39;s built-in
+         multi-threading, garbage collection, synchronization primitives, and platform independence make it a natural
+         implementation language for multi-threaded FastCGI applications.)
+      </P>
+      <H3>
+         Remote FastCGI
+      </H3>
+      <P>
+         FastCGI&#39;s ability to run applications remotely (over a TCP connection) provides some major benefits. These
+         benefits are described in this section, along with some of the security issues that affect remote FastCGI
+         applications.
+      </P>
+      <H4>
+         FastCGI with Firewalls
+      </H4>
+      <P>
+         Applications that run on organizational (external) Web servers and depend on internal databases can be a
+         challenge to administer. Figure 1 shows a typical organization, with an external Web server, a firewall
+         restricting access to the internal network, and internal databases and applications.
+      </P>
+      <P>
+      </P>
+      <DIV CLASS="c2">
+         <IMG ALT="error-file:TidyOut.log" SRC="img00001.gif"><A NAME="_Ref352505891">Figure 1</A>
+      </DIV>
+      <P>
+         With CGI and vendor APIs, the application has to run on the Web server machine. This means the server
+         administrator has to replicate the necessary database information onto the system hosting the Web server
+         (which may be difficult to do in an automated way without compromising firewall security). Or, the
+         administrator may build a &quot;bridge&quot; that allows access through the Web server to internal databases
+         and applications (which is effectively re-inventing remote FastCGI).
+      </P>
+      <P>
+         With remote FastCGI, the applications can run on the internal network, simplifying the administrator&#39;s
+         job. When used with appropriate firewall configuration and auditing, this approach provides a secure,
+         high-performance, scalable way to bring internal applications and data to the external network.
+      </P>
+      <H4>
+         Load Distribution
+      </H4>
+      <P>
+         For resource-intensive CGI and API applications, the Web server machine quickly becomes the bottleneck for
+         overall throughput. The usual way to solve this performance problem is to buy a bigger, faster Web server
+         machine, or to partition the Web site across several Web servers.
+      </P>
+      <P>
+         With remote FastCGI, the resource-intensive applications can be moved off the Web server machine, giving the
+         server administrator additional flexibility in configuring the Web server. The administrator can configure
+         FastCGI applications &quot;behind the scenes&quot; without having to change any content links or the external
+         view of the Web site. The administrator can use several smaller, inexpensive server machines for applications,
+         and can tailor each machine to the application it is hosting.
+      </P>
+      <H4>
+         Security Issues with Remote FastCGI
+      </H4>
+      <P>
+         The two security issues with remote FastCGI connections are authentication and privacy. FastCGI applications
+         should only accept connections from Web servers that they trust (the application library includes support for
+         IP address validation). Future versions of the protocol will include support for applications authenticating
+         Web servers, as well as support for running remote connections over secure transport protocols such as SSL or
+         PCT.<!--This pargraph needs to be made stronger, going into the issues in a little more detail.-->
+      </P>
+      <H3>
+         The FastCGI Protocol
+      </H3>
+      <P>
+         This section offers a brief introduction to the protocol used on the connection between the Web server and
+         FastCGI application. Most application developers will use the FastCGI application library and won&#39;t have
+         to worry about the protocol details. However, specialized applications are free to implement the FastCGI
+         protocol directly.
+      </P>
+      <P>
+         FastCGI uses a simple packet record format on the connection between the application and the Web server. The
+         same record format is used in both directions and is outlined in Figure 2.
+      </P>
+      <P>
+      </P>
+      <DIV CLASS="c2">
+         <IMG ALT="error-file:TidyOut.log" SRC="img00002.gif"><A NAME="_Ref352404075">Figure 2</A>
+      </DIV>
+      <P>
+         The protocol version field specifies the version of the FastCGI protocol that is in use. The type field
+         specifies the type of the record (described in the following section). The request ID identifies this record
+         to a particular request, allowing multiple requests to be multiplexed over a single connection. The data
+         length field specifies the number of data bytes that follow.
+      </P>
+      <P>
+         The different FastCGI packet types are:
+      </P>
+      <TABLE>
+         <TR>
+            <TD WIDTH="186">
+               <TT CLASS="c3">FCGI_PARAMS</TT> 
+            </TD>
+            <TD WIDTH="228">
+               Used for sending name/value pairs (CGI environment variables) from the Web server to the application.
+            </TD>
+         </TR>
+         <TR>
+            <TD WIDTH="186">
+               <TT CLASS="c3">FCGI_STDIN</TT> 
+            </TD>
+            <TD WIDTH="228">
+               Used for sending the standard input from the Web server to the application.
+            </TD>
+         </TR>
+         <TR>
+            <TD WIDTH="186">
+               <TT CLASS="c3">FCGI_DATA</TT> 
+            </TD>
+            <TD WIDTH="228">
+               Used for sending filter data to the application (for more information, see the filter role described on
+               page 7.)
+            </TD>
+         </TR>
+         <TR>
+            <TD WIDTH="186">
+               <TT CLASS="c3">FCGI_STDOUT</TT> 
+            </TD>
+            <TD WIDTH="228">
+               Used to send standard output from the application to the Web server.
+            </TD>
+         </TR>
+         <TR>
+            <TD WIDTH="186">
+               <TT CLASS="c3">FCGI_STDERR</TT> 
+            </TD>
+            <TD WIDTH="228">
+               Used to send standard error information from the application to the Web server.
+            </TD>
+         </TR>
+         <TR>
+            <TD WIDTH="186">
+               <TT CLASS="c3">FCGI_END_REQUEST</TT> 
+            </TD>
+            <TD WIDTH="228">
+               Ends the request (can be sent by either the server or the application).
+            </TD>
+         </TR>
+      </TABLE>
+      <P>
+      </P>
+      <P>
+         For complete protocol details, see the <I>FastCGI Protocol Specification</I>, available from the Web site
+         listed at the end of this paper.
+      </P>
+      <H2>
+         3. Application Roles
+      </H2>
+      <P>
+         A major problem with CGI is its limited functionality: CGI programs can only provide simple responses to
+         requests. FastCGI provides expanded functionality with support for three different application
+         &quot;roles&quot;:
+      </P>
+      <UL>
+         <LI>
+            <B>Responder.</B> This is the basic FastCGI role, and corresponds to the simple functionality offered by
+            CGI today.
+         </LI>
+         <LI>
+            <B>Filter.</B> The FastCGI application filters the requested Web server file before sending it to the
+            client.
+         </LI>
+         <LI>
+            <B>Authorizer.</B> The FastCGI program performs an access control decision for the request (such as
+            performing a username/password database lookup).
+         </LI>
+      </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&#39;s log entries for real-time processing and analysis.
+      </P>
+      <P>
+         The roles are described in more detail in the following sections.
+      </P>
+      <H3>
+         Responder Role
+      </H3>
+      <P>
+         FastCGI&#39;s Responder role is identical to the functionality provided by CGI today. When a request comes
+         into the server, the FastCGI program generates the response that&#39;s returned to the client (typically an
+         HTML page).
+      </P>
+      <H3>
+         <A NAME="_Ref352404524">Filter Role</A>
+      </H3>
+      <P>
+         The Filter role allows a FastCGI application to process a requested file before it is returned to the client.
+      </P>
+      <P>
+         Let&#39;s assume that the Web server is configured so that all files with the .<TT CLASS="c3">sgml</TT>
+         extension are processed by a SGML-to-HTML FastCGI filter application, and the user accesses the following URL:
+      </P>
+      <P>
+         <TT CLASS="c3">/document.sgml</TT>
+      </P>
+      <P>
+         After the Web server makes an access control decision and maps this URL to a content file, it invokes the
+         FastCGI filter application with this file available as input. The FastCGI program&#39;s HTML output is sent
+         back to the client, just as in the responder role. The process is outlined in Figure 3.
+      </P>
+      <P>
+      </P>
+      <DIV CLASS="c2">
+         <IMG ALT="error-file:TidyOut.log" SRC="img00003.gif"><A NAME="_Ref352560526">Figure 3</A>
+      </DIV>
+      <P>
+         Filter applications can significantly improve performance by caching filter results (the server provides the
+         modification time in the request information so that applications can flush the cache when the server file has
+         been modified).
+      </P>
+      <P>
+         The Filter role is useful for:
+      </P>
+      <UL>
+         <LI>
+            On-the-fly format conversions
+         </LI>
+         <LI>
+            Dynamic documents (such as documents with embedded SQL queries, or dynamic advertisement insertion)
+         </LI>
+         <LI>
+            Applying a standard template: headers, footers, and backgrounds
+         </LI>
+      </UL>
+      <H3>
+         Authorizer Role
+      </H3>
+      <P>
+         The Authorizer role allows a FastCGI application to make an access control decision for a request. The FastCGI
+         application is invoked with all of the request information, just as in the Responder role. If the authorizer
+         application generates a &quot;200 OK&quot; HTTP result, the Web server assumes that access is allowed and
+         proceeds with the request. (The Web server may process other access checks, including other FastCGI
+         authorizers, before access is ultimately allowed.) If the application generates any other response, that
+         response is returned to the client and the request is ended. The response can be any valid HTTP response,
+         including &quot;Access Denied&quot; or &quot;Redirect&quot;.
+      </P>
+      <P>
+         The Authorizer role is useful for:
+      </P>
+      <UL>
+         <LI>
+            Access control based on username and password, where the user information is looked up in an external
+            database.
+         </LI>
+         <LI>
+            Complex access policies, such as time-of-day based access.
+         </LI>
+         <LI>
+            Smart-card challenge/response authentication.
+         </LI>
+         <LI>
+            Dynamic redirects, where the user is sent to different pages based on the request profile.
+         </LI>
+      </UL>
+      <H2>
+         <A NAME="_Ref352251764">4. FastCGI Application Library</A>
+      </H2>
+      <P>
+         Open Market has developed a FastCGI application library that implements the FastCGI protocol (hiding the
+         protocol details from the developer). This library makes implementing FastCGI programs as easy as writing CGI
+         applications.
+      </P>
+      <P>
+         The application library provides a replacement for the C language standard I/O (stdio) routines, such as <TT
+         CLASS="c3">printf()</TT> and <TT CLASS="c3">gets()</TT>. The library converts references to 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.
+      </P>
+      <P>
+         This approach has several benefits:
+      </P>
+      <UL>
+         <LI>
+            Developers don&#39;t have to learn a new API to develop FastCGI applications.
+         </LI>
+         <LI>
+            Existing CGI programs can be migrated with minimal source changes (CGI migration is described in more
+            detail in the following section).
+         </LI>
+         <LI>
+            FastCGI interpreters for Perl, Tcl, and other interpreted languages can be built without modifying the
+            interpreter source code.
+         </LI>
+      </UL>
+      <P>
+         Here&#39;s a simple FastCGI application:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+    #include &lt;fcgi_stdio.h&gt;
+
+    void main(void)
+    {
+        int count = 0;
+        while(FCGI_Accept() &gt;= 0) {
+            printf(&quot;Content-type: text/html\r\n&quot;);
+            printf(&quot;\r\n&quot;);
+            printf(&quot;Hello world!&lt;br&gt;\r\n&quot;);
+            printf(&quot;Request number %d.&quot;, count++);
+        }
+        exit(0);
+    }
+</PRE>
+      <P>
+         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.
+      </P>
+      <P>
+         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.
+      </P>
+      <H3>
+         Migrating Existing CGI Programs
+      </H3>
+      <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. FastCGI applications have the following structure, with an initialization
+         section and a request processing loop:
+      </P>
+      <P>
+         <I>Initialize application;<BR>
+         </I> <TT>while(FCGI_Accept() &gt;= 0) {</TT><BR>
+          <I>Process request</I>;<BR>
+          <TT>}</TT>
+      </P>
+      <P>
+         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>
+      <P>
+         After migration, developers can clean up their FastCGI applications for best performance:
+      </P>
+      <UL>
+         <LI>
+            Fix any resource leaks. Many CGI programs do not attempt to manage memory or close files, because they
+            assume the world is going to be cleaned up when they exit. (If you don&#39;t want to clean up your program,
+            you can just have your process assume that it is leaking memory and exit after processing some fixed number
+            of requests.) Purify from Pure Software is one of a number of excellent tools for finding leaks and other
+            memory use problems.
+         </LI>
+         <LI>
+            Fix any problems with retained application state. The application must ensure that any state that it
+            creates in processing one request has no unintended effects on later requests.
+         </LI>
+         <LI>
+            Collapse functionality. A common practice with CGI applications is to implement many small programs, with
+            one function per program. CGI encourages this, because smaller programs load faster. With FastCGI, it&#39;s
+            better to have related functionality in a single executable, so there are fewer processes to manage and
+            applications can take advantage of sharing cached information across functions.
+         </LI>
+      </UL>
+      <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 Open Market. The interpreters are backward-compatible: They can run standard Tcl
+         and Perl applications.
+      </P>
+      <H2>
+         5. FastCGI in the Open Market WebServer
+      </H2>
+      <P>
+         This section describes the FastCGI support in the following Open Market server products:
+      </P>
+      <UL>
+         <LI>
+            Open Market WebServer V2.0
+         </LI>
+         <LI>
+            Open Market Secure WebServer V2.0
+         </LI>
+         <LI>
+            Open Market Secure WebServer (Global) V2.0
+         </LI>
+      </UL>
+      <P>
+         For more information about FastCGI support, see the <I>Open Market WebServer Installation and Configuration
+         Guide</I>.
+      </P>
+      <H3>
+         Server Configuration
+      </H3>
+      <P>
+         FastCGI applications are configured with the server&#39;s configuration file. Configuration has two parts.
+      </P>
+      <P>
+         First, the server administrator defines an <I>application class</I>. For local applications, the application
+         class specifies the details of running the FastCGI application, such as:
+      </P>
+      <UL>
+         <LI>
+            The pathname of the application executable.
+         </LI>
+         <LI>
+            Any arguments and environment variables to pass to the process at startup.
+         </LI>
+         <LI>
+            The number of processes to run.
+         </LI>
+      </UL>
+      <P>
+         For remote applications, the class configuration information includes the host and TCP port to connect to. The
+         Web server assumes that the FastCGI application has been started on the remote host. If a request comes in and
+         the server can&#39;t connect to the FastCGI TCP port, the server logs an error and returns an error page to
+         the client.
+      </P>
+      <P>
+         The second configuration step is mapping the application class to a role:
+      </P>
+      <UL>
+         <LI>
+            For responder roles, the administrator configures some part of the URL space to be handled by the FastCGI
+            application. For example, all URLs beginning with <SPAN CLASS="c4">/rollcall/</SPAN> might be handled by
+            the employee database application.
+         </LI>
+         <LI>
+            For filter roles, the administrator configures a file extension to be handled by a filter application. For
+            example, all files with the <SPAN CLASS="c4">.sql</SPAN> extension could be handled by a SQL query lookup
+            filter.
+         </LI>
+         <LI>
+            For authorizer roles, the administrator configures an authorizer application in the same manner as other
+            access methods (hostname, username/password, etc.) A request must pass <I>all</I> access control checks
+            (possibly including multiple FastCGI authorizers) before access is allowed.
+         </LI>
+      </UL>
+      <H3>
+         Basic FastCGI
+      </H3>
+      <P>
+         To simplify migration for existing CGI programs, the WebServer provides a simple way to install new FastCGI
+         programs without having to reconfigure the server. However, this approach doesn&#39;t offer all of the
+         performance benefits of FastCGI application classes.
+      </P>
+      <P>
+         The WebServer treats any file with the extension <SPAN CLASS="c4">.fcg</SPAN> as a FastCGI application. When a
+         request corresponds to such a file, the WebServer creates a new FastCGI process to handle the request, and
+         shuts down the process when the request is complete (just as in CGI). In this mode of operation performance is
+         comparable to CGI. Future versions of the WebServer will improve performance by automatically caching
+         processes and re-using them for subsequent requests.
+      </P>
+      <H3>
+         Session Affinity
+      </H3>
+      <P>
+         FastCGI programs can improve performance by caching information in the application process. For applications
+         that require frequent but expensive operations such as validating a username/password in an external database
+         for each request, this technique can significantly improve performance.
+      </P>
+      <P>
+         To improve the effectiveness of this technique, the WebServer implements <I>session affinity</I>. When session
+         affinity is enabled, the WebServer arranges for all requests in a user session to be handled by the same
+         FastCGI application process. What constitutes a &quot;session&quot; is configurable. The default configuration
+         uses the WebServer&#39;s built-in session tracking facility to identify user sessions. However, the server
+         administrator can use any part of the request information for the session affinity mapping: the URL path, the
+         client&#39;s hostname, the username, etc.
+         <!--Talk about applications that need to hold onto resources for the user (such as open connections to the database).-->
+      </P>
+      <H2>
+         6. FastCGI Performance Analysis
+      </H2>
+      <P>
+         How fast is FastCGI? The answer depends on the application. This section contains some real FastCGI
+         performance measurements, as well as guidelines for estimating the FastCGI speedup.
+      </P>
+      <H3>
+         FastCGI vs CGI
+      </H3>
+      <P>
+         We measured the relative performance of CGI, FastCGI, and static files on the Open Market WebServer, using a
+         simple application that generates a fixed number of output bytes. The following table shows the measured
+         request processing time for different request types on a typical platform. The times are measured from the
+         client perspective and include client, server, and application processing time.
+      </P>
+      <TABLE BORDERCOLOR="#000000" BORDER="2">
+         <TR>
+            <TD WIDTH="72">
+               <DIV CLASS="c5">
+                  Static file
+               </DIV>
+            </TD>
+            <TD WIDTH="180">
+               <DIV CLASS="c5">
+                  21ms + 0.19ms per Kbyte
+               </DIV>
+            </TD>
+         </TR>
+         <TR>
+            <TD WIDTH="72">
+               <DIV CLASS="c5">
+                  FastCGI
+               </DIV>
+            </TD>
+            <TD WIDTH="180">
+               <DIV CLASS="c5">
+                  22ms + 0.28ms per Kbyte
+               </DIV>
+            </TD>
+         </TR>
+         <TR>
+            <TD WIDTH="72">
+               <DIV CLASS="c5">
+                  CGI
+               </DIV>
+            </TD>
+            <TD WIDTH="180">
+               <DIV CLASS="c5">
+                  59ms + 0.37ms per Kbyte
+               </DIV>
+            </TD>
+         </TR>
+      </TABLE>
+      <P>
+         FastCGI performance is comparable to serving static files, and significantly better than CGI (clearly showing
+         the high overhead for process creation). Real applications have an additional time component: process
+         initialization, which should be added to overall request processing time.
+      </P>
+      <P>
+         Let&#39;s use this data to estimate the speedup from migrating a typical database CGI application to FastCGI.
+         Assume the application takes 50ms to initialize the database connection and generates 5K of output data.
+         Request performance can be computed as follows:
+      </P>
+      <TABLE>
+         <TR>
+            <TD WIDTH="108">
+               CGI
+            </TD>
+            <TD WIDTH="331">
+               59ms + 50ms + (0.37ms)(5) = 111ms
+            </TD>
+         </TR>
+         <TR>
+            <TD WIDTH="108">
+               FastCGI
+            </TD>
+            <TD WIDTH="331">
+               22ms + (0.28ms)(5) = 23ms
+            </TD>
+         </TR>
+      </TABLE>
+      <P>
+         In this example, FastCGI has a 5x performance advantage over CGI, mostly due to savings from not having to
+         create and initialize new processes for each request.<!--Need to talk about FastCGI vs proprietary APIs.-->
+      </P>
+      <H2>
+         7. Conclusions
+      </H2>
+      <P>
+         Today&#39;s Web business applications need a platform that&#39;s fast, open, maintainable, straightforward,
+         stable, and secure. FastCGI&#39;s design meets these requirements, and provides for a logical extension from
+         proven and widely deployed CGI technology. This allows developers to take advantage of FastCGI&#39;s benefits
+         without losing their existing investment in CGI applications.<!--Need to talk about NT.-->
+          
+         <!--Need to give &quot;more punch&quot; to this conclusion: include info about uses for FastCGI (accessing legacy data in databases, access control, distributed applications, apps that have to run in multiple OS environments. -->
+      </P>
+      <H2>
+         8. For More Information
+      </H2>
+      <P>
+         For more information about Open Market and our products, visit our Web site at:<SPAN CLASS=
+         "c4">http://www.openmarket.com/</SPAN>
+      </P>
+      <P>
+         For more information about the FastCGI protocol and the developer&#39;s kit, and the latest information about
+         FastCGI standardization and support in other Web servers, visit the FastCGI project page at:<SPAN CLASS=
+         "c4">http://www.openmarket.com/fastcgi/</SPAN>
+      </P>
+   </BODY>
+</HTML>
+
index a0a8556..0f2c8ac 100644 (file)
-<!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.5 2001/11/27 03:06:17 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</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, see <A HREF=\r
-         "http://fastcgi.com/fastcgi-developers">http://fastcgi.com/fastcgi-developers</A>.\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
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         FastCGI Developer&#39;s Kit
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #FFFFFF;
+  color: #000000;
+ }
+ :link { color: #cc0000 }
+ :visited { color: #555555 }
+ :active { color: #000011 }
+ h5.c3 {text-align: center}
+ h3.c2 {text-align: center}
+ p.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <P CLASS="c1">
+         <IMG BORDER="0" SRC="../images/fcgi-hd.gif" ALT="[[FastCGI]]"><BR CLEAR="all">
+      </P>
+      <H3 CLASS="c2">
+         FastCGI Developer&#39;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 CLASS="c1">
+         Mark R. Brown<BR>
+          Open Market, Inc.<BR>
+      </P>
+      <P CLASS="c1">
+         Document Version: 1.08<BR>
+          11 June 1996<BR>
+      </P>
+      <H5 CLASS="c3">
+         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-devel-kit.htm,v 1.6 2002/02/25 00:42:59 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&#39;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:
+      </P>
+      <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&#39;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&#39;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://cgi-spec.golux.com/">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&#39;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&#39;t work
+         when index.html is opened using the &quot;Open File&quot; command because they aren&#39;t aren&#39;t being
+         accessed through a Web server.
+      </P>
+      <P>
+         In order to use the kit in earnest you&#39;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&#39;s not possible, arrange a configuration
+         such that the kit is accessible from the machine that&#39;s going to run your Web server, and build the kit
+         and your applications on a machine that&#39;s configured exactly the same way (same processor architecture,
+         operating system, etc.) as the machine that&#39;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&#39;ve built and exercised the kit on these platforms (listed in alphabetical order):
+      </P>
+      <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&#39;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:
+      </P>
+      <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:
+      </P>
+      <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&#39;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:
+      </P>
+      <UL TYPE="square">
+         <LI>
+            Add the directory containing the <TT>fcgi_stdio.h</TT> header to the compiler&#39;s include search path.
+            The kit calls this directory <TT>include</TT>.
+         </LI>
+         <LI>
+            Add the library <TT>libfcgi.a</TT> to the linker&#39;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&#39;t replace these.) For instance, <TT>FILE</TT> becomes <TT>FCGI_FILE</TT> and <TT>printf</TT> becomes
+         <TT>FCGI_printf</TT>. You&#39;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:
+      </P>
+      <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&#39;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&#39;ll need to include the headers for these libraries <I>before</I> you include
+            <TT>fcgi_stdio.h</TT>. You can&#39;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&#39;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&#39;t worry about storage leaks because the programs
+         don&#39;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:
+      </P>
+      <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&#39;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&#39;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:
+      </P>
+      <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>&#39;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&#39;d then open the URL
+         <TT>http://bowser:8888/index.html</TT> to reach the kit&#39;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&#39;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&#39;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</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, see <A HREF=
+         "http://fastcgi.com/fastcgi-developers">http://fastcgi.com/fastcgi-developers</A>.
+      </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>
+         &copy; 1996, Open Market, Inc. / mbrown@openmarket.com
+      </ADDRESS>
+   </BODY>
+</HTML>
+
index 88d3a9b..b19f381 100644 (file)
-<!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
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         Integrating FastCGI with Java
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #FFFFFF;
+  color: #000000;
+ }
+ :link { color: #cc0000 }
+ :visited { color: #555555 }
+ :active { color: #000011 }
+ dt.c4 {font-style: italic}
+ h5.c3 {text-align: center}
+ p.c2 {text-align: center}
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <DIV CLASS="c1">
+         <A HREF="http://fastcgi.com"><IMG BORDER="0" SRC="../images/fcgi-hd.gif" ALT="[[FastCGI]]"></A>
+      </DIV>
+      <BR CLEAR="all">
+      <DIV CLASS="c1">
+         <H3>
+            Integrating FastCGI with Java
+         </H3>
+      </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: fcgi-java.htm,v 1.4 2002/02/25 00:42:59 robs Exp $ -->
+      <P CLASS="c2">
+         Steve Harris<BR>
+         Open Market, Inc.<BR>
+         <EM>7 May 1996</EM>
+      </P>
+      <H5 CLASS="c3">
+         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>
+      <P>
+         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&#39;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>
+      <P>
+         There are two kinds of applications built using Java.
+      </P>
+      <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>
+         <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.
+         </LI>
+      </UL>
+      <P>
+         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>
+      <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.
+      </P>
+      <H3>
+         <A NAME="S2">2. Writing FastCGI applications in Java</A>
+      </H3>
+      <P>
+         Writing a FastCGI application in Java is as simple as writing one in C.
+      </P>
+      <OL>
+         <LI>
+            Import the <TT>FCGIInterface</TT> class.
+         </LI>
+         <LI>
+            Perform one-time initialization at the top of the <TT>main()</TT> method.
+         </LI>
+         <LI>
+            Create a new <TT>FCGIInterface</TT> object and send it an <TT>FCGIaccept()</TT> message in a loop.
+         </LI>
+         <LI>
+            Put the per-request application code inside that loop.
+         </LI>
+      </OL>
+      <P>
+         On return from <TT>FCGIaccept()</TT> you can access the request&#39;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>
+      <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&#39;s Kit document</A>.
+      </P>
+      <H4>
+         A. TinyCGI
+      </H4>
+<PRE>
+class TinyCGI { 
+ public static void main (String args[]) {  
+  int count = 0;
+                ++count;
+  System.out.println(&quot;Content-type: text/html\n\n&quot;);
+  System.out.println(&quot;&lt;html&gt;&quot;);
+  System.out.println(
+                 &quot;&lt;head&gt;&lt;TITLE&gt;CGI Hello&lt;/TITLE&gt;&lt;/head&gt;&quot;);
+  System.out.println(&quot;&lt;body&gt;&quot;);
+  System.out.println(&quot;&lt;H3&gt;CGI-Hello&lt;/H3&gt;&quot;);
+  System.out.println(&quot;request number &quot; + count + 
+     &quot; running on host &quot; 
+    + System.getProperty&lt;&quot;SERVER_NAME&quot;));
+  System.out.println(&quot;&lt;/body&gt;&quot;);
+  System.out.println(&quot;&lt;/html&gt;&quot;); 
+  }
+ }
+
+</PRE>
+      <H4>
+         B. TinyFCGI
+      </H4>
+<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\n\n&quot;);
+   System.out.println(&quot;&lt;html&gt;&quot;);
+   System.out.println(
+     &quot;&lt;head&gt;&lt;TITLE&gt;FastCGI-Hello Java stdio&lt;/TITLE&gt;&lt;/head&gt;&quot;);
+   System.out.println(&quot;&lt;body&gt;&quot;);
+   System.out.println(&quot;&lt;H3&gt;FastCGI-HelloJava stdio&lt;/H3&gt;&quot;);
+   System.out.println(&quot;request number &quot; + count + 
+     &quot; running on host &quot; 
+    + System.getProperty&lt;&quot;SERVER_NAME&quot;));
+   System.out.println(&quot;&lt;/body&gt;&quot;);
+   System.out.println(&quot;&lt;/html&gt;&quot;); 
+   }
+  }
+ }
+
+</PRE>
+      <H4>
+         C. Running these Examples
+      </H4>
+      <P>
+         We assume that you have downloaded the JDK and the FastCGI Developer&#39;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.
+      </P>
+      <H5>
+         Configuring
+      </H5>
+      <OL>
+         <LI>
+            Add your JDK&#39;s <TT>java/bin</TT> directory to your Unix <TT>PATH</TT> if it isn&#39;t there
+            already.<BR>
+            <BR>
+         </LI>
+         <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>
+         <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>
+               <LI>
+                  <I>portNum</I> is the port that you&#39;ve selected for communication between the Web server and the
+                  Java application.<BR>
+               </LI>
+            </UL>
+            <BR>
+             On other servers you can use <TT>cgi-fcgi</TT> to get a similar effect.
+         </LI>
+         <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>
+         <LI>
+            You might have to modify <TT>examples/TinyFCGI.cgi</TT> to use a Unix shell for which your CLASSPATH is
+            defined.
+         </LI>
+      </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>
+         <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>
+         <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.
+         </LI>
+      </UL>
+      <P>
+         Due to gaps in the Java interpreter&#39;s support for listening sockets, Java FastCGI applications are
+         currently limited to being started as external applications. They can&#39;t be started and managed by the Web
+         server because they are incapable of using a listening socket that the Web server creates.
+      </P>
+      <H3>
+         <A NAME="S3">3. Standard I/O and Application Libraries</A>
+      </H3>
+      <P>
+         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>
+      <P>
+         Java defines standard I/O in the <I>java.System</I> class as follows:
+      </P>
+      <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>
+      <P>
+         The File Descriptors <I>in</I>, <I>out</I>, <I>err</I> are constants set to 0, 1 and 2 respectively.
+      </P>
+      <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>
+      <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.
+      </P>
+      <H3>
+         <A NAME="S4">4. Environment Variables</A>
+      </H3>
+      <P>
+         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>
+      <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>
+      <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&#39;t be needed, since its use is due to an acknowledged rigidity in the
+         JDK&#39;s implementation of sockets.
+      </P>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S4">5. Further examples: EchoFCGI and Echo2FCGI</A>
+      </H3>
+      <P>
+         The next two examples illustrate the points made in the last two sections. EchoFCGI and Echo2FCGI both echo
+         user input and display the application&#39;s environment variables. EchoFCGI reads the user input from
+         System.in, while Echo2FCGI reads the user input directly from the intermediate FastCGI input stream.
+      </P>
+      <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()&gt;= 0) {
+  System.out.println(&quot;Content-type: text/html\n\n&quot;);
+   System.out.println(&quot;&lt;html&gt;&quot;);
+   System.out.println(
+    &quot;&lt;head%gt;&lt;TITLE&gt;FastCGI echo
+                                      &lt;/TITLE&gt;&lt;/head&gt;&quot;);
+   System.out.println(&quot;&lt;body&gt;&quot;); 
+   System.out.println(
+                                         &quot;&lt;H2&gt;FastCGI echo&lt;/H2&gt;&quot;);
+   System.out.println(&quot;&lt;H3&gt;STDIN&lt;/H3&gt;&quot;);
+   for ( int c = 0; c != -1; ) {
+    try {
+     c = System.in.read();
+    } catch(IOException e) {
+     System.out.println(
+     &quot;&lt;br&gt;&lt;b&gt;SYSTEM EXCEPTION&quot;);
+     Runtime rt = Runtime.getRuntime();
+     rt.exit(status);
+     }
+    if (c != -1) { 
+     System.out.print((char)c);
+     }
+    }
+   System.out.println(
+    &quot;&lt;H3&gt;Environment Variables:&lt;/H3&gt;&quot;);
+   System.getProperties().list(System.out);
+   System.out.println(&quot;&lt;/body&gt;&quot;);
+   System.out.println(&quot;&lt;/html&gt;&quot;);
+      }
+  }
+   }
+</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()&gt;= 0) {
+  System.out.println(&quot;Content-type: text/html\n\n&quot;);
+   System.out.println(&quot;&lt;html&gt;&quot;);
+   System.out.println(
+    &quot;&lt;head&gt;&lt;TITLE&gt;FastCGI echo
+                                    &lt;/TITLE&gt;&lt;/head&gt;&quot;);
+   System.out.println(&quot;&lt;body&gt;&quot;);   
+   System.out.println(&quot;&lt;H2&gt;FastCGI echo&lt;/H2&gt;&quot;);
+   System.out.println(&quot;&lt;H3&gt;STDIN:&lt;/H3&quot;&gt;);
+   for ( int c = 0; c != -1; ) {
+    try {
+     c = intf.request.inStream.read();
+    } catch(IOException e) {
+     System.out.println(
+     &quot;&lt;br&gt;&lt;b&gt;SYSTEM EXCEPTION&quot;);
+     Runtime rt = Runtime.getRuntime();
+     rt.exit(status);
+     }
+    if (c != -1) { 
+     System.out.print((char)c);
+     }
+    }
+   System.out.println(
+    &quot;&lt;H3&gt;Environment Variables:&lt;/H3&gt;&quot;);
+   System.getProperties().list(System.out);
+   System.out.println(&lt;&quot;/body&gt;&quot;);
+   System.out.println(&quot;&lt;/html&gt;&quot;);
+      }
+  }
+   }
+</PRE>
+      <H4>
+         C. Running these Examples
+      </H4>
+      <H5>
+         Configuring
+      </H5>
+      <P>
+         As with TinyFCGI, you need to configure the web server to recognize these two FastCGI applications. Your
+         configuration now looks like this:
+      </P>
+      <P>
+      </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.
+      </P>
+      <H5>
+         Running
+      </H5>
+      <P>
+         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.
+      </P>
+      <H3>
+         <A NAME="S6">6. FastCGI Java Classes</A>
+      </H3>
+      <P>
+         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>
+      <P>
+      </P>
+      <DL>
+         <DT CLASS="c4">
+            FCGIInterface
+         </DT>
+         <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>
+         </DD>
+         <DT CLASS="c4">
+            FCGIInputStream
+         </DT>
+         <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>
+         </DD>
+         <DT CLASS="c4">
+            FCGIOutputStream
+         </DT>
+         <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>
+         </DD>
+         <DT CLASS="c4">
+            FCGIMessage
+         </DT>
+         <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>
+         </DD>
+         <DT CLASS="c4">
+            FCGIRequest
+         </DT>
+         <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>
+         </DD>
+         <DT CLASS="c4">
+            FCGIGlobalDefs
+         </DT>
+         <DD>
+            This class contains definitions of FastCGI constants.
+         </DD>
+      </DL>
+      <HR>
+      <ADDRESS>
+         <A HREF="mailto:harris@openmarket.com">Steve Harris // harris@openmarket.com</A>
+      </ADDRESS>
+   </BODY>
+</HTML>
+
index 329ce28..bf697c9 100644 (file)
-<!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
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         Understanding FastCGI Application Performance
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #FFFFFF;
+  color: #000000;
+ }
+ :link { color: #cc0000 }
+ :visited { color: #555555 }
+ :active { color: #000011 }
+ div.c3 {margin-left: 2em}
+ h5.c2 {text-align: center}
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <DIV CLASS="c1">
+         <A HREF="http://fastcgi.com"><IMG BORDER="0" SRC="../images/fcgi-hd.gif" ALT="[[FastCGI]]"></A>
+      </DIV>
+      <BR CLEAR="all">
+      <DIV CLASS="c1">
+         <H3>
+            Understanding FastCGI Application Performance
+         </H3>
+      </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.                   -->
+      <DIV CLASS="c1">
+         Mark R. Brown<BR>
+         Open Market, Inc.<BR>
+         <P>
+            10 June 1996<BR>
+         </P>
+      </DIV>
+      <P>
+      </P>
+      <H5 CLASS="c2">
+         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.4 2002/02/25 00:42:59 robs Exp $<BR>
+      </H5>
+      <HR>
+      <UL TYPE="square">
+         <LI>
+            <A HREF="#S1">1. Introduction</A>
+         </LI>
+         <LI>
+            <A HREF="#S2">2. Performance Basics</A>
+         </LI>
+         <LI>
+            <A HREF="#S3">3. Caching</A>
+         </LI>
+         <LI>
+            <A HREF="#S4">4. Database Access</A>
+         </LI>
+         <LI>
+            <A HREF="#S5">5. A Performance Test</A> 
+            <UL TYPE="square">
+               <LI>
+                  <A HREF="#S5.1">5.1 Application Scenario</A>
+               </LI>
+               <LI>
+                  <A HREF="#S5.2">5.2 Application Design</A>
+               </LI>
+               <LI>
+                  <A HREF="#S5.3">5.3 Test Conditions</A>
+               </LI>
+               <LI>
+                  <A HREF="#S5.4">5.4 Test Results and Discussion</A>
+               </LI>
+            </UL>
+         </LI>
+         <LI>
+            <A HREF="#S6">6. Multi-threaded APIs</A>
+         </LI>
+         <LI>
+            <A HREF="#S7">7. Conclusion</A>
+         </LI>
+      </UL>
+      <P>
+      </P>
+      <HR>
+      <H3>
+         <A NAME="S1">1. Introduction</A>
+      </H3>
+      <P>
+         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>
+      <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>
+      <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 &quot;executes web
+         applications up to five times faster than all other servers,&quot; but the ad gives little clue where the
+         number &quot;five&quot; came from.
+      </P>
+      <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
+         &quot;unfair&quot; 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&#39;d need to measure to figure that
+         out for the situation you face, rather than just saying &quot;we&#39;re three times faster&quot; and moving
+         on.
+      </P>
+      <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&#39;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>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S2">2. Performance Basics</A>
+      </H3>
+      <P>
+         Since this paper is about performance we need to be clear on what &quot;performance&quot; is.
+      </P>
+      <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>
+      <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&#39;s response, response time at both the
+         client and the server will go up, and there&#39;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>
+      <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>
+      <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>
+      <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>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S3">3. Caching</A>
+      </H3>
+      <P>
+         It is a rare Web server application that doesn&#39;t run fast when all the information it needs is available
+         in its memory. And if the application doesn&#39;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&#39;s functional specification so it doesn&#39;t need to do so much work.
+      </P>
+      <P>
+         The way to make information available in memory is by caching. A cache is an in-memory data structure that
+         contains information that&#39;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&#39;t improve
+         performance when it is empty.
+      </P>
+      <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&#39;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>
+      <P>
+         Today&#39;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>
+      <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&#39;t provide a way to do it).
+      </P>
+      <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>
+      <P>
+         In some cases a single FastCGI application server won&#39;t provide enough performance. FastCGI provides two
+         solutions: session affinity and multi-threading.
+      </P>
+      <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&#39;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>
+      <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>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S4">4. Database Access</A>
+      </H3>
+      <P>
+         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>
+      <P>
+         Access to database management systems, even within a single machine, is via connection-oriented protocols. An
+         application &quot;logs in&quot; 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>
+      <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>
+      <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&#39;s hardware resources, it could
+         break your software budget.
+      </P>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S5">5. A Performance Test</A>
+      </H3>
+      <P>
+         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>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S5.1">5.1 Application Scenario</A>
+      </H4>
+      <P>
+         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>
+      <P>
+         Each request accomplishes the following:
+      </P>
+      <P>
+      </P>
+      <OL>
+         <LI>
+            authentication check: The user id is used to retrieve and check the password.
+            <P>
+            </P>
+         </LI>
+         <LI>
+            attribute retrieval: The user id is used to retrieve all of the user&#39;s attribute values.
+            <P>
+            </P>
+         </LI>
+         <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&#39;s corresponding attribute values. The modified HTML is
+            returned to the user.<BR>
+            <BR>
+         </LI>
+      </OL>
+      <P>
+         Of course, it is fair game to perform caching to shortcut any of these steps.
+      </P>
+      <P>
+         Each user&#39;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>
+      <P>
+         A typical user makes 10 file accesses with realistic think times (30-60 seconds) between accesses, then
+         disappears for a long time.
+      </P>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S5.2">5.2 Application Design</A>
+      </H4>
+      <P>
+         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>
+      <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&#39;s requests
+         after the first hit in the application&#39;s cache.
+      </P>
+      <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>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S5.3">5.3 Test Conditions</A>
+      </H4>
+      <P>
+         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>
+      <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>
+      <P>
+         Response time is not an issue under the test conditions. We just measure throughput.
+      </P>
+      <P>
+         The API Web server is in these tests is Netscape 1.1.
+      </P>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S5.4">5.4 Test Results and Discussion</A>
+      </H4>
+      <P>
+         Here are the test results:
+      </P>
+      <P>
+      </P>
+      <DIV CLASS="c3">
+<PRE>
+    FastCGI  12.0 msec per request = 83 requests per second
+    API      36.6 msec per request = 27 requests per second
+</PRE>
+      </DIV>
+      <P>
+         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>
+      <P>
+      </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>
+            </P>
+<PRE>
+    API      16.0 msec per request = 61 requests per second
+</PRE>
+            Answer: Still not as fast as the FastCGI application.
+            <P>
+            </P>
+         </LI>
+         <LI>
+            FastCGI with cache disabled. How much benefit does the FastCGI application get from its cache?
+            <P>
+            </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.<BR>
+            <BR>
+         </LI>
+      </UL>
+      <P>
+         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&#39;d expect, since the FastCGI application has to pay the cost of
+         inter-process communication not present in the API application.
+      </P>
+      <P>
+         In the real world the two applications would not be implemented in the same way. FastCGI&#39;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>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S6">6. Multi-threaded APIs</A>
+      </H3>
+      <P>
+         Web servers with a multi-threaded internal structure (and APIs to match) are now starting to become more
+         common. These servers don&#39;t have all of the disadvantages described in Section 3. Does this mean that
+         FastCGI&#39;s performance advantages will disappear?
+      </P>
+      <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>
+      <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>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S7">7. Conclusion</A>
+      </H3>
+      <P>
+         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>
+      <P>
+      </P>
+      <HR>
+      <A HREF="http://www.openmarket.com/"><IMG SRC="omi-logo.gif" ALT="OMI Home Page"></A> 
+      <ADDRESS>
+         &copy; 1995, Open Market, Inc. / mbrown@openmarket.com
+      </ADDRESS>
+   </BODY>
+</HTML>
+
index 60c4a92..c5f936c 100644 (file)
@@ -1,53 +1,53 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//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
-       \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.4 2001/11/27 18:38:06 robs Exp $<BR>\r
-      </H5>\r
-      <HR>\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.\r
-      </P>\r
-      <P>\r
-         FastCGI support is available for Perl via the FCGI.pm Perl module. FCGI.pm no longer requires SFIO or a\r
-         specially-built Perl. FCGI.pm is available via CPAN as well as in the perl directory of this kit.\r
-      </P>\r
-      <P>\r
-         Please see the FCGI.pm documentation for examples and details.\r
-      </P>\r
-   </BODY>\r
-</HTML>\r
-\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         Integrating FastCGI with Perl-5
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #FFFFFF;
+  color: #000000;
+ }
+ :link { color: #cc0000 }
+ :visited { color: #555555 }
+ :active { color: #000011 }
+ p.c3 {text-align: center}
+ h5.c2 {text-align: center}
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <DIV CLASS="c1">
+         <A HREF="http://fastcgi.com"><IMG BORDER="0" SRC="../images/fcgi-hd.gif" ALT="[[FastCGI]]"></A>
+      </DIV>
+      <BR CLEAR="all">
+       
+      <DIV CLASS="c1">
+         <H3>
+            Integrating FastCGI with Perl-5
+         </H3>
+      </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.                   -->
+      <H5 CLASS="c2">
+         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.5 2002/02/25 00:42:59 robs Exp $<BR>
+      </H5>
+      <HR>
+      <P>
+         Perl (Practical Extraction and Report Language) is a scripting language that is often used for CGI
+         programming. Perl is freely available.
+      </P>
+      <P>
+         FastCGI support is available for Perl via the FCGI.pm Perl module. FCGI.pm no longer requires SFIO or a
+         specially-built Perl. FCGI.pm is available via CPAN as well as in the perl directory of this kit.
+      </P>
+      <P>
+         Please see the FCGI.pm documentation for examples and details.
+      </P>
+   </BODY>
+</HTML>
+
index eb30ce8..e24f378 100644 (file)
-<!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
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<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>
+<STYLE TYPE="text/css">
+ h5.c2 {text-align: center}
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <DIV CLASS="c1">
+         <H2>
+            FastCGI Specification
+         </H2>
+      </DIV>
+      <DIV CLASS="c1">
+         Mark R. Brown<BR>
+         Open Market, Inc.<BR>
+         <P>
+            Document Version: 1.0<BR>
+            29 April 1996<BR>
+         </P>
+      </DIV>
+      <P>
+      </P>
+      <H5 CLASS="c2">
+         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.4 2002/02/25 00:42:59 robs Exp $
+      </H5>
+      <HR>
+      <UL TYPE="square">
+         <LI>
+            <A HREF="#S1">1. Introduction</A>
+         </LI>
+         <LI>
+            <A HREF="#S2">2. Initial Process State</A> 
+            <UL TYPE="square">
+               <LI>
+                  <A HREF="#S2.1">2.1 Argument list</A>
+               </LI>
+               <LI>
+                  <A HREF="#S2.2">2.2 File descriptors</A>
+               </LI>
+               <LI>
+                  <A HREF="#S2.3">2.3 Environment variables</A>
+               </LI>
+               <LI>
+                  <A HREF="#S2.4">2.4 Other state</A>
+               </LI>
+            </UL>
+         </LI>
+         <LI>
+            <A HREF="#S3">3. Protocol Basics</A> 
+            <UL TYPE="square">
+               <LI>
+                  <A HREF="#S3.1">3.1 Notation</A>
+               </LI>
+               <LI>
+                  <A HREF="#S3.2">3.2 Accepting Transport Connections</A>
+               </LI>
+               <LI>
+                  <A HREF="#S3.3">3.3 Records</A>
+               </LI>
+               <LI>
+                  <A HREF="#S3.4">3.4 Name-Value Pairs</A>
+               </LI>
+               <LI>
+                  <A HREF="#S3.5">3.5 Closing Transport Connections</A>
+               </LI>
+            </UL>
+         </LI>
+         <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>
+               <LI>
+                  <A HREF="#S4.2">4.2 <TT>FCGI_UNKNOWN_TYPE</TT></A>
+               </LI>
+            </UL>
+         </LI>
+         <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>
+               <LI>
+                  <A HREF="#S5.2">5.2 Name-Value Pair Streams: <TT>FCGI_PARAMS</TT>, <TT>FCGI_RESULTS</TT></A>
+               </LI>
+               <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>
+               <LI>
+                  <A HREF="#S5.4">5.4 <TT>FCGI_ABORT_REQUEST</TT></A>
+               </LI>
+               <LI>
+                  <A HREF="#S5.5">5.5 <TT>FCGI_END_REQUEST</TT></A>
+               </LI>
+            </UL>
+         </LI>
+         <LI>
+            <A HREF="#S6">6. Roles</A> 
+            <UL TYPE="square">
+               <LI>
+                  <A HREF="#S6.1">6.1 Role Protocols</A>
+               </LI>
+               <LI>
+                  <A HREF="#S6.2">6.2 Responder</A>
+               </LI>
+               <LI>
+                  <A HREF="#S6.3">6.3 Authorizer</A>
+               </LI>
+               <LI>
+                  <A HREF="#S6.4">6.4 Filter</A>
+               </LI>
+            </UL>
+         </LI>
+         <LI>
+            <A HREF="#S7">7. Errors</A>
+         </LI>
+         <LI>
+            <A HREF="#S8">8. Types and Constants</A>
+         </LI>
+         <LI>
+            <A HREF="#S9">9. References</A>
+         </LI>
+         <LI>
+            <A HREF="#SA">A. Table: Properties of the record types</A>
+         </LI>
+         <LI>
+            <A HREF="#SB">B. Typical Protocol Message Flow</A>
+         </LI>
+      </UL>
+      <P>
+      </P>
+      <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>
+         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>
+      <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>
+      <P>
+         We&#39;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&#39;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>
+      <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&#39;t begin life connected to anything. It doesn&#39;t have the conventional open
+         files <TT>stdin</TT>, <TT>stdout</TT>, and <TT>stderr</TT>, and it doesn&#39;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>
+      <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>
+      <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&#39;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 &quot;filtered&quot; version of the data stream as an HTTP response. The framework is
+         extensible so that more FastCGI can be defined later.
+      </P>
+      <P>
+         In the remainder of this specification the terms &quot;FastCGI application,&quot; &quot;application
+         process,&quot; or &quot;application server&quot; are abbreviated to &quot;application&quot; whenever that
+         won&#39;t cause confusion.
+      </P>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S2">2. Initial Process State</A>
+      </H3>
+      <H4>
+         <A NAME="S2.1">2.1 Argument list</A>
+      </H4>
+      <P>
+         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&#39;s path name. The Web server may provide a way to specify
+         a different application name, or a more elaborate argument list.
+      </P>
+      <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&#39;s argument list is constructed as described in the
+         <TT>execve</TT> manpage.
+      </P>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S2.2">2.2 File descriptors</A>
+      </H4>
+      <P>
+         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>
+      <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>
+      <P>
+         The Web server&#39;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>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S2.3">2.3 Environment variables</A>
+      </H4>
+      <P>
+         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>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S2.4">2.4 Other state</A>
+      </H4>
+      <P>
+         The Web server may provide a way to specify other components of an application&#39;s initial process state,
+         such as the priority, user ID, group ID, root directory, and working directory of the process.
+      </P>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S3">3. Protocol Basics</A>
+      </H3>
+      <H4>
+         <A NAME="S3.1">3.1 Notation</A>
+      </H4>
+      <P>
+         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>
+      <P>
+         We use two conventions to abbreviate our definitions.
+      </P>
+      <P>
+         First, when two adjacent structure components are named identically except for the suffixes
+         &quot;<TT>B1</TT>&quot; and &quot;<TT>B0</TT>,&quot; it means that the two components may be viewed as a
+         single number, computed as <TT>B1&lt;&lt;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>
+      <P>
+         Second, we extend C <TT>struct</TT>s to allow the form
+      </P>
+<PRE>
+        struct {
+            unsigned char mumbleLengthB1;
+            unsigned char mumbleLengthB0;
+            ... /* other stuff */
+            unsigned char mumbleData[mumbleLength];
+        };
+</PRE>
+      <P>
+         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>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S3.2">3.2 Accepting Transport Connections</A>
+      </H4>
+      <P>
+         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>
+      <P>
+      </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&#39;t use TCP/IP transport), the application responds by closing the connection.
+            </P>
+            <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>
+            <BR>
+            <BR>
+         </LI>
+      </UL>
+      <P>
+         An application may accept several concurrent transport connections, but it need not do so.
+      </P>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S3.3">3.3 Records</A>
+      </H4>
+      <P>
+         Applications execute requests from a Web server using a simple protocol. Details of the protocol depend upon
+         the application&#39;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>
+      <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>
+      <P>
+      </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>
+      <P>
+         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>
+      <P>
+      </P>
+      <UL TYPE="square">
+         <LI>
+            <TT>version</TT>: Identifies the FastCGI protocol version. This specification documents
+            <TT>FCGI_VERSION_1</TT>.
+            <P>
+            </P>
+         </LI>
+         <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>
+            </P>
+         </LI>
+         <LI>
+            <TT>requestId</TT>: Identifies the <I>FastCGI request</I> to which the record belongs.
+            <P>
+            </P>
+         </LI>
+         <LI>
+            <TT>contentLength</TT>: The number of bytes in the <TT>contentData</TT> component of the record.
+            <P>
+            </P>
+         </LI>
+         <LI>
+            <TT>paddingLength</TT>: The number of bytes in the <TT>paddingData</TT> component of the record.
+            <P>
+            </P>
+         </LI>
+         <LI>
+            <TT>contentData</TT>: Between 0 and 65535 bytes of data, interpreted according to the record type.
+            <P>
+            </P>
+         </LI>
+         <LI>
+            <TT>paddingData</TT>: Between 0 and 255 bytes of data, which are ignored.<BR>
+            <BR>
+         </LI>
+      </UL>
+      <P>
+         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>
+      <P>
+      </P>
+      <H5>
+         Padding
+      </H5>
+      <P>
+         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>
+      <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>
+      <P>
+      </P>
+      <H5>
+         Managing Request IDs
+      </H5>
+      <P>
+         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>
+      <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>
+      <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>
+      <P>
+      </P>
+      <H5>
+         Types of Record Types
+      </H5>
+      <P>
+         There are two useful ways of classifying FastCGI record types.
+      </P>
+      <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>
+      <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>
+      <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&#39;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>
+      <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&#39;s a stream in some later version of the protocol.
+      </P>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S3.4">3.4 Name-Value Pairs</A>
+      </H4>
+      <P>
+         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>
+      <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>
+      <P>
+      </P>
+<PRE>
+        typedef struct {
+            unsigned char nameLengthB0;  /* nameLengthB0  &gt;&gt; 7 == 0 */
+            unsigned char valueLengthB0; /* valueLengthB0 &gt;&gt; 7 == 0 */
+            unsigned char nameData[nameLength];
+            unsigned char valueData[valueLength];
+        } FCGI_NameValuePair11;
+
+        typedef struct {
+            unsigned char nameLengthB0;  /* nameLengthB0  &gt;&gt; 7 == 0 */
+            unsigned char valueLengthB3; /* valueLengthB3 &gt;&gt; 7 == 1 */
+            unsigned char valueLengthB2;
+            unsigned char valueLengthB1;
+            unsigned char valueLengthB0;
+            unsigned char nameData[nameLength];
+            unsigned char valueData[valueLength
+                    ((B3 &amp; 0x7f) &lt;&lt; 24) + (B2 &lt;&lt; 16) + (B1 &lt;&lt; 8) + B0];
+        } FCGI_NameValuePair14;
+
+        typedef struct {
+            unsigned char nameLengthB3;  /* nameLengthB3  &gt;&gt; 7 == 1 */
+            unsigned char nameLengthB2;
+            unsigned char nameLengthB1;
+            unsigned char nameLengthB0;
+            unsigned char valueLengthB0; /* valueLengthB0 &gt;&gt; 7 == 0 */
+            unsigned char nameData[nameLength
+                    ((B3 &amp; 0x7f) &lt;&lt; 24) + (B2 &lt;&lt; 16) + (B1 &lt;&lt; 8) + B0];
+            unsigned char valueData[valueLength];
+        } FCGI_NameValuePair41;
+
+        typedef struct {
+            unsigned char nameLengthB3;  /* nameLengthB3  &gt;&gt; 7 == 1 */
+            unsigned char nameLengthB2;
+            unsigned char nameLengthB1;
+            unsigned char nameLengthB0;
+            unsigned char valueLengthB3; /* valueLengthB3 &gt;&gt; 7 == 1 */
+            unsigned char valueLengthB2;
+            unsigned char valueLengthB1;
+            unsigned char valueLengthB0;
+            unsigned char nameData[nameLength
+                    ((B3 &amp; 0x7f) &lt;&lt; 24) + (B2 &lt;&lt; 16) + (B1 &lt;&lt; 8) + B0];
+            unsigned char valueData[valueLength
+                    ((B3 &amp; 0x7f) &lt;&lt; 24) + (B2 &lt;&lt; 16) + (B1 &lt;&lt; 8) + B0];
+        } FCGI_NameValuePair44;
+</PRE>
+      <P>
+         The high-order bit of the first byte of a length indicates the length&#39;s encoding. A high-order zero
+         implies a one-byte encoding, a one a four-byte encoding.
+      </P>
+      <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>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S3.5">3.5 Closing Transport Connections</A>
+      </H4>
+      <P>
+         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>
+      <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>
+      <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>
+      <P>
+         When an application closes a connection or finds that a connection has closed, the application initiates a new
+         connection.
+      </P>
+      <P>
+      </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>
+      <P>
+         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>
+      <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>
+      <P>
+         The application responds by sending a record <TT>{FCGI_GET_VALUES_RESULT, 0, ...}</TT> with the values
+         supplied. If the application doesn&#39;t understand a variable name that was included in the query, it omits
+         that name from the response.
+      </P>
+      <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>
+      <P>
+      </P>
+      <UL TYPE="square">
+         <LI>
+            <TT>FCGI_MAX_CONNS</TT>: The maximum number of concurrent transport connections this application will
+            accept, e.g. <TT>&quot;1&quot;</TT> or <TT>&quot;10&quot;</TT>.
+            <P>
+            </P>
+         </LI>
+         <LI>
+            <TT>FCGI_MAX_REQS</TT>: The maximum number of concurrent requests this application will accept, e.g.
+            <TT>&quot;1&quot;</TT> or <TT>&quot;50&quot;</TT>.
+            <P>
+            </P>
+         </LI>
+         <LI>
+            <TT>FCGI_MPXS_CONNS</TT>: <TT>&quot;0&quot;</TT> if this application does not multiplex connections (i.e.
+            handle concurrent requests over each connection), <TT>&quot;1&quot;</TT> otherwise.<BR>
+            <BR>
+         </LI>
+      </UL>
+      <P>
+         An application may receive a <TT>FCGI_GET_VALUES</TT> record at any time. The application&#39;s response
+         should not involve the application proper but only the FastCGI library.
+      </P>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S4.2">4.2 <TT>FCGI_UNKNOWN_TYPE</TT></A>
+      </H4>
+      <P>
+         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>
+      <P>
+         The <TT>contentData</TT> component of a <TT>FCGI_UNKNOWN_TYPE</TT> record has the form:
+      </P>
+<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>
+      <P>
+      </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>
+      <P>
+         The Web server sends a <TT>FCGI_BEGIN_REQUEST</TT> record to start a request.
+      </P>
+      <P>
+         The <TT>contentData</TT> component of a <TT>FCGI_BEGIN_REQUEST</TT> record has the form:
+      </P>
+<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>
+      <P>
+      </P>
+      <UL TYPE="square">
+         <LI>
+            <TT>FCGI_RESPONDER</TT>
+         </LI>
+         <LI>
+            <TT>FCGI_AUTHORIZER</TT>
+         </LI>
+         <LI>
+            <TT>FCGI_FILTER</TT>
+         </LI>
+      </UL>
+      <P>
+         Roles are described in more detail in <A HREF="#S6">Section 6</A> below.
+      </P>
+      <P>
+         The <TT>flags</TT> component contains a bit that controls connection shutdown:
+      </P>
+      <P>
+      </P>
+      <UL TYPE="square">
+         <LI>
+            <TT>flags &amp; 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.<BR>
+            <BR>
+         </LI>
+      </UL>
+      <H4>
+         <A NAME="S5.2">5.2 Name-Value Pair Stream: <TT>FCGI_PARAMS</TT></A>
+      </H4>
+      <TT>FCGI_PARAMS</TT>
+      <P>
+         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>
+      <P>
+      </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>
+      <P>
+         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>
+      <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>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S5.4">5.4 <TT>FCGI_ABORT_REQUEST</TT></A>
+      </H4>
+      <P>
+         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>
+      <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>
+      <P>
+         When a Web server is not multiplexing requests over a transport connection, the Web server can abort a request
+         by closing the request&#39;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>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S5.5">5.5 <TT>FCGI_END_REQUEST</TT></A>
+      </H4>
+      <P>
+         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>
+      <P>
+         The <TT>contentData</TT> component of a <TT>FCGI_END_REQUEST</TT> record has the form:
+      </P>
+<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>
+      <P>
+         The <TT>protocolStatus</TT> component is a protocol-level status code; the possible <TT>protocolStatus</TT>
+         values are:
+      </P>
+      <P>
+      </P>
+      <UL TYPE="square">
+         <LI>
+            <TT>FCGI_REQUEST_COMPLETE</TT>: normal end of request.
+            <P>
+            </P>
+         </LI>
+         <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>
+            </P>
+         </LI>
+         <LI>
+            <TT>FCGI_OVERLOADED</TT>: rejecting a new request. This happens when the application runs out of some
+            resource, e.g. database connections.
+            <P>
+            </P>
+         </LI>
+         <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.<BR>
+            <BR>
+         </LI>
+      </UL>
+      <H3>
+         <A NAME="S6">6. Roles</A>
+      </H3>
+      <H4>
+         <A NAME="S6.1">6.1 Role Protocols</A>
+      </H4>
+      <P>
+         Role protocols only include records with application record types. They transfer essentially all data using
+         streams.
+      </P>
+      <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>
+      <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>
+      <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>
+      <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>
+      <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&#39;t allow
+         pipelining.
+      </P>
+      <P>
+         The request-response rule is too restrictive for some FastCGI roles; after all, CGI programs aren&#39;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>
+      <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>
+      <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>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S6.2">6.2 Responder</A>
+      </H4>
+      <P>
+         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>
+      <P>
+         It suffices to explain how each element of CGI/1.1 is emulated by a Responder:
+      </P>
+      <BR>
+      <BR>
+      <UL TYPE="square">
+         <LI>
+            The Responder application receives CGI/1.1 environment variables from the Web server over
+            <TT>FCGI_PARAMS</TT>.
+            <P>
+            </P>
+         </LI>
+         <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>
+            </P>
+         </LI>
+         <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&#39;t finish reading from
+            <TT>FCGI_STDIN</TT> before it begins writing these two streams.
+            <P>
+            </P>
+         </LI>
+         <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.<BR>
+            <BR>
+         </LI>
+      </UL>
+      <P>
+         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>
+      <P>
+      </P>
+      <H4>
+         <A NAME="S6.3">6.3 Authorizer</A>
+      </H4>
+      <P>
+         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>
+      <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>
+      <P>
+      </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>
+            </P>
+         </LI>
+         <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&#39;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
+            </P>
+<PRE>
+        Variable-AUTH_METHOD: database lookup
+</PRE>
+            transmits the value <TT>&quot;database lookup&quot;</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&#39;t prefixed with <TT>Variable-</TT> prefix, and ignores any
+            response content.
+            <P>
+               For Authorizer response status values other than &quot;200&quot; (OK), the Web server denies access and
+               sends the response status, headers, and content back to the HTTP client.
+            </P>
+            <BR>
+            <BR>
+         </LI>
+      </UL>
+      <H4>
+         <A NAME="S6.4">6.4 Filter</A>
+      </H4>
+      <P>
+         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 &quot;filtered&quot; version of the data
+         stream as an HTTP response.
+      </P>
+      <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&#39;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>
+      <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>
+      <BR>
+      <BR>
+      <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>
+            </P>
+         </LI>
+         <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>
+            </P>
+         </LI>
+         <LI>
+            Next the Filter application receives the file data from the Web server over <TT>FCGI_DATA</TT>. This
+            file&#39;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>
+            </P>
+         </LI>
+         <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&#39;t finish reading from <TT>FCGI_DATA</TT>
+            before it begins writing these two streams.
+            <P>
+            </P>
+         </LI>
+         <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.<BR>
+            <BR>
+         </LI>
+      </UL>
+      <P>
+         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&#39;t match and the Filter is a
+         query, the Filter response should provide an indication that data is missing. If the numbers don&#39;t match
+         and the Filter is an update, the Filter should abort the update.
+      </P>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S7">7. Errors</A>
+      </H3>
+      <P>
+         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>
+      <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>
+      <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>
+      <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>
+      <P>
+      </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  &quot;FCGI_MAX_CONNS&quot;
+#define FCGI_MAX_REQS   &quot;FCGI_MAX_REQS&quot;
+#define FCGI_MPXS_CONNS &quot;FCGI_MPXS_CONNS&quot;
+
+typedef struct {
+    unsigned char type;    
+    unsigned char reserved[7];
+} FCGI_UnknownTypeBody;
+
+typedef struct {
+    FCGI_Header header;
+    FCGI_UnknownTypeBody body;
+} FCGI_UnknownTypeRecord;
+</PRE>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S9">9. References</A>
+      </H3>
+      <P>
+         National Center for Supercomputer Applications, <A HREF="http://hoohoo.ncsa.uiuc.edu/cgi/">The Common Gateway
+         Interface</A>, version CGI/1.1.
+      </P>
+      <P>
+         D.R.T. Robinson, <A HREF="http://cgi-spec.golux.com/">The WWW
+         Common Gateway Interface Version 1.1</A>, Internet-Draft, 15 February 1996.
+      </P>
+      <P>
+      </P>
+      <H3>
+         <A NAME="SA">A. Table: Properties of the record types</A>
+      </H3>
+      <P>
+         The following chart lists all of the record types and indicates these properties of each:
+      </P>
+      <P>
+      </P>
+      <UL TYPE="square">
+         <LI>
+            <TT>WS-&gt;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>
+            </P>
+         </LI>
+         <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>
+            </P>
+         </LI>
+         <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.<BR>
+            <BR>
+         </LI>
+      </UL>
+<PRE>
+                               WS-&gt;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>
+      </P>
+      <H3>
+         <A NAME="SB">B. Typical Protocol Message Flow</A>
+      </H3>
+      <P>
+         Additional notational conventions for the examples:
+      </P>
+      <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>&quot; ... &quot;</TT> is too long to display, so only a prefix is shown.
+         </LI>
+         <LI>
+            Messages sent to the Web server are indented with respect to messages received from the Web server.
+         </LI>
+         <LI>
+            Messages are shown in the time sequence experienced by the application.
+         </LI>
+      </UL>
+      <P>
+         1. A simple request with no data on <TT>stdin</TT>, and a successful response:
+      </P>
+<PRE>
+{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, 0}}
+{FCGI_PARAMS,          1, &quot;\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... &quot;}
+{FCGI_PARAMS,          1, &quot;&quot;}
+{FCGI_STDIN,           1, &quot;&quot;}
+
+    {FCGI_STDOUT,      1, &quot;Content-type: text/html\r\n\r\n&lt;html&gt;\n&lt;head&gt; ... &quot;}
+    {FCGI_STDOUT,      1, &quot;&quot;}
+    {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:
+      </P>
+<PRE>
+{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, 0}}
+{FCGI_PARAMS,          1, &quot;\013\002SERVER_PORT80\013\016SER&quot;}
+{FCGI_PARAMS,          1, &quot;VER_ADDR199.170.183.42 ... &quot;}
+{FCGI_PARAMS,          1, &quot;&quot;}
+{FCGI_STDIN,           1, &quot;quantity=100&amp;item=3047936&quot;}
+{FCGI_STDIN,           1, &quot;&quot;}
+
+    {FCGI_STDOUT,      1, &quot;Content-type: text/html\r\n\r\n&lt;html&gt;\n&lt;head&gt; ... &quot;}
+    {FCGI_STDOUT,      1, &quot;&quot;}
+    {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:
+      </P>
+<PRE>
+{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, 0}}
+{FCGI_PARAMS,          1, &quot;\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... &quot;}
+{FCGI_PARAMS,          1, &quot;&quot;}
+{FCGI_STDIN,           1, &quot;&quot;}
+
+    {FCGI_STDOUT,      1, &quot;Content-type: text/html\r\n\r\n&lt;ht&quot;}
+    {FCGI_STDERR,      1, &quot;config error: missing SI_UID\n&quot;}
+    {FCGI_STDOUT,      1, &quot;ml&gt;\n&lt;head&gt; ... &quot;}
+    {FCGI_STDOUT,      1, &quot;&quot;}
+    {FCGI_STDERR,      1, &quot;&quot;}
+    {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:
+      </P>
+<PRE>
+{FCGI_BEGIN_REQUEST,   1, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
+{FCGI_PARAMS,          1, &quot;\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... &quot;}
+{FCGI_PARAMS,          1, &quot;&quot;}
+{FCGI_BEGIN_REQUEST,   2, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
+{FCGI_PARAMS,          2, &quot;\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... &quot;}
+{FCGI_STDIN,           1, &quot;&quot;}
+
+    {FCGI_STDOUT,      1, &quot;Content-type: text/html\r\n\r\n&quot;}
+
+{FCGI_PARAMS,          2, &quot;&quot;}
+{FCGI_STDIN,           2, &quot;&quot;}
+
+    {FCGI_STDOUT,      2, &quot;Content-type: text/html\r\n\r\n&lt;html&gt;\n&lt;head&gt; ... &quot;}
+    {FCGI_STDOUT,      2, &quot;&quot;}
+    {FCGI_END_REQUEST, 2, {0, FCGI_REQUEST_COMPLETE}}
+    {FCGI_STDOUT,      1, &quot;&lt;html&gt;\n&lt;head&gt; ... &quot;}
+    {FCGI_STDOUT,      1, &quot;&quot;}
+    {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
+</PRE>
+      <P>
+      </P>
+      <HR>
+      <ADDRESS>
+         &copy; 1995, 1996 Open Market, Inc. / mbrown@openmarket.com
+      </ADDRESS>
+   </BODY>
+</HTML>
+
index 7556ef6..16dd767 100644 (file)
-<!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
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         Integrating FastCGI with Tcl
+      </TITLE>
+<STYLE TYPE="text/css">
+ body {
+  background-color: #FFFFFF;
+  color: #000000;
+ }
+ :link { color: #cc0000 }
+ :visited { color: #555555 }
+ :active { color: #000011 }
+ h5.c3 {text-align: center}
+ p.c2 {text-align: center}
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <DIV CLASS="c1">
+         <A HREF="http://fastcgi.com"><IMG BORDER="0" SRC="../images/fcgi-hd.gif" ALT="[[FastCGI]]"></A>
+      </DIV>
+      <BR CLEAR="all">
+      <DIV CLASS="c1">
+         <H3>
+            Integrating FastCGI with Tcl
+         </H3>
+      </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.                   -->
+      <P CLASS="c2">
+         Michael S. Shanzer<BR>
+         Open Market, Inc.<BR>
+         <EM>19 January 1995</EM>
+      </P>
+      <H5 CLASS="c3">
+         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.4 2002/02/25 00:42:59 robs Exp $<BR>
+      </H5>
+      <HR>
+      <H3>
+         <A NAME="S1">1. Introduction</A>
+      </H3>
+      <P>
+         Tcl (tool command language) is an embeddable scripting language that&#39;s often used for CGI programming. Tcl
+         is freely available as a source kit.
+      </P>
+      <P>
+         We&#39;ve built a Tcl interpreter that runs as a FastCGI application. Our purpose in doing so was twofold:
+      </P>
+      <UL>
+         <LI>
+            <I>Create a useful artifact.</I> Open Market has written many CGI applications using Tcl. Now we&#39;d like
+            to turn them into FastCGI applications.
+            <P>
+            </P>
+         </LI>
+         <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.
+         </LI>
+      </UL>
+      <P>
+         We&#39;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>
+      <P>
+         The FastCGI-integrated Tcl interpreter works as usual when run from a shell or as a CGI program. You don&#39;t
+         need two Tcls, one for FastCGI and one for other uses.
+      </P>
+      <P>
+         The remainder of this document gives a recipe you can follow to build FastCGI into Tcl, explains what&#39;s
+         happening in the recipe, and illustrates the use of FastCGI Tcl with an example program.
+      </P>
+      <P>
+      </P>
+      <H3>
+         <A NAME="S2">2. Recipe</A>
+      </H3>
+      <P>
+         Here are the assumptions embedded in the following recipe:
+      </P>
+      <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&#39;s a sibling of the FastCGI kit directory <TT>fcgi-devel-kit</TT>.
+            <P>
+            </P>
+         </LI>
+         <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>
+            </P>
+         </LI>
+         <LI>
+            You have GNU autoconf installed on your system. If you don&#39;t have GNU autoconf, you will have to make
+            certain edits by hand and repeat these edits for each build platform.<BR>
+            <BR>
+         </LI>
+      </UL>
+      <P>
+         If those are valid assumptions, follow these steps:
+      </P>
+      <OL>
+         <LI>
+            <I>Build the FastCGI Developer&#39;s Kit.</I> Tcl needs to link against <TT>libfcgi.a</TT>, so <A HREF=
+            "fcgi-devel-kit.htm#S2">build the FastCGI Developer&#39;s Kit</A> in order to create this library for your
+            platform.
+            <P>
+            </P>
+         </LI>
+         <LI>
+            <I>Pull the Tcl 7.4p3 kit.</I> You&#39;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&#39;t perform these retrievals because of a protocol conflict between Netscape and Sun&#39;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>
+            <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>
+            <P>
+            </P>
+         </LI>
+         <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>
+    &gt; cd tcl7.4
+    &gt; mv tclAppInit.c tclAppInit.c.orig
+    &gt; mv Makefile.in.orig Makefile.in.orig.orig
+    &gt; mv Makefile.in Makefile.in.orig
+    &gt; mv configure.in configure.in.orig
+    &gt; cp ../fcgi-devel-kit/tcl/tcl7.4/* .
+    &gt; cp ../fcgi-devel-kit/tcl/common/* .
+</PRE>
+         </LI>
+         <LI>
+            <I>Create a new <TT>configure</TT> script.</I> 
+<PRE>
+    &gt; autoconf
+</PRE>
+         </LI>
+         <LI>
+            <I>Configure and build.</I> 
+<PRE>
+    &gt; ./configure
+    &gt; 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.<BR>
+            <BR>
+         </LI>
+      </OL>
+      <H3>
+         <A NAME="S3">3. Recipe Explained</A>
+      </H3>
+      <P>
+         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&#39;t hold for you, and to illuminate how little work was involved
+         in integrating FastCGI, here&#39;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.
+      </P>
+      <UL>
+         <LI>
+            <TT>tclAppInit.c</TT>:
+            <P>
+            </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>
+                  </P>
+               </LI>
+            </UL>
+         </LI>
+         <LI>
+            <TT>Makefile.in</TT>:
+            <P>
+            </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>
+                  <P>
+                  </P>
+               </LI>
+               <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>
+                  <P>
+                  </P>
+               </LI>
+               <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>
+                  <P>
+                  </P>
+               </LI>
+            </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>
+            <P>
+            </P>
+         </LI>
+         <LI>
+            <TT>configure.in</TT>:
+            <P>
+            </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>
+                  </P>
+               </LI>
+               <LI>
+                  Add the following lines just after the <TT>AC_SUBST(CC)</TT> line: 
+<PRE>
+AC_CHECK_LIB(socket, main, [LIBS=&quot;$LIBS -lsocket&quot;])
+AC_CHECK_LIB(nsl, main, [LIBS=&quot;$LIBS -lnsl&quot;])
+AC_SUBST(LIBS)
+</PRE>
+                  This ensures that the socket libraries used by FastCGI are linked into the Tcl interpreter.
+                  <P>
+                  </P>
+               </LI>
+            </UL>
+            If GNU autoconf is not available to you, you&#39;ll leave <TT>configure.in</TT> alone and perform the
+            following steps:
+            <P>
+            </P>
+            <UL>
+               <LI>
+                  Execute 
+<PRE>
+    &gt; SETENV CC gcc
+</PRE>
+                  before running <TT>configure</TT>.
+                  <P>
+                  </P>
+               </LI>
+               <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>
+                  </P>
+               </LI>
+            </UL>
+            If you ever re-run <TT>configure</TT>, you&#39;ll need to repeat these steps.
+            <P>
+            </P>
+         </LI>
+      </UL>
+      <H3>
+         <A NAME="S4">4. Writing FastCGI applications in Tcl</A>
+      </H3>
+      <P>
+         The Tcl program <TT>tcl/tiny-tcl-fcgi</TT> performs the same function as the C program
+         <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
+         Developer&#39;s Kit document</A>. Here&#39;s what the Tcl version looks like:
+      </P>
+      <P>
+      </P>
+<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>
+         If you&#39;ve built Tcl according to the recipe and you have a Web server set up to run FastCGI applications,
+         load the FastCGI Developer&#39;s Kit Index Page in that server and run this Tcl application now.
+      </P>
+      <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&#39;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>
+      <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>
+      <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>
+      <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>
+      <P>
+      </P>
+      <HR>
+      <ADDRESS>
+         <A HREF="mailto:shanzer@openmarket.com">Mike Shanzer // shanzer@openmarket.com</A>
+      </ADDRESS>
+   </BODY>
+</HTML>
+
index 3afa216..48bc42d 100644 (file)
-<!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
+<!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.4 2002/02/25 00:42:59 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>
+
index 5d4fef6..66945ae 100644 (file)
-<!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
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+   <HEAD>
+      <TITLE>
+         FastCGI: A High-Performance Gateway Interface
+      </TITLE>
+<STYLE TYPE="text/css">
+ h5.c2 {text-align: center}
+ div.c1 {text-align: center}
+</STYLE>
+   </HEAD>
+   <BODY>
+      <DIV CLASS="c1">
+         <H2>
+            FastCGI: A High-Performance Gateway Interface
+         </H2>
+         Position paper for the workshop &quot;Programming the Web - a search for APIs&quot;,<BR>
+         Fifth International World Wide Web Conference, 6 May 1996, Paris, France.<BR>
+         <P>
+            Mark R. Brown<BR>
+            Open Market, Inc.<BR>
+         </P>
+         <P>
+            2 May 1996<BR>
+         </P>
+      </DIV>
+      <P>
+      </P>
+      <H5 CLASS="c2">
+         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>
+      <P>
+         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&#39;s
+         &quot;responder&quot; role.
+      </P>
+      <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>.
+      </P>
+      <H3>
+         1. Introduction
+      </H3>
+      <P>
+         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>
+      <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:
+      </P>
+      <UL>
+         <LI>
+            <B>Complexity.</B> Server APIs introduce a steep learning curve, with increased implementation and
+            maintenance costs.
+         </LI>
+         <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&#39;t be used with any existing
+            server API.
+         </LI>
+         <LI>
+            <B>No process isolation.</B> Since the applications run in the server&#39;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>
+         <LI>
+            <B>Proprietary.</B> Coding your application to a particular API locks you into a particular server.
+         </LI>
+         <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&#39;t gain any performance advantage. Also, when
+            the server&#39;s architecture changes, the API will usually have to change, and applications will have to
+            be adapted or rewritten.
+         </LI>
+      </UL>
+      <P>
+         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>
+      <P>
+         FastCGI is best viewed as a new implementation of CGI, designed to overcome CGI&#39;s performance problems.
+         The major implementation differences are:
+      </P>
+      <UL>
+         <LI>
+            FastCGI processes are persistent: after finishing a request, they wait for a new request instead of
+            exiting.
+         </LI>
+         <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.
+         </LI>
+      </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.
+      </P>
+      <H3>
+         2. Migration from CGI
+      </H3>
+      <P>
+         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>
+      <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:
+      </P>
+      <UL>
+         <LI>
+            Developers don&#39;t have to learn a new API to develop FastCGI applications.
+         </LI>
+         <LI>
+            Existing CGI programs can be migrated with minimal source changes.
+         </LI>
+         <LI>
+            FastCGI interpreters for Perl, Tcl, and other interpreted languages can be built without modifying the
+            interpreter source code.
+         </LI>
+      </UL>
+      <P>
+         Here&#39;s a simple FastCGI application:
+      </P>
+      <BR>
+      <BR>
+<PRE>
+    #include &lt;fcgi_stdio.h&gt;
+
+    void main(void)
+    {
+        int count = 0;
+        while(FCGI_Accept() &gt;= 0) {
+            printf(&quot;Content-type: text/html\r\n&quot;);
+            printf(&quot;\r\n&quot;);
+            printf(&quot;Hello world!&lt;br&gt;\r\n&quot;);
+            printf(&quot;Request number %d.&quot;, count++);
+        }
+        exit(0);
+    }
+</PRE>
+      <P>
+         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.
+      </P>
+      <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>
+      <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.
+      </P>
+      <H3>
+         3. Single-threaded and multi-threaded applications
+      </H3>
+      <P>
+         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:
+      </P>
+      <UL>
+         <LI>
+            Applications can accept concurrent Web server connections to provide concurrent requests to multiple
+            application threads.
+         </LI>
+         <LI>
+            Applications can accept multiplexed Web server connections, in which concurrent requests are communicated
+            over a single connection to multiple application threads.
+         </LI>
+      </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>
+      <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&#39;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.
+      </P>
+      <H3>
+         4. Distributed FastCGI
+      </H3>
+      <P>
+         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&#39;t have Web servers.
+      </P>
+      <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.
+      </P>
+      <H3>
+         5. Roles
+      </H3>
+      <P>
+         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;:
+      </P>
+      <UL>
+         <LI>
+            <B>Responder.</B> This is the basic FastCGI role, and corresponds to the simple functionality offered by
+            CGI today.
+         </LI>
+         <LI>
+            <B>Filter.</B> The FastCGI application filters the requested Web server file before sending it to the
+            client.
+         </LI>
+         <LI>
+            <B>Authorizer.</B> The FastCGI program performs an access control decision for the request (such as
+            performing a username/password database lookup).
+         </LI>
+      </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&#39;s log entries for real-time processing and analysis.
+      </P>
+      <H3>
+         6. Conclusions
+      </H3>
+      <P>
+         Today&#39;s Web business applications need a platform that&#39;s fast, open, maintainable, straightforward,
+         stable, and secure. FastCGI&#39;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&#39;s
+         benefits without losing their existing investment in CGI applications.
+      </P>
+      <P>
+         For more information about FastCGI, visit the <A HREF="http://www.fastcgi.com/">www.fastcgi.com Web site</A>.
+      </P>
+   </BODY>
+</HTML>
+