-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- FastCGI Application Programmer'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'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>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- FastCGI Programmer'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 "Roles" 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'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 "Roles" 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>
+
-<!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 <fcgi_stdio.h>\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 <fcgi_stdio.h>\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("FCGI_ROLE") == "FILTER"</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("FCGI_DATA_LENGTH")</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("FCGI_DATA_LAST_MOD").</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() >= 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)) > 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 <fcgi_stdio.h>\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 <fcgi_stdio.h>
+</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 <fcgi_stdio.h>
+</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("FCGI_ROLE") == "FILTER"</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("FCGI_DATA_LENGTH")</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("FCGI_DATA_LAST_MOD").</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() >= 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)) > 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 <fcgi_stdio.h>
+</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>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- FastCGI Programmer'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'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'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 "Roles"\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 "roles" 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 "filtered" 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>"database lookup"</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'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, "Developing\r
- FastCGI Applications in Perl," 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, "Developing FastCGI Applications in Tcl," 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, "<H2>Aerobic Juggling</H2>/n");\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, "<H2>Aerobic Juggling</H2>/n");\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'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'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'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 "Roles"
+ </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 "roles" 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 "filtered" 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>"database lookup"</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'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, "Developing
+ FastCGI Applications in Perl," 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, "Developing FastCGI Applications in Tcl," 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, "<H2>Aerobic Juggling</H2>/n");
+</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, "<H2>Aerobic Juggling</H2>/n");
+</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>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- FastCGI Programmer'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() >= 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">"FCGI_Accept\r
- (3)" 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 "fcgi_stdio.h" /* fcgi library; put it first*/<BR>\r
-#include <stdlib.h>\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() >= 0) {\r
- printf("Content-type: text/html\r\n"\r
- "\r\n"\r
- "<title>FastCGI Hello! (C, fcgi_stdio library)</title>"\r
- "<h1>FastCGI Hello! (C, fcgi_stdio library)</h1>"\r
- "Request number %d running on host <i>%s</i>\n",\r
- ++count, getenv("SERVER_HOSTNAME"));\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 "fcgi_stdio.h"\r
-#include <stdlib.h>\r
-#include <string.h>\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 < VALS_IN_SIEVE_TABLE) {\r
- /* Mark off composite numbers. */\r
- for (c = current_prime; c <= 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() >= 0) {\r
- /*\r
- * Produce the necessary HTTP header.\r
- */\r
- printf("Content-type: text/html\r\n"\r
- "\r\n");\r
- /*\r
- * Produce the constant part of the HTML document.\r
- */\r
- printf("<title>Prime FastCGI</title>\n"\r
- "<h1>Prime FastCGI</h1>\n");\r
- /*\r
- * Read the query string and produce the variable part\r
- * of the HTML document.\r
- */\r
- query_string = getenv("QUERY_STRING");\r
- if(query_string == NULL) {\r
- printf("Usage: Specify a positive number in the query string.\n");\r
- } else {\r
- query_string = strchr(query_string, `=') + 1;\r
- n = strtol(query_string);\r
- if(n < 1) {\r
- printf("The query string `%s' is not a positive number.\n",\r
- query_string);\r
- } else if(n > MAX_NUMBER_OF_PRIME_NUMBERS) {\r
- printf("The number %d is too large for this program.\n", n);\r
- } else\r
- printf("The %ldth prime number is %ld.\n", 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'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() >= 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">"FCGI_Accept
+ (3)" 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 "fcgi_stdio.h" /* fcgi library; put it first*/<BR>
+#include <stdlib.h>
+
+int count;
+
+void initialize(void)
+{
+ count=0;
+}
+
+void main(void)
+{
+/* Initialization. */
+ initialize();
+
+/* Response loop. */
+ while (FCGI_Accept() >= 0) {
+ printf("Content-type: text/html\r\n"
+ "\r\n"
+ "<title>FastCGI Hello! (C, fcgi_stdio library)</title>"
+ "<h1>FastCGI Hello! (C, fcgi_stdio library)</h1>"
+ "Request number %d running on host <i>%s</i>\n",
+ ++count, getenv("SERVER_HOSTNAME"));
+ }
+}
+</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 "fcgi_stdio.h"
+#include <stdlib.h>
+#include <string.h>
+
+#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 < VALS_IN_SIEVE_TABLE) {
+ /* Mark off composite numbers. */
+ for (c = current_prime; c <= 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() >= 0) {
+ /*
+ * Produce the necessary HTTP header.
+ */
+ printf("Content-type: text/html\r\n"
+ "\r\n");
+ /*
+ * Produce the constant part of the HTML document.
+ */
+ printf("<title>Prime FastCGI</title>\n"
+ "<h1>Prime FastCGI</h1>\n");
+ /*
+ * Read the query string and produce the variable part
+ * of the HTML document.
+ */
+ query_string = getenv("QUERY_STRING");
+ if(query_string == NULL) {
+ printf("Usage: Specify a positive number in the query string.\n");
+ } else {
+ query_string = strchr(query_string, `=') + 1;
+ n = strtol(query_string);
+ if(n < 1) {
+ printf("The query string `%s' is not a positive number.\n",
+ query_string);
+ } else if(n > MAX_NUMBER_OF_PRIME_NUMBERS) {
+ printf("The number %d is too large for this program.\n", n);
+ } else
+ printf("The %ldth prime number is %ld.\n", 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>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- FastCGI Programmer'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'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's\r
- kit for how to make your own FastCGI-savvy Perl, if you need a version for some platform that we don'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 >= 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 >= 0) {\r
- print "Content-type: text/html\r\n\r\n";\r
- print "<head>\n<title>FastCGI Demo Page (perl)</title>\n</head>\n";\r
- print "<h1>FastCGI Demo Page (perl)</h1>\n";\r
- print "This is coming from a FastCGI server.\n<BR>\n";\r
- print "Running on <EM>$ENV{SERVER_NAME}</EM> to <EM>$ENV{REMOTE_HOST}</EM>\n<BR>\n";\r
- $cnt++;\r
- print "This is connection number $cnt\n";\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'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'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's
+ kit for how to make your own FastCGI-savvy Perl, if you need a version for some platform that we don'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 >= 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 >= 0) {
+ print "Content-type: text/html\r\n\r\n";
+ print "<head>\n<title>FastCGI Demo Page (perl)</title>\n</head>\n";
+ print "<h1>FastCGI Demo Page (perl)</h1>\n";
+ print "This is coming from a FastCGI server.\n<BR>\n";
+ print "Running on <EM>$ENV{SERVER_NAME}</EM> to <EM>$ENV{REMOTE_HOST}</EM>\n<BR>\n";
+ $cnt++;
+ print "This is connection number $cnt\n";
+}
+</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>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- FastCGI Programmer'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'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's\r
- kit for how to make your own FastCGI-savvy Tcl, if you need a version for some platform that we don'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] >= 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] >= 0 } {\r
- incr count\r
- puts -nonewline "Content-type: text/html\r\n\r\n"\r
- puts "<title>FastCGI Hello! (Tcl)</title>"\r
- puts "<h1>FastCGI Hello! (Tcl)</h1>"\r
- puts "Request number $count running on host <i>$env(SERVER_NAME)</i>"\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'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'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's
+ kit for how to make your own FastCGI-savvy Tcl, if you need a version for some platform that we don'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] >= 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] >= 0 } {
+ incr count
+ puts -nonewline "Content-type: text/html\r\n\r\n"
+ puts "<title>FastCGI Hello! (Tcl)</title>"
+ puts "<h1>FastCGI Hello! (Tcl)</h1>"
+ puts "Request number $count running on host <i>$env(SERVER_NAME)</i>"
+}
+</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>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- FastCGI Programmer'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'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 "AS IS" 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 © 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'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'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 "AS IS" 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 © 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>
+
-<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'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 "responder" role, where the\r
- application generates the response that is returned to the client. CGI programs can'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's log file, and link in to other stages in the\r
- server's request processing.\r
- </P>\r
- <P>\r
- However, APIs sacrifice all of CGI'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'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'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'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't gain any performance advantage. Also, when\r
- the vendor changes the server'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'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'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'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'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'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'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 "bridge" 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'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 "behind the scenes" 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'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
- "roles":\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 "logger" role would be useful, where the\r
- FastCGI program would receive the server'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'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'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'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'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 "200 OK" 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 "Access Denied" or "Redirect".\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 "fall\r
- through" 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'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's a simple FastCGI application:\r
- </P>\r
- <BR>\r
- <BR>\r
-<PRE>\r
- #include <fcgi_stdio.h>\r
-\r
- void main(void)\r
- {\r
- int count = 0;\r
- while(FCGI_Accept() >= 0) {\r
- printf("Content-type: text/html\r\n");\r
- printf("\r\n");\r
- printf("Hello world!<br>\r\n");\r
- printf("Request number %d.", count++);\r
- }\r
- exit(0);\r
- }\r
-</PRE>\r
- <P>\r
- This application returns a "Hello world" 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() >= 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'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'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'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'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'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 "session" is configurable. The default configuration\r
- uses the WebServer'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'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'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's Web business applications need a platform that's fast, open, maintainable, straightforward,\r
- stable, and secure. FastCGI'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's benefits\r
- without losing their existing investment in CGI applications.<!--Need to talk about NT.-->\r
- \r
- <!--Need to give "more punch" 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'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'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 "responder" role, where the
+ application generates the response that is returned to the client. CGI programs can'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's log file, and link in to other stages in the
+ server's request processing.
+ </P>
+ <P>
+ However, APIs sacrifice all of CGI'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't be used with any existing
+ vendor API.
+ </LI>
+ <LI>
+ <B>No process isolation.</B> <SPAN>Since the applications run in the server's address space, buggy
+ applications can corrupt the core server (or each other). A malicious or buggy application can compromise
+ server security, and bugs in the core server can corrupt applications.</SPAN>
+ </LI>
+ <LI>
+ <B>Proprietary.</B> Coding your application to a particular API locks you into a particular vendor'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't gain any performance advantage. Also, when
+ the vendor changes the server'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'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'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'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'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'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'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 "bridge" 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'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 "behind the scenes" 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'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
+ "roles":
+ </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 "logger" role would be useful, where the
+ FastCGI program would receive the server'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'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'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'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'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 "200 OK" 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 "Access Denied" or "Redirect".
+ </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 "fall
+ through" to the underlying operating system standard I/O routines.
+ </P>
+ <P>
+ This approach has several benefits:
+ </P>
+ <UL>
+ <LI>
+ Developers don'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's a simple FastCGI application:
+ </P>
+ <BR>
+ <BR>
+<PRE>
+ #include <fcgi_stdio.h>
+
+ void main(void)
+ {
+ int count = 0;
+ while(FCGI_Accept() >= 0) {
+ printf("Content-type: text/html\r\n");
+ printf("\r\n");
+ printf("Hello world!<br>\r\n");
+ printf("Request number %d.", count++);
+ }
+ exit(0);
+ }
+</PRE>
+ <P>
+ This application returns a "Hello world" 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() >= 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'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'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'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'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'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 "session" is configurable. The default configuration
+ uses the WebServer'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'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'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's Web business applications need a platform that's fast, open, maintainable, straightforward,
+ stable, and secure. FastCGI'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's benefits
+ without losing their existing investment in CGI applications.<!--Need to talk about NT.-->
+
+ <!--Need to give "more punch" 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'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>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- FastCGI Developer'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'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 © 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'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'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'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's index page, <TT>fcgi-devel-kit/index.html</TT>, using the "Open File" 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't work\r
- when index.html is opened using the "Open File" command because they aren't aren't being\r
- accessed through a Web server.\r
- </P>\r
- <P>\r
- In order to use the kit in earnest you'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's not possible, arrange a configuration\r
- such that the kit is accessible from the machine that's going to run your Web server, and build the kit\r
- and your applications on a machine that's configured exactly the same way (same processor architecture,\r
- operating system, etc.) as the machine that'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'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'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 <stdio.h>\r
- #include <stdlib.h>\r
-\r
- void main(void)\r
- {\r
- int count = 0;\r
- printf("Content-type: text/html\r\n"\r
- "\r\n"\r
- "<title>CGI Hello!</title>"\r
- "<h1>CGI Hello!</h1>"\r
- "Request number %d running on host <i>%s</i>\n",\r
- ++count, getenv("SERVER_NAME"));\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 "fcgi_stdio.h"\r
- #include <stdlib.h>\r
-\r
- void main(void)\r
- {\r
- int count = 0;\r
- while(FCGI_Accept() >= 0)\r
- printf("Content-type: text/html\r\n"\r
- "\r\n"\r
- "<title>FastCGI Hello!</title>"\r
- "<h1>FastCGI Hello!</h1>"\r
- "Request number %d running on host <i>%s</i>\n",\r
- ++count, getenv("SERVER_NAME"));\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'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'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'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't replace these.) For instance, <TT>FILE</TT> becomes <TT>FCGI_FILE</TT> and <TT>printf</TT> becomes\r
- <TT>FCGI_printf</TT>. You'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'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'll need to include the headers for these libraries <I>before</I> you include\r
- <TT>fcgi_stdio.h</TT>. You can'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, "r");\r
- answer = MungeStream(FCGI_ToFile(myStream));\r
- \r
-</PRE>\r
- <P>\r
- Here <TT>MungeStream</TT> is a library function that you can'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't worry about storage leaks because the programs\r
- don'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, "r");\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() >= 0) {\r
- print("Content-type: text/html\r\n\r\n",\r
- "<title>FastCGI Hello! (Perl)</title>\n",\r
- "<h1>FastCGI Hello! (Perl)</h1>\n";\r
- "Request number ", ++$count,\r
- " running on host <i>";$env(SERVER_NAME)</i>");\r
-}\r
-</PRE>\r
-<PRE>\r
-#!./tclsh\r
-set count 0 \r
-while {[FCGI_Accept] >= 0 } {\r
- incr count\r
- puts -nonewline "Content-type: text/html\r\n\r\n"\r
- puts "<title>FastCGI Hello! (Tcl)</title>"\r
- puts "<h1>FastCGI Hello! (Tcl)</h1>"\r
- puts "Request number $count running on host <i>$env(SERVER_NAME)</i>"\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'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()>= 0) {\r
- count ++;\r
- System.out.println("Content-type: text/html\r\n\r\n");\r
- System.out.println(\r
- "<title>FastCGI Hello! (Java)</title>");\r
- System.out.println("<h1>FastCGI Hello! (Java)</h1>");\r
- System.out.println(\r
- "request number " + count + " running on host <i>" +\r
- System.getProperty("SERVER_NAME") + "</i>");\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'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>'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'd then open the URL\r
- <TT>http://bowser:8888/index.html</TT> to reach the kit'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'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'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
- © 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'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'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 © 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'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't need to read the specification in order to write applications.
+ </P>
+ <P>
+ Additional information is provided in the <A HREF="http://fastcgi.com/docs/faq.html">FAQ</A> document, which
+ contains frequently asked questions about application development using FastCGI, as well as some general
+ information.
+ </P>
+ <P>
+ Experience with CGI programming will be extremely valuable in writing FastCGI applications. If you don't
+ have enough experience with CGI programming, you should read one of the popular books on the topic or study
+ the <A HREF="http://hoohoo.ncsa.uiuc.edu/cgi/">NCSA CGI page</A>. For a more formal treatment of CGI/1.1 see
+ the <A HREF="http://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's index page, <TT>fcgi-devel-kit/index.html</TT>, using the "Open File" command in
+ your Web browser. The index page gives you an overview of the kit structure and helps you navigate the kit.
+ The index page also contains links that run some example applications, but the applications won't work
+ when index.html is opened using the "Open File" command because they aren't aren't being
+ accessed through a Web server.
+ </P>
+ <P>
+ In order to use the kit in earnest you'll need a Web server that you control, a Web server running with
+ your user ID. The Web server will be starting FastCGI applications that you will need to debug; this will be a
+ lot more convenient for you if these processes run with your user ID. It is best to have a Web server that
+ supports FastCGI. <A HREF="#S4">Section 4</A> discusses Web server issues.
+ </P>
+ <P>
+ If you can, keep the kit on a file system accessible from your personal workstation, do your builds on your
+ workstation, and run your Web server on your workstation. If that's not possible, arrange a configuration
+ such that the kit is accessible from the machine that's going to run your Web server, and build the kit
+ and your applications on a machine that's configured exactly the same way (same processor architecture,
+ operating system, etc.) as the machine that's going to run your Web server.
+ </P>
+ <P>
+ To build the kit you execute this sequence of commands in the <TT>fcgi-devel-kit</TT> directory:
+ </P>
+<PRE>
+ % ./configure
+ % make
+</PRE>
+ <P>
+ We've built and exercised the kit on these platforms (listed in alphabetical order):
+ </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'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 <stdio.h>
+ #include <stdlib.h>
+
+ void main(void)
+ {
+ int count = 0;
+ printf("Content-type: text/html\r\n"
+ "\r\n"
+ "<title>CGI Hello!</title>"
+ "<h1>CGI Hello!</h1>"
+ "Request number %d running on host <i>%s</i>\n",
+ ++count, getenv("SERVER_NAME"));
+ }
+</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 "fcgi_stdio.h"
+ #include <stdlib.h>
+
+ void main(void)
+ {
+ int count = 0;
+ while(FCGI_Accept() >= 0)
+ printf("Content-type: text/html\r\n"
+ "\r\n"
+ "<title>FastCGI Hello!</title>"
+ "<h1>FastCGI Hello!</h1>"
+ "Request number %d running on host <i>%s</i>\n",
+ ++count, getenv("SERVER_NAME"));
+ }
+</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'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's include search path.
+ The kit calls this directory <TT>include</TT>.
+ </LI>
+ <LI>
+ Add the library <TT>libfcgi.a</TT> to the linker's command line so that it will be searched when
+ linking. The <TT>libfcgi.a</TT> library implements the functions defined in <TT>fcgi_stdio.h</TT>. The kit
+ calls the directory containing this library <TT>libfcgi</TT>.
+ </LI>
+ <LI>
+ Determine whether or not the linker on your platform searches the Berkeley socket library by default, and
+ if not, add linker directives to force this search.
+ </LI>
+ </UL>
+ <P>
+ See <TT>examples/Makefile</TT> (created by <TT>configure</TT>) for a Makefile that builds both programs.
+ Autoconf handles the platform-dependent linking issues; to see how, examine <TT>configure.in</TT> and
+ <TT>examples/Makefile.in</TT>.
+ </P>
+ <H4>
+ Running the program
+ </H4>
+ <P>
+ <A HREF="#S4">Section 4</A> is all about how to run FastCGI applications.
+ </P>
+ <P>
+ You can use CGI to run application binaries built with the <TT>fcgi_stdio</TT> library. The
+ <TT>FCGI_Accept</TT> function tests its environment to determine how the application was invoked. If it was
+ invoked as a CGI program, the first call to FCGI_Accept is essentially a no-op and the second call returns
+ <TT>-1</TT>. In effect, the request loop disappears.
+ </P>
+ <P>
+ Of course, when a FastCGI application is run using CGI it does not get the benefits of FastCGI. For instance,
+ the application exits after servicing a single request, so it cannot maintain cached information.
+ </P>
+ <H4>
+ Implementation details
+ </H4>
+ <P>
+ <TT>fcgi_stdio.h</TT> works by first including <TT>stdio.h</TT>, then defining macros to replace essentially
+ all of the types and procedures defined in <TT>stdio.h</TT>. (<TT>stdio.h</TT> defines a few procedures that
+ have nothing to do with <TT>FILE *</TT>, such as <TT>sprintf</TT> and <TT>sscanf</TT>; <TT>fcgi_stdio.h</TT>
+ doesn't replace these.) For instance, <TT>FILE</TT> becomes <TT>FCGI_FILE</TT> and <TT>printf</TT> becomes
+ <TT>FCGI_printf</TT>. You'll only see these new names if you read <TT>fcgi_stdio.h</TT> or examine your C
+ source code after preprocessing.
+ </P>
+ <P>
+ Here are some consequences of this implementation technique:
+ </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'll want to recompile these libraries with <TT>fcgi_stdio.h</TT> included. Most C
+ compilers provide a command-line option for including headers in a program being compiled; using such a
+ compiler feature allows you to rebuild your libraries without making source changes. For instance the gcc
+ command line
+<PRE>
+ gcc -include /usr/local/include/fcgi_stdio.h wonderlib.c
+
+</PRE>
+ <P>
+ causes gcc to include <TT>fcgi_stdio.h</TT> before it even begins to read the module
+ <TT>wonderlib.c</TT>.
+ </P>
+ </LI>
+ <LI>
+ If your application passes <TT>FILE *</TT> to functions implemented in libraries for which you do not have
+ source code, then you'll need to include the headers for these libraries <I>before</I> you include
+ <TT>fcgi_stdio.h</TT>. You can't pass the <TT>stdin</TT>, <TT>stdout</TT>, or <TT>stderr</TT> streams
+ produced by <TT>FCGI_Accept</TT> to any functions implemented by these libraries. You can pass a stream on
+ a Unix file to a library function by following this pattern:
+<PRE>
+ FILE *myStream = fopen(path, "r");
+ answer = MungeStream(FCGI_ToFile(myStream));
+
+</PRE>
+ <P>
+ Here <TT>MungeStream</TT> is a library function that you can't recompile and <TT>FCGI_ToFile</TT> is
+ a macro that converts from <TT>FCGI_FILE *</TT> to <TT>FILE *</TT>. The macro <TT>FCGI_ToFile</TT> is
+ defined in <TT>fcgi_stdio.h</TT>.
+ </P>
+ </LI>
+ </UL>
+ <H4>
+ Converting CGI programs
+ </H4>
+ <P>
+ The main task in converting a CGI program into a FastCGI program is separating the code that needs to execute
+ once, initializing the program, from the code that needs to run for each request. In our tiny example,
+ initializing the <TT>count</TT> variable is outside the loop, while incrementing the <TT>count</TT> variable
+ goes inside.
+ </P>
+ <P>
+ Retained application state may be an issue. You must ensure that any application state created in processing
+ one request has no unintended effects on later requests. FastCGI offers the possibility of significant
+ application performance improvements, through caching; it is up to you to make the caches work correctly.
+ </P>
+ <P>
+ Storage leaks may be an issue. Many CGI programs don't worry about storage leaks because the programs
+ don't run for long enough for bloating to be a problem. When converting to FastCGI, you can either use a
+ tool such as <A HREF="http://www.pure.com/"><I>Purify</I></A> from Pure Software to discover and fix storage
+ leaks, or you can run a C garbage collector such as <A HREF="http://www.geodesic.com/"><I>Great Circle</I></A>
+ from Geodesic Systems.
+ </P>
+ <H4>
+ Limitations
+ </H4>
+ <P>
+ Currently there are some limits to the compatibility provided by the <TT>fcgi_stdio</TT> library:
+ </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, "r");
+ 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() >= 0) {
+ print("Content-type: text/html\r\n\r\n",
+ "<title>FastCGI Hello! (Perl)</title>\n",
+ "<h1>FastCGI Hello! (Perl)</h1>\n";
+ "Request number ", ++$count,
+ " running on host <i>";$env(SERVER_NAME)</i>");
+}
+</PRE>
+<PRE>
+#!./tclsh
+set count 0
+while {[FCGI_Accept] >= 0 } {
+ incr count
+ puts -nonewline "Content-type: text/html\r\n\r\n"
+ puts "<title>FastCGI Hello! (Tcl)</title>"
+ puts "<h1>FastCGI Hello! (Tcl)</h1>"
+ puts "Request number $count running on host <i>$env(SERVER_NAME)</i>"
+}
+</PRE>
+ <P>
+ Converting a Perl or Tcl CGI application to FastCGI is not fundamentally different from converting a C CGI
+ application to FastCGI. You separate the portion of the application that performs one-time initialization from
+ the portion that performs per-request processing. You put the per-request processing into a loop controlled by
+ <TT>FCGI::accept</TT> (Perl) or <TT>FCGI_Accept</TT> (Tcl).
+ </P>
+ <H4>
+ <A NAME="S3.4">3.4 Using Java</A>
+ </H4>
+ <P>
+ Java is not just for browser-based applets. It is already suitable for writing some Web server applications,
+ and its range of applicability will only grow as Java compilers and other Java tools improve. Java's
+ modules, garbage collection, and threads are especially valuable for writing long-lived application servers.
+ </P>
+ <P>
+ The <TT>FCGIInterface</TT> class provides facilities for Java applications analogous to what
+ <TT>fcgi_stdio</TT> provides for C applications. Using this library your Java application can run using either
+ CGI or FastCGI.
+ </P>
+ <P>
+ The kit includes separate companion document on <A HREF="fcgi-java.htm">using FastCGI with Java</A>. The
+ source code for FastCGI classes is contained in directory <TT>java/src</TT> and the compiled code in
+ <TT>java/classes</TT>.
+ </P>
+ <P>
+ Here is the Java version of <TT>tiny-fcgi</TT>:
+ </P>
+<PRE>
+import FCGIInterface;
+
+class TinyFCGI {
+ public static void main (String args[]) {
+ int count = 0;
+ while(new FCGIInterface().FCGIaccept()>= 0) {
+ count ++;
+ System.out.println("Content-type: text/html\r\n\r\n");
+ System.out.println(
+ "<title>FastCGI Hello! (Java)</title>");
+ System.out.println("<h1>FastCGI Hello! (Java)</h1>");
+ System.out.println(
+ "request number " + count + " running on host <i>" +
+ System.getProperty("SERVER_NAME") + "</i>");
+ }
+ }
+}
+</PRE>
+ <H3>
+ <A NAME="S4">4. Running applications</A>
+ </H3>
+ <H3>
+ <A NAME="S4.1">4.1 Using a Web server that supports FastCGI</A>
+ </H3>
+ <P>
+ For a current listing of Web servers that support FastCGI, see the <A HREF=
+ "http://fastcgi.com">fastcgi.com</A> Web page.
+ </P>
+ <P>
+ Some of the Web servers that support FastCGI perform management of FastCGI applications. You don't need to
+ start and stop FastCGI applications; the Web server takes care of this. If an application process should
+ crash, the Web server restarts it.
+ </P>
+ <P>
+ Web servers support FastCGI via new configuration directives. Since these directives are server-specific, get
+ more information from the documentation that accompanies each server.
+ </P>
+ <H3>
+ <A NAME="S4.2">4.2 Using <TT>cgi-fcgi</TT> with any Web server</A>
+ </H3>
+ <P>
+ The program <TT>cgi-fcgi</TT> allows you to run FastCGI applications using any Web server that supports CGI.
+ </P>
+ <P>
+ Here is how <TT>cgi-fcgi</TT> works. <TT>cgi-fcgi</TT> is a standard CGI program that uses Unix domain or
+ TCP/IP sockets to communicate with a FastCGI application. <TT>cgi-fcgi</TT> takes the path name or host/port
+ name of a listening socket as a parameter and <TT>connect</TT>s to the FastCGI application listening on that
+ socket. <TT>cgi-fcgi</TT> then forwards the CGI environment variables and <TT>stdin</TT> data to the FastCGI
+ application, and forwards the <TT>stdout</TT> and <TT>stderr</TT> data from the FastCGI application to the Web
+ server. When the FastCGI application signals the end of its response, <TT>cgi-fcgi</TT> flushes its buffers
+ and exits.
+ </P>
+ <P>
+ Obviously, having <TT>cgi-fcgi</TT> is not as good as having a server with integrated FastCGI support:
+ </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>'s connection attempt fails, it creates a new process running
+ the program <TT>examples/tiny-fcgi</TT> and listening on socket <TT>examples/sockets/tiny-fcgi</TT>. Then
+ <TT>cgi-fcgi</TT> retries the connection attempt, which now should succeed.
+ </P>
+ <P>
+ The <TT>cgi-fcgi</TT> program has two other modes of operation. In one mode it connects to applications but
+ does not start them; in the other it starts applications but does not connect to them. These modes are
+ required when using TCP/IP. The <A HREF="cgi-fcgi.1"><TT>cgi-fcgi</TT> manpage</A>, <TT>doc/cgi-fcgi.1</TT>,
+ tells the full story.
+ </P>
+ <P>
+ To run the example applications using <TT>cgi-fcgi</TT>, start your Web server and give it the directory
+ <TT>fcgi-devel-kit</TT> as the root of its URL space. If the machine running your server is called
+ <TT>bowser</TT> and your server is running on port <TT>8888</TT>, you'd then open the URL
+ <TT>http://bowser:8888/index.html</TT> to reach the kit's index page. Now the links on the index page that
+ run example applications via <TT>cgi-fcgi</TT> should be active.
+ </P>
+ <H3>
+ <A NAME="S5">5. Known problems</A>
+ </H3>
+ <P>
+ On Digital UNIX 3.0 there's a problem with Unix domain listening sockets on NFS file systems. The symptom
+ when using cgi-fcgi is an exit status of 38 (<TT>ENOTSOCK</TT>: socket operation on non-socket), but cgi-fcgi
+ may dump core in this case when compiled optimized. Work-around: Store your Unix domain listening sockets on a
+ non NFS file system, upgrade to Digital UNIX 3.2, or use TCP sockets.
+ </P>
+ <P>
+ On AIX there's a problem with shared listening sockets. The symptoms can include application core dumps
+ and kernel panic. Work-around: Run a single FastCGI application server per listening socket.
+ </P>
+ <H3>
+ <A NAME="S6">6. Getting support</A>
+ </H3>
+ <P>
+ The mailing list <TT>fastcgi-developers</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>
+ © 1996, Open Market, Inc. / mbrown@openmarket.com
+ </ADDRESS>
+ </BODY>
+</HTML>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- 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 © 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'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><APPLET></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'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'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("Content-type: text/html\n\n");\r
- System.out.println("<html>");\r
- System.out.println(\r
- "<head><TITLE>CGI Hello</TITLE></head>");\r
- System.out.println("<body>");\r
- System.out.println("<H3>CGI-Hello</H3>");\r
- System.out.println("request number " + count + \r
- " running on host " \r
- + System.getProperty<"SERVER_NAME"));\r
- System.out.println("</body>");\r
- System.out.println("</html>"); \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()>= 0) {\r
- count ++;\r
- System.out.println("Content-type: text/html\n\n");\r
- System.out.println("<html>");\r
- System.out.println(\r
- "<head><TITLE>FastCGI-Hello Java stdio</TITLE></head>");\r
- System.out.println("<body>");\r
- System.out.println("<H3>FastCGI-HelloJava stdio</H3>");\r
- System.out.println("request number " + count + \r
- " running on host " \r
- + System.getProperty<"SERVER_NAME"));\r
- System.out.println("</body>");\r
- System.out.println("</html>"); \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'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's <TT>java/bin</TT> directory to your Unix <TT>PATH</TT> if it isn'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'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's support for listening sockets, Java FastCGI applications are\r
- currently limited to being started as external applications. They can'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't be needed, since its use is due to an acknowledged rigidity in the\r
- JDK'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'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()>= 0) {\r
- System.out.println("Content-type: text/html\n\n");\r
- System.out.println("<html>");\r
- System.out.println(\r
- "<head%gt;<TITLE>FastCGI echo\r
- </TITLE></head>");\r
- System.out.println("<body>"); \r
- System.out.println(\r
- "<H2>FastCGI echo</H2>");\r
- System.out.println("<H3>STDIN</H3>");\r
- for ( int c = 0; c != -1; ) {\r
- try {\r
- c = System.in.read();\r
- } catch(IOException e) {\r
- System.out.println(\r
- "<br><b>SYSTEM EXCEPTION");\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
- "<H3>Environment Variables:</H3>");\r
- \r
- System.getProperties().list(System.out);\r
- System.out.println("</body>");\r
- System.out.println("</html>");\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()>= 0) {\r
- System.out.println("Content-type: text/html\n\n");\r
- System.out.println("<html>");\r
- System.out.println(\r
- "<head><TITLE>FastCGI echo\r
- </TITLE></head>");\r
- System.out.println("<body>"); \r
- System.out.println("<H2>FastCGI echo</H2>");\r
- System.out.println("<H3>STDIN:</H3">);\r
- for ( int c = 0; c != -1; ) {\r
- try {\r
- c = intf.request.inStream.read();\r
- } catch(IOException e) {\r
- System.out.println(\r
- "<br><b>SYSTEM EXCEPTION");\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
- "<H3>Environment Variables:</H3>");\r
- \r
- System.getProperties().list(System.out);\r
- System.out.println(<"/body>");\r
- System.out.println("</html>");\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 © 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'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><APPLET></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'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'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("Content-type: text/html\n\n");
+ System.out.println("<html>");
+ System.out.println(
+ "<head><TITLE>CGI Hello</TITLE></head>");
+ System.out.println("<body>");
+ System.out.println("<H3>CGI-Hello</H3>");
+ System.out.println("request number " + count +
+ " running on host "
+ + System.getProperty<"SERVER_NAME"));
+ System.out.println("</body>");
+ System.out.println("</html>");
+ }
+ }
+
+</PRE>
+ <H4>
+ B. TinyFCGI
+ </H4>
+<PRE>
+
+import FCGIInterface;
+
+class TinyFCGI {
+ public static void main (String args[]) {
+ int count = 0;
+ while(new FCGIInterface().FCGIaccept()>= 0) {
+ count ++;
+ System.out.println("Content-type: text/html\n\n");
+ System.out.println("<html>");
+ System.out.println(
+ "<head><TITLE>FastCGI-Hello Java stdio</TITLE></head>");
+ System.out.println("<body>");
+ System.out.println("<H3>FastCGI-HelloJava stdio</H3>");
+ System.out.println("request number " + count +
+ " running on host "
+ + System.getProperty<"SERVER_NAME"));
+ System.out.println("</body>");
+ System.out.println("</html>");
+ }
+ }
+ }
+
+</PRE>
+ <H4>
+ C. Running these Examples
+ </H4>
+ <P>
+ We assume that you have downloaded the JDK and the FastCGI Developer's Kit, and that you have a Web server
+ running that can access the <TT>fcgi-devel-kit/examples</TT> directory. In all cases where we specify paths,
+ we are using relative paths within <TT>fcgi-devel-kit</TT> or the JDK which will need to be enlarged to a full
+ path by the user.
+ </P>
+ <H5>
+ Configuring
+ </H5>
+ <OL>
+ <LI>
+ Add your JDK's <TT>java/bin</TT> directory to your Unix <TT>PATH</TT> if it isn't there
+ already.<BR>
+ <BR>
+ </LI>
+ <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'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's support for listening sockets, Java FastCGI applications are
+ currently limited to being started as external applications. They can't be started and managed by the Web
+ server because they are incapable of using a listening socket that the Web server creates.
+ </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't be needed, since its use is due to an acknowledged rigidity in the
+ JDK'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'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()>= 0) {
+ System.out.println("Content-type: text/html\n\n");
+ System.out.println("<html>");
+ System.out.println(
+ "<head%gt;<TITLE>FastCGI echo
+ </TITLE></head>");
+ System.out.println("<body>");
+ System.out.println(
+ "<H2>FastCGI echo</H2>");
+ System.out.println("<H3>STDIN</H3>");
+ for ( int c = 0; c != -1; ) {
+ try {
+ c = System.in.read();
+ } catch(IOException e) {
+ System.out.println(
+ "<br><b>SYSTEM EXCEPTION");
+ Runtime rt = Runtime.getRuntime();
+ rt.exit(status);
+ }
+ if (c != -1) {
+ System.out.print((char)c);
+ }
+ }
+ System.out.println(
+ "<H3>Environment Variables:</H3>");
+
+ System.getProperties().list(System.out);
+ System.out.println("</body>");
+ System.out.println("</html>");
+ }
+ }
+ }
+</PRE>
+ <H4>
+ B. Echo2FCGI
+ </H4>
+<PRE>
+import FCGIInterface;
+import FCGIGlobalDefs;
+import FCGIInputStream;
+import FCGIOutputStream;
+import FCGIMessage;
+import FCGIRequest;
+import java.io.*;
+
+class Echo2FCGI {
+
+ public static void main (String args[]) {
+ int status = 0;
+ FCGIInterface intf = new FCGIInterface();
+ while(intf.FCGIaccept()>= 0) {
+ System.out.println("Content-type: text/html\n\n");
+ System.out.println("<html>");
+ System.out.println(
+ "<head><TITLE>FastCGI echo
+ </TITLE></head>");
+ System.out.println("<body>");
+ System.out.println("<H2>FastCGI echo</H2>");
+ System.out.println("<H3>STDIN:</H3">);
+ for ( int c = 0; c != -1; ) {
+ try {
+ c = intf.request.inStream.read();
+ } catch(IOException e) {
+ System.out.println(
+ "<br><b>SYSTEM EXCEPTION");
+ Runtime rt = Runtime.getRuntime();
+ rt.exit(status);
+ }
+ if (c != -1) {
+ System.out.print((char)c);
+ }
+ }
+ System.out.println(
+ "<H3>Environment Variables:</H3>");
+
+ System.getProperties().list(System.out);
+ System.out.println(<"/body>");
+ System.out.println("</html>");
+ }
+ }
+ }
+</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>
+
-<!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 © 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 "executes web\r
- applications up to five times faster than all other servers," but the ad gives little clue where the\r
- number "five" 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
- "unfair" 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'd need to measure to figure that\r
- out for the situation you face, rather than just saying "we're three times faster" 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'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 "performance" 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's response, response time at both the\r
- client and the server will go up, and there'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't run fast when all the information it needs is available\r
- in its memory. And if the application doesn'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's functional specification so it doesn'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'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'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'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'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'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'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'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 "logs in" 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'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'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'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'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's requests\r
- after the first hit in the application'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'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'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't have all of the disadvantages described in Section 3. Does this mean that\r
- FastCGI'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
- © 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 © 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 "executes web
+ applications up to five times faster than all other servers," but the ad gives little clue where the
+ number "five" came from.
+ </P>
+ <P>
+ This paper is meant to convey an understanding of the primary factors that influence the performance of Web
+ server applications and to show that architectural differences between FastCGI and server APIs often give an
+ "unfair" performance advantage to FastCGI applications. We run a test that shows a FastCGI
+ application running three times faster than the corresponding Web server API application. Under different
+ conditions this factor might be larger or smaller. We show you what you'd need to measure to figure that
+ out for the situation you face, rather than just saying "we're three times faster" and moving
+ on.
+ </P>
+ <P>
+ This paper makes no attempt to prove that FastCGI is better than Web server APIs for every application. Web
+ server APIs enable lightweight protocol extensions, such as Open Market's SecureLink extension, to be
+ added to Web servers, as well as allowing other forms of server customization. But APIs are not well matched
+ to mainstream applications such as personalized content or access to corporate databases, because of API
+ drawbacks including high complexity, low security, and limited scalability. FastCGI shines when used for the
+ vast majority of Web applications.
+ </P>
+ <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 "performance" 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's response, response time at both the
+ client and the server will go up, and there's nothing the server can do about it. For the purposes of
+ making repeatable measurements the client should have a high-bandwidth communications link to the server.
+ </P>
+ <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't run fast when all the information it needs is available
+ in its memory. And if the application doesn't run fast under those conditions, the possible solutions are
+ evident: Tune the processor-hungry parts of the application, install a faster processor, or change the
+ application's functional specification so it doesn't need to do so much work.
+ </P>
+ <P>
+ The way to make information available in memory is by caching. A cache is an in-memory data structure that
+ contains information that's been read from its permanent home on disk. When the application needs
+ information, it consults the cache, and uses the information if it is there. Otherwise is reads the
+ information from disk and places a copy in the cache. If the cache is full, the application discards some old
+ information before adding the new. When the application needs to change cached information, it changes both
+ the cache entry and the information on disk. That way, if the application crashes, no information is lost; the
+ application just runs more slowly for awhile after restarting, because the cache doesn't improve
+ performance when it is empty.
+ </P>
+ <P>
+ Caching can reduce both disk I/O and processor time, because reading information from disk uses more processor
+ time than reading it from the cache. Because caching addresses both of the potential bottlenecks, it is the
+ focal point of high-performance Web server application design. CGI applications couldn't perform in-memory
+ caching, because they exited after processing just one request. Web server APIs promised to solve this
+ problem. But how effective is the solution?
+ </P>
+ <P>
+ Today's most widely deployed Web server APIs are based on a pool-of-processes server model. The Web server
+ consists of a parent process and a pool of child processes. Processes do not share memory. An incoming request
+ is assigned to an idle child at random. The child runs the request to completion before accepting a new
+ request. A typical server has 32 child processes, a large server has 100 or 200.
+ </P>
+ <P>
+ In-memory caching works very poorly in this server model because processes do not share memory and incoming
+ requests are assigned to processes at random. For instance, to keep a frequently-used file available in memory
+ the server must keep a file copy per child, which wastes memory. When the file is modified all the children
+ need to be notified, which is complex (the APIs don't provide a way to do it).
+ </P>
+ <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'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'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 "logs in" to a database, creating a connection, then performs one or more accesses.
+ Frequently, the cost of creating the database connection is several times the cost of accessing data over an
+ established connection.
+ </P>
+ <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'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'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'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'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's requests
+ after the first hit in the application'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'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'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't have all of the disadvantages described in Section 3. Does this mean that
+ FastCGI'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>
+ © 1995, Open Market, Inc. / mbrown@openmarket.com
+ </ADDRESS>
+ </BODY>
+</HTML>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- 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 © 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 © 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>
+
-<!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 © 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'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'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't begin life connected to anything. It doesn't have the conventional open\r
- files <TT>stdin</TT>, <TT>stdout</TT>, and <TT>stderr</TT>, and it doesn'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'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 "filtered" 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 "FastCGI application," "application\r
- process," or "application server" are abbreviated to "application" whenever that\r
- won'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'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'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'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'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
- "<TT>B1</TT>" and "<TT>B0</TT>," it means that the two components may be viewed as a\r
- single number, computed as <TT>B1<<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'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'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'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'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 >> 7 == 0 */\r
- unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */\r
- unsigned char nameData[nameLength];\r
- unsigned char valueData[valueLength];\r
- } FCGI_NameValuePair11;\r
-\r
- typedef struct {\r
- unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */\r
- unsigned char valueLengthB3; /* valueLengthB3 >> 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 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];\r
- } FCGI_NameValuePair14;\r
-\r
- typedef struct {\r
- unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */\r
- unsigned char nameLengthB2;\r
- unsigned char nameLengthB1;\r
- unsigned char nameLengthB0;\r
- unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */\r
- unsigned char nameData[nameLength\r
- ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];\r
- unsigned char valueData[valueLength];\r
- } FCGI_NameValuePair41;\r
-\r
- typedef struct {\r
- unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */\r
- unsigned char nameLengthB2;\r
- unsigned char nameLengthB1;\r
- unsigned char nameLengthB0;\r
- unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */\r
- unsigned char valueLengthB2;\r
- unsigned char valueLengthB1;\r
- unsigned char valueLengthB0;\r
- unsigned char nameData[nameLength\r
- ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];\r
- unsigned char valueData[valueLength\r
- ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];\r
- } FCGI_NameValuePair44;\r
-</PRE>\r
- <P>\r
- The high-order bit of the first byte of a length indicates the length'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'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>"1"</TT> or <TT>"10"</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>"1"</TT> or <TT>"50"</TT>.\r
- <P>\r
- </P>\r
- </LI>\r
- <LI>\r
- <TT>FCGI_MPXS_CONNS</TT>: <TT>"0"</TT> if this application does not multiplex connections (i.e.\r
- handle concurrent requests over each connection), <TT>"1"</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'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 & 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'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'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'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'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'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>"database lookup"</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't prefixed with <TT>Variable-</TT> prefix, and ignores any\r
- response content.\r
- <P>\r
- For Authorizer response status values other than "200" (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 "filtered" 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'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'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'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't match and the Filter is a\r
- query, the Filter response should provide an indication that data is missing. If the numbers don'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 "FCGI_MAX_CONNS"\r
-#define FCGI_MAX_REQS "FCGI_MAX_REQS"\r
-#define FCGI_MPXS_CONNS "FCGI_MPXS_CONNS"\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->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->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>" ... "</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, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}\r
-{FCGI_PARAMS, 1, ""}\r
-{FCGI_STDIN, 1, ""}\r
-\r
- {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n<html>\n<head> ... "}\r
- {FCGI_STDOUT, 1, ""}\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, "\013\002SERVER_PORT80\013\016SER"}\r
-{FCGI_PARAMS, 1, "VER_ADDR199.170.183.42 ... "}\r
-{FCGI_PARAMS, 1, ""}\r
-{FCGI_STDIN, 1, "quantity=100&item=3047936"}\r
-{FCGI_STDIN, 1, ""}\r
-\r
- {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n<html>\n<head> ... "}\r
- {FCGI_STDOUT, 1, ""}\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, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}\r
-{FCGI_PARAMS, 1, ""}\r
-{FCGI_STDIN, 1, ""}\r
-\r
- {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n<ht"}\r
- {FCGI_STDERR, 1, "config error: missing SI_UID\n"}\r
- {FCGI_STDOUT, 1, "ml>\n<head> ... "}\r
- {FCGI_STDOUT, 1, ""}\r
- {FCGI_STDERR, 1, ""}\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, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}\r
-{FCGI_PARAMS, 1, ""}\r
-{FCGI_BEGIN_REQUEST, 2, {FCGI_RESPONDER, FCGI_KEEP_CONN}}\r
-{FCGI_PARAMS, 2, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}\r
-{FCGI_STDIN, 1, ""}\r
-\r
- {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n"}\r
-\r
-{FCGI_PARAMS, 2, ""}\r
-{FCGI_STDIN, 2, ""}\r
-\r
- {FCGI_STDOUT, 2, "Content-type: text/html\r\n\r\n<html>\n<head> ... "}\r
- {FCGI_STDOUT, 2, ""}\r
- {FCGI_END_REQUEST, 2, {0, FCGI_REQUEST_COMPLETE}}\r
- {FCGI_STDOUT, 1, "<html>\n<head> ... "}\r
- {FCGI_STDOUT, 1, ""}\r
- {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}\r
-</PRE>\r
- <P>\r
- </P>\r
- <HR>\r
- <ADDRESS>\r
- © 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 © 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'll introduce FastCGI by comparing it with conventional Unix implementations of CGI/1.1. FastCGI is
+ designed to support long-lived application processes, i.e. <I>application servers</I>. That's a major
+ difference compared with conventional Unix implementations of CGI/1.1, which construct an application process,
+ use it respond to one request, and have it exit.
+ </P>
+ <P>
+ The initial state of a FastCGI process is more spartan than the initial state of a CGI/1.1 process, because
+ the FastCGI process doesn't begin life connected to anything. It doesn't have the conventional open
+ files <TT>stdin</TT>, <TT>stdout</TT>, and <TT>stderr</TT>, and it doesn't receive much information
+ through environment variables. The key piece of initial state in a FastCGI process is a listening socket,
+ through which it accepts connections from a Web server.
+ </P>
+ <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's the role CGI/1.1 programs play. A second role is <I>Authorizer</I>,
+ in which the application receives all the information associated with an HTTP request and generates an
+ authorized/unauthorized decision. A third role is <I>Filter</I>, in which the application receives all the
+ information associated with an HTTP request, plus an extra stream of data from a file stored on the Web
+ server, and generates a "filtered" version of the data stream as an HTTP response. The framework is
+ extensible so that more FastCGI can be defined later.
+ </P>
+ <P>
+ In the remainder of this specification the terms "FastCGI application," "application
+ process," or "application server" are abbreviated to "application" whenever that
+ won't cause confusion.
+ </P>
+ <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'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'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'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'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
+ "<TT>B1</TT>" and "<TT>B0</TT>," it means that the two components may be viewed as a
+ single number, computed as <TT>B1<<8 + B0</TT>. The name of this single number is the name of the
+ components, minus the suffixes. This convention generalizes in an obvious way to handle numbers represented in
+ more than two bytes.
+ </P>
+ <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'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'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'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'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 >> 7 == 0 */
+ unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */
+ unsigned char nameData[nameLength];
+ unsigned char valueData[valueLength];
+ } FCGI_NameValuePair11;
+
+ typedef struct {
+ unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */
+ unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */
+ unsigned char valueLengthB2;
+ unsigned char valueLengthB1;
+ unsigned char valueLengthB0;
+ unsigned char nameData[nameLength];
+ unsigned char valueData[valueLength
+ ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
+ } FCGI_NameValuePair14;
+
+ typedef struct {
+ unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */
+ unsigned char nameLengthB2;
+ unsigned char nameLengthB1;
+ unsigned char nameLengthB0;
+ unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */
+ unsigned char nameData[nameLength
+ ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
+ unsigned char valueData[valueLength];
+ } FCGI_NameValuePair41;
+
+ typedef struct {
+ unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */
+ unsigned char nameLengthB2;
+ unsigned char nameLengthB1;
+ unsigned char nameLengthB0;
+ unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */
+ unsigned char valueLengthB2;
+ unsigned char valueLengthB1;
+ unsigned char valueLengthB0;
+ unsigned char nameData[nameLength
+ ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
+ unsigned char valueData[valueLength
+ ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
+ } FCGI_NameValuePair44;
+</PRE>
+ <P>
+ The high-order bit of the first byte of a length indicates the length's encoding. A high-order zero
+ implies a one-byte encoding, a one a four-byte encoding.
+ </P>
+ <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'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>"1"</TT> or <TT>"10"</TT>.
+ <P>
+ </P>
+ </LI>
+ <LI>
+ <TT>FCGI_MAX_REQS</TT>: The maximum number of concurrent requests this application will accept, e.g.
+ <TT>"1"</TT> or <TT>"50"</TT>.
+ <P>
+ </P>
+ </LI>
+ <LI>
+ <TT>FCGI_MPXS_CONNS</TT>: <TT>"0"</TT> if this application does not multiplex connections (i.e.
+ handle concurrent requests over each connection), <TT>"1"</TT> otherwise.<BR>
+ <BR>
+ </LI>
+ </UL>
+ <P>
+ An application may receive a <TT>FCGI_GET_VALUES</TT> record at any time. The application's response
+ should not involve the application proper but only the FastCGI library.
+ </P>
+ <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 & 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'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't allow
+ pipelining.
+ </P>
+ <P>
+ The request-response rule is too restrictive for some FastCGI roles; after all, CGI programs aren't
+ restricted to read all of <TT>stdin</TT> before starting to write <TT>stdout</TT>. So some role protocols
+ allow that specific possibility. First the application receives all of its inputs except for a final stream
+ input. As the application begins to receive the final stream input, it can begin writing its output.
+ </P>
+ <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'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'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>"database lookup"</TT> with name <TT>AUTH-METHOD</TT>. The server
+ associates such name-value pairs with the HTTP request and includes them in subsequent CGI or FastCGI
+ requests performed in processing the HTTP request. When the application gives a 200 response, the server
+ ignores response headers whose names aren't prefixed with <TT>Variable-</TT> prefix, and ignores any
+ response content.
+ <P>
+ For Authorizer response status values other than "200" (OK), the Web server denies access and
+ sends the response status, headers, and content back to the HTTP client.
+ </P>
+ <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 "filtered" 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'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'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'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't match and the Filter is a
+ query, the Filter response should provide an indication that data is missing. If the numbers don't match
+ and the Filter is an update, the Filter should abort the update.
+ </P>
+ <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 "FCGI_MAX_CONNS"
+#define FCGI_MAX_REQS "FCGI_MAX_REQS"
+#define FCGI_MPXS_CONNS "FCGI_MPXS_CONNS"
+
+typedef struct {
+ unsigned char type;
+ unsigned char reserved[7];
+} FCGI_UnknownTypeBody;
+
+typedef struct {
+ FCGI_Header header;
+ FCGI_UnknownTypeBody body;
+} FCGI_UnknownTypeRecord;
+</PRE>
+ <P>
+ </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->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->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>" ... "</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, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
+{FCGI_PARAMS, 1, ""}
+{FCGI_STDIN, 1, ""}
+
+ {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n<html>\n<head> ... "}
+ {FCGI_STDOUT, 1, ""}
+ {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
+</PRE>
+ <P>
+ 2. Similar to example 1, but this time with data on <TT>stdin</TT>. The Web server chooses to send the
+ parameters using more <TT>FCGI_PARAMS</TT> records than before:
+ </P>
+<PRE>
+{FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, 0}}
+{FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SER"}
+{FCGI_PARAMS, 1, "VER_ADDR199.170.183.42 ... "}
+{FCGI_PARAMS, 1, ""}
+{FCGI_STDIN, 1, "quantity=100&item=3047936"}
+{FCGI_STDIN, 1, ""}
+
+ {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n<html>\n<head> ... "}
+ {FCGI_STDOUT, 1, ""}
+ {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
+</PRE>
+ <P>
+ 3. Similar to example 1, but this time the application detects an error. The application logs a message to
+ <TT>stderr</TT>, returns a page to the client, and returns non-zero exit status to the Web server. The
+ application chooses to send the page using more <TT>FCGI_STDOUT</TT> records:
+ </P>
+<PRE>
+{FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, 0}}
+{FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
+{FCGI_PARAMS, 1, ""}
+{FCGI_STDIN, 1, ""}
+
+ {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n<ht"}
+ {FCGI_STDERR, 1, "config error: missing SI_UID\n"}
+ {FCGI_STDOUT, 1, "ml>\n<head> ... "}
+ {FCGI_STDOUT, 1, ""}
+ {FCGI_STDERR, 1, ""}
+ {FCGI_END_REQUEST, 1, {938, FCGI_REQUEST_COMPLETE}}
+</PRE>
+ <P>
+ 4. Two instances of example 1, multiplexed onto a single connection. The first request is more difficult than
+ the second, so the application finishes the requests out of order:
+ </P>
+<PRE>
+{FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
+{FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
+{FCGI_PARAMS, 1, ""}
+{FCGI_BEGIN_REQUEST, 2, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
+{FCGI_PARAMS, 2, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
+{FCGI_STDIN, 1, ""}
+
+ {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n"}
+
+{FCGI_PARAMS, 2, ""}
+{FCGI_STDIN, 2, ""}
+
+ {FCGI_STDOUT, 2, "Content-type: text/html\r\n\r\n<html>\n<head> ... "}
+ {FCGI_STDOUT, 2, ""}
+ {FCGI_END_REQUEST, 2, {0, FCGI_REQUEST_COMPLETE}}
+ {FCGI_STDOUT, 1, "<html>\n<head> ... "}
+ {FCGI_STDOUT, 1, ""}
+ {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
+</PRE>
+ <P>
+ </P>
+ <HR>
+ <ADDRESS>
+ © 1995, 1996 Open Market, Inc. / mbrown@openmarket.com
+ </ADDRESS>
+ </BODY>
+</HTML>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- 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 © 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's often used for CGI programming. Tcl\r
- is freely available as a source kit.\r
- </P>\r
- <P>\r
- We'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'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'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'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'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'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'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'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'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'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't perform these retrievals because of a protocol conflict between Netscape and Sun'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
- > cd tcl7.4\r
- > mv tclAppInit.c tclAppInit.c.orig\r
- > mv Makefile.in.orig Makefile.in.orig.orig\r
- > mv Makefile.in Makefile.in.orig\r
- > mv configure.in configure.in.orig\r
- > cp ../fcgi-devel-kit/tcl/tcl7.4/* .\r
- > 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
- > autoconf\r
-</PRE>\r
- </LI>\r
- <LI>\r
- <I>Configure and build.</I> \r
-<PRE>\r
- > ./configure\r
- > 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't hold for you, and to illuminate how little work was involved\r
- in integrating FastCGI, here'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="$LIBS -lsocket"])\r
-AC_CHECK_LIB(nsl, main, [LIBS="$LIBS -lnsl"])\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'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
- > 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'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's used as an example in the <A HREF="fcgi-devel-kit.htm#S3.1.1">FastCGI\r
- Developer's Kit document</A>. Here'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] >= 0 } {\r
- incr count\r
- puts -nonewline "Content-type: text/html\r\n\r\n"\r
- puts "<title>FastCGI Hello! (Tcl)</title>"\r
- puts "<h1>FastCGI Hello! (Tcl)</h1>"\r
- puts "Request number $count running on host <i>$env(SERVER_NAME)</i>"\r
-}\r
-</PRE>\r
- <P>\r
- If you've built Tcl according to the recipe and you have a Web server set up to run FastCGI applications,\r
- load the FastCGI Developer'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'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 © 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's often used for CGI programming. Tcl
+ is freely available as a source kit.
+ </P>
+ <P>
+ We'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'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'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'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'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'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'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's Kit.</I> Tcl needs to link against <TT>libfcgi.a</TT>, so <A HREF=
+ "fcgi-devel-kit.htm#S2">build the FastCGI Developer's Kit</A> in order to create this library for your
+ platform.
+ <P>
+ </P>
+ </LI>
+ <LI>
+ <I>Pull the Tcl 7.4p3 kit.</I> You'll need the files <A HREF=
+ "ftp://ftp.smli.com/pub/tcl/tcl7.4.tar.Z">tcl7.4.tar.Z</A>, <A HREF=
+ "ftp://ftp.smli.com/pub/tcl/tcl7.4p1.patch.gz">tcl7.4p1.patch.gz</A>, <A HREF=
+ "ftp://ftp.smli.com/pub/tcl/tcl7.4p2.patch.gz">tcl7.4p2.patch.gz</A>, and <A HREF=
+ "ftp://ftp.smli.com/pub/tcl/tcl7.4p3.patch.gz">tcl7.4p3.patch.gz</A>. (Some older Netscape browsers
+ can't perform these retrievals because of a protocol conflict between Netscape and Sun's firewall.)
+ <P>
+ Unpack the tar file in the parent directory of the FastCGI kit directory you used in the previous step,
+ so that the directories <TT>tcl7.4</TT> and <TT>fcgi-devel-kit</TT> are siblings. After unpacking the
+ tar file, follow the directions in the <TT>README</TT> to apply the patches.
+ </P>
+ <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>
+ > cd tcl7.4
+ > mv tclAppInit.c tclAppInit.c.orig
+ > mv Makefile.in.orig Makefile.in.orig.orig
+ > mv Makefile.in Makefile.in.orig
+ > mv configure.in configure.in.orig
+ > cp ../fcgi-devel-kit/tcl/tcl7.4/* .
+ > cp ../fcgi-devel-kit/tcl/common/* .
+</PRE>
+ </LI>
+ <LI>
+ <I>Create a new <TT>configure</TT> script.</I>
+<PRE>
+ > autoconf
+</PRE>
+ </LI>
+ <LI>
+ <I>Configure and build.</I>
+<PRE>
+ > ./configure
+ > make
+</PRE>
+ The <TT>make</TT> creates the Tcl interpreter <TT>tclsh</TT> and library archive <TT>libtcl.a</TT> (for
+ embedding Tcl in your own C applications). The Tcl <TT>README</TT> file explains how you can experiment
+ with <TT>tclsh</TT> without installing it in a standard place.<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't hold for you, and to illuminate how little work was involved
+ in integrating FastCGI, here's an explanation of how and why you would modify the files
+ <TT>tclAppInit.c</TT>, <TT>Makefile.in</TT>, and <TT>configure.in</TT> from the Tcl kit.
+ </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="$LIBS -lsocket"])
+AC_CHECK_LIB(nsl, main, [LIBS="$LIBS -lnsl"])
+AC_SUBST(LIBS)
+</PRE>
+ This ensures that the socket libraries used by FastCGI are linked into the Tcl interpreter.
+ <P>
+ </P>
+ </LI>
+ </UL>
+ If GNU autoconf is not available to you, you'll leave <TT>configure.in</TT> alone and perform the
+ following steps:
+ <P>
+ </P>
+ <UL>
+ <LI>
+ Execute
+<PRE>
+ > 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'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's used as an example in the <A HREF="fcgi-devel-kit.htm#S3.1.1">FastCGI
+ Developer's Kit document</A>. Here's what the Tcl version looks like:
+ </P>
+ <P>
+ </P>
+<PRE>
+#!./tclsh
+set count 0
+while {[FCGI_Accept] >= 0 } {
+ incr count
+ puts -nonewline "Content-type: text/html\r\n\r\n"
+ puts "<title>FastCGI Hello! (Tcl)</title>"
+ puts "<h1>FastCGI Hello! (Tcl)</h1>"
+ puts "Request number $count running on host <i>$env(SERVER_NAME)</i>"
+}
+</PRE>
+ <P>
+ If you've built Tcl according to the recipe and you have a Web server set up to run FastCGI applications,
+ load the FastCGI Developer's Kit Index Page in that server and run this Tcl application now.
+ </P>
+ <P>
+ The script invokes Tcl indirectly via the symbolic link <TT>examples/tclsh</TT>. It does this because HP-UX
+ has a limit of 32 characters for the first line of a command-interpreter file such as
+ <TT>examples/tiny-tcl-fcgi</TT>. If you run on HP-UX you won't want to sprinkle symbolic links to
+ <TT>tclsh</TT> everywhere, so you should install <TT>tclsh</TT> with a shorter pathname than
+ <TT>/usr/local/tcl7.4-fcgi/bin/tclsh7.4</TT>.
+ </P>
+ <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>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- FastCGI Developer'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'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'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's Guide</A>\r
- Programmer-oriented documentation for developers of applications that run on the Open Market's\r
- Secure WebServer 2.0. The content overlaps considerably with Section 3 of the Developer'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 "Programming the Web -- a search for APIs", 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
- © 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's Kit Index Page
+ </TITLE>
+<STYLE TYPE="text/css">
+ div.c1 {text-align: center}
+</STYLE>
+ </HEAD>
+ <BODY>
+ <DIV CLASS="c1">
+ <H2>
+ FastCGI Developer'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'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's Guide</A>
+ Programmer-oriented documentation for developers of applications that run on the Open Market's
+ Secure WebServer 2.0. The content overlaps considerably with Section 3 of the Developer'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 "Programming the Web -- a search for APIs", 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>
+ © 1996, Open Market, Inc.
+ </ADDRESS>
+ </BODY>
+</HTML>
+
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<HTML>\r
- <HEAD>\r
- <TITLE>\r
- FastCGI: A High-Performance Gateway Interface\r
- </TITLE>\r
-<STYLE TYPE="text/css">\r
- h5.c2 {text-align: center}\r
- div.c1 {text-align: center}\r
-</STYLE>\r
- </HEAD>\r
- <BODY>\r
- <DIV CLASS="c1">\r
- <H2>\r
- FastCGI: A High-Performance Gateway Interface\r
- </H2>\r
- Position paper for the workshop "Programming the Web - a search for APIs",<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 © 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's\r
- "responder" 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'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'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't gain any performance advantage. Also, when\r
- the server'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'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 "fall\r
- through" to the underlying operating system standard I/O routines. This approach has several benefits:\r
- </P>\r
- <UL>\r
- <LI>\r
- Developers don'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's a simple FastCGI application:\r
- </P>\r
- <BR>\r
- <BR>\r
-<PRE>\r
- #include <fcgi_stdio.h>\r
-\r
- void main(void)\r
- {\r
- int count = 0;\r
- while(FCGI_Accept() >= 0) {\r
- printf("Content-type: text/html\r\n");\r
- printf("\r\n");\r
- printf("Hello world!<br>\r\n");\r
- printf("Request number %d.", count++);\r
- }\r
- exit(0);\r
- }\r
-</PRE>\r
- <P>\r
- This application returns a "Hello world" 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'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'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 "roles":\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 "logger" role would be useful, where the\r
- FastCGI program would receive the server's log entries for real-time processing and analysis.\r
- </P>\r
- <H3>\r
- 6. Conclusions\r
- </H3>\r
- <P>\r
- Today's Web business applications need a platform that's fast, open, maintainable, straightforward,\r
- stable, and secure. FastCGI'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'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 "Programming the Web - a search for APIs",<BR>
+ Fifth International World Wide Web Conference, 6 May 1996, Paris, France.<BR>
+ <P>
+ Mark R. Brown<BR>
+ Open Market, Inc.<BR>
+ </P>
+ <P>
+ 2 May 1996<BR>
+ </P>
+ </DIV>
+ <P>
+ </P>
+ <H5 CLASS="c2">
+ Copyright © 1996 Open Market, Inc. 245 First Street, Cambridge, MA 02142 U.S.A.<BR>
+ Tel: 617-621-9500 Fax: 617-621-1703 URL: <A HREF=
+ "http://www.openmarket.com/">http://www.openmarket.com/</A><BR>
+ </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's
+ "responder" 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't be used with any existing
+ server API.
+ </LI>
+ <LI>
+ <B>No process isolation.</B> Since the applications run in the server's address space, buggy
+ applications can corrupt the core server (or each other). A malicious or buggy application can compromise
+ server security, and bugs in the core server can corrupt applications.
+ </LI>
+ <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't gain any performance advantage. Also, when
+ the server's architecture changes, the API will usually have to change, and applications will have to
+ be adapted or rewritten.
+ </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'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 "fall
+ through" to the underlying operating system standard I/O routines. This approach has several benefits:
+ </P>
+ <UL>
+ <LI>
+ Developers don'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's a simple FastCGI application:
+ </P>
+ <BR>
+ <BR>
+<PRE>
+ #include <fcgi_stdio.h>
+
+ void main(void)
+ {
+ int count = 0;
+ while(FCGI_Accept() >= 0) {
+ printf("Content-type: text/html\r\n");
+ printf("\r\n");
+ printf("Hello world!<br>\r\n");
+ printf("Request number %d.", count++);
+ }
+ exit(0);
+ }
+</PRE>
+ <P>
+ This application returns a "Hello world" 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'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'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 "roles":
+ </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 "logger" role would be useful, where the
+ FastCGI program would receive the server's log entries for real-time processing and analysis.
+ </P>
+ <H3>
+ 6. Conclusions
+ </H3>
+ <P>
+ Today's Web business applications need a platform that's fast, open, maintainable, straightforward,
+ stable, and secure. FastCGI's design meets these requirements, and provides a logical migration path from
+ the proven and widely deployed CGI technology. This allows developers to take advantage of FastCGI's
+ benefits without losing their existing investment in CGI applications.
+ </P>
+ <P>
+ For more information about FastCGI, visit the <A HREF="http://www.fastcgi.com/">www.fastcgi.com Web site</A>.
+ </P>
+ </BODY>
+</HTML>
+