-<html>
-<!--Copyright (c) 1996 Open Market, Inc. -->
-<!--See the file "LICENSE.TERMS" for information on usage and redistribution-->
-<!--of this file, and for a DISCLAIMER OF ALL WARRANTIES. -->
-<head>
-<title>FastCGI Specification</title>
-</head>
-
-<body>
-<center>
-<h2>FastCGI Specification</h2>
-</center>
-
-<center>
-Mark R. Brown<br>
-Open Market, Inc.<br>
-<p>
-
-Document Version: 1.0<br>
-29 April 1996<br>
-</center>
-<p>
-
-<h5 align=center>
-Copyright © 1996 Open Market, Inc. 245 First Street, Cambridge,
- MA 02142 U.S.A.<br>
-Tel: 617-621-9500 Fax: 617-621-1703 URL:
- <a href="http://www.openmarket.com/">http://www.openmarket.com/</a><br>
-<br>
-$Id: fcgi-spec.html,v 1.2 2001/05/14 13:00:30 robs Exp $
-</h5>
-<hr>
-
-
-<ul type=square>
- <li><a HREF = "#S1">1. Introduction</a>
- <li><a HREF = "#S2">2. Initial Process State</a>
- <ul type=square>
- <li><a HREF = "#S2.1">2.1 Argument list</a>
- <li><a HREF = "#S2.2">2.2 File descriptors</a>
- <li><a HREF = "#S2.3">2.3 Environment variables</a>
- <li><a HREF = "#S2.4">2.4 Other state</a>
- </ul>
- <li><a HREF = "#S3">3. Protocol Basics</a>
- <ul type=square>
- <li><a HREF = "#S3.1">3.1 Notation</a>
- <li><a HREF = "#S3.2">3.2 Accepting Transport Connections</a>
- <li><a HREF = "#S3.3">3.3 Records</a>
- <li><a HREF = "#S3.4">3.4 Name-Value Pairs</a>
- <li><a HREF = "#S3.5">3.5 Closing Transport Connections</a>
- </ul>
- <li><a HREF = "#S4">4. Management Record Types</a>
- <ul type=square>
- <li><a HREF = "#S4.1">4.1 <tt>FCGI_GET_VALUES, FCGI_GET_VALUES_RESULT</tt></a>
- <li><a HREF = "#S4.2">4.2 <tt>FCGI_UNKNOWN_TYPE</tt></a>
- </ul>
- <li><a HREF = "#S5">5. Application Record Types</a>
- <ul type=square>
- <li><a HREF = "#S5.1">5.1 <tt>FCGI_BEGIN_REQUEST</tt></a>
- <li><a HREF = "#S5.2">5.2 Name-Value Pair Streams: <tt>FCGI_PARAMS</tt>, <tt>FCGI_RESULTS</tt></a>
- <li><a HREF = "#S5.3">5.3 Byte Streams: <tt>FCGI_STDIN</tt>, <tt>FCGI_DATA</tt>, <tt>FCGI_STDOUT</tt>, <tt>FCGI_STDERR</tt></a>
- <li><a HREF = "#S5.4">5.4 <tt>FCGI_ABORT_REQUEST</tt></a>
- <li><a HREF = "#S5.5">5.5 <tt>FCGI_END_REQUEST</tt></a>
- </ul>
- <li><a HREF = "#S6">6. Roles</a>
- <ul type=square>
- <li><a HREF = "#S6.1">6.1 Role Protocols</a>
- <li><a HREF = "#S6.2">6.2 Responder</a>
- <li><a HREF = "#S6.3">6.3 Authorizer</a>
- <li><a HREF = "#S6.4">6.4 Filter</a>
- </ul>
- <li><a HREF = "#S7">7. Errors</a>
- <li><a HREF = "#S8">8. Types and Constants</a>
- <li><a HREF = "#S9">9. References</a>
- <li><a HREF = "#SA">A. Table: Properties of the record types</a>
- <li><a HREF = "#SB">B. Typical Protocol Message Flow</a>
-</ul>
-<p>
-
-<hr>
-
-
-<h3><a name = "S1">1. Introduction</a></h3>
-
-FastCGI is an open extension to CGI that provides high performance
-for all Internet applications without the penalties of Web server
-APIs.<p>
-
-This specification has narrow
-goal: to specify, from an application perspective, the
-interface between a FastCGI application and a Web server that supports
-FastCGI. Many Web server features related to FastCGI,
-e.g. application management facilities, have nothing to do with the
-application to Web server interface, and are not described here.<p>
-
-This specification is for Unix (more precisely, for POSIX systems that support
-Berkeley Sockets). The bulk of the specification is a simple
-communications protocol that is independent of byte ordering
-and will extend to other systems.<p>
-
-We'll introduce FastCGI by comparing it with conventional Unix
-implementations of CGI/1.1.
-
-FastCGI is designed to support long-lived application processes,
-i.e. <i>application servers</i>. That's a major difference
-compared with conventional Unix implementations of CGI/1.1,
-which construct an application process, use
-it respond to one request, and have it exit.<p>
-
-The initial state of a FastCGI process is more spartan than the initial
-state of a CGI/1.1 process, because the FastCGI process doesn't begin life
-connected to anything. It doesn't have the conventional open files
-<tt>stdin</tt>, <tt>stdout</tt>, and <tt>stderr</tt>, and it doesn't
-receive much information through environment variables. The key
-piece of initial state in a FastCGI process is a listening
-socket, through which it accepts connections from a Web server.<p>
-
-After a FastCGI process accepts a connection on its listening socket,
-the process executes a simple protocol to receive and send data. The
-protocol serves two purposes. First, the protocol
-multiplexes a single transport connection between several independent
-FastCGI requests. This supports applications that are able to process
-concurrent requests using event-driven or multi-threaded programming
-techniques. Second, within each request the protocol provides several
-independent data streams in each direction. This way, for instance,
-both <tt>stdout</tt> and <tt>stderr</tt> data pass over a single
-transport connection from the application to the Web server, rather
-than requiring separate pipes as with CGI/1.1.<p>
-
-A FastCGI application plays one of several well-defined <i>roles</i>.
-The most familiar is the <i>Responder</i> role, in which the
-application receives all the information associated with an HTTP
-request and generates an HTTP response; that's the role CGI/1.1
-programs play. A second role is <i>Authorizer</i>, in which the
-application receives all the information associated with an HTTP
-request and generates an authorized/unauthorized decision.
-A third role is <i>Filter</i>, in which the
-application receives all the information associated with an HTTP
-request, plus an extra stream of data from a file stored on the Web
-server, and generates a "filtered" version of the data stream as
-an HTTP response. The framework is extensible so that more FastCGI
-can be defined later.<p>
-
-In the remainder of this specification the terms "FastCGI
-application," "application process," or "application server" are
-abbreviated to "application" whenever that won't cause confusion.<p>
-
-
-
-<h3><a name = "S2">2. Initial Process State</a></h3>
-
-
-<h4><a name = "S2.1">2.1 Argument list</a></h4>
-
-By default the Web server creates an argument list containing a single
-element, the name of the application, taken to be the last component
-of the executable's path name. The Web server may provide a way
-to specify a different application name, or a more elaborate argument
-list.<p>
-
-Note that the file executed by the Web server might be an interpreter
-file (a text file that starts with the characters <tt>#!</tt>), in
-which case the application's argument list is constructed as described
-in the <tt>execve</tt> manpage.<p>
-
-
-<h4><a name = "S2.2">2.2 File descriptors</a></h4>
-
-The Web server leaves a single file descriptor,
-<tt>FCGI_LISTENSOCK_FILENO</tt>, open when the application begins
-execution. This descriptor refers to a listening socket created by
-the Web server.<p>
-
-<tt>FCGI_LISTENSOCK_FILENO</tt> equals <tt>STDIN_FILENO</tt>.
-The standard descriptors
-<tt>STDOUT_FILENO</tt> and <tt>STDERR_FILENO</tt> are closed when
-the application begins execution. A reliable method for an application
-to determine whether it was invoked using CGI or FastCGI is to call
-<tt>getpeername(FCGI_LISTENSOCK_FILENO)</tt>, which returns
--1 with <tt>errno</tt> set to <tt>ENOTCONN</tt> for
-a FastCGI application.<p>
-
-The Web server's choice of reliable transport, Unix stream pipes
-(<tt>AF_UNIX</tt>) or TCP/IP (<tt>AF_INET</tt>), is implicit in the
-internal state of the <tt>FCGI_LISTENSOCK_FILENO</tt> socket.<p>
-
-
-<h4><a name = "S2.3">2.3 Environment variables</a></h4>
-
-The Web server may use environment variables to pass parameters
-to the application. This specification defines one such
-variable, <tt>FCGI_WEB_SERVER_ADDRS</tt>; we expect more to
-be defined as the specification evolves.
-
-The Web server may provide a way to bind other environment
-variables, such as the <tt>PATH</tt> variable.<p>
-
-
-<h4><a name = "S2.4">2.4 Other state</a></h4>
-
-The Web server may provide a way to specify other components of an
-application's initial process state, such as the priority,
-user ID, group ID, root directory, and working directory of the
-process.<p>
-
-
-
-<h3><a name = "S3">3. Protocol Basics</a></h3>
-
-
-<h4><a name = "S3.1">3.1 Notation</a></h4>
-
-We use C language notation to define protocol message
-formats. All structure elements are defined in terms
-of the <tt>unsigned char</tt> type, and are arranged
-so that an ISO C compiler lays them out in the obvious
-manner, with no padding. The first byte defined in the
-structure is transmitted first, the second byte second, etc.<p>
-
-We use two conventions to abbreviate our definitions.<p>
-
-First, when two adjacent structure components are named identically
-except for the suffixes "<tt>B1</tt>" and "<tt>B0</tt>," it means that
-the two components may be viewed as a single number, computed as
-<tt>B1<<8 + B0</tt>. The name of this single number is the name of
-the components, minus the suffixes. This convention generalizes in an
-obvious way to handle numbers represented in more than two bytes.<p>
-
-Second, we extend C <tt>struct</tt>s to allow the form
-<pre>
- struct {
- unsigned char mumbleLengthB1;
- unsigned char mumbleLengthB0;
- ... /* other stuff */
- unsigned char mumbleData[mumbleLength];
- };
-</pre>
-meaning a structure of varying length, where the length of
-a component is determined by the values of the indicated
-earlier component or components.<p>
-
-
-<h4><a name = "S3.2">3.2 Accepting Transport Connections</a></h4>
-
-A FastCGI application calls <tt>accept()</tt> on the socket referred to
-by file descriptor <tt>FCGI_LISTENSOCK_FILENO</tt> to accept a new
-transport connection.
-
-If the <tt>accept()</tt> succeeds, and the <tt>FCGI_WEB_SERVER_ADDRS</tt>
-environment variable is bound, the application
-application immediately performs the following
-special processing:<p>
-
-<ul type=square>
- <li><tt>FCGI_WEB_SERVER_ADDRS</tt>:
-
- The value is a list of valid IP addresses for the Web server.<p>
-
- If <tt>FCGI_WEB_SERVER_ADDRS</tt>
- was bound, the application checks the peer
- IP address of the new connection for membership in the list.
- If the check fails (including the possibility that the
- connection didn't use TCP/IP transport), the application
- responds by closing the connection.<p>
-
- <tt>FCGI_WEB_SERVER_ADDRS</tt>
- is expressed as a comma-separated list of IP
- addresses. Each IP address is written as four decimal numbers
- in the range [0..255] separated by decimal points. So one
- legal binding for this variable is
- <tt>FCGI_WEB_SERVER_ADDRS=199.170.183.28,199.170.183.71</tt>.<p>
-</ul>
-
-An application may accept several concurrent transport
-connections, but it need not do so.<p>
-
-
-<h4><a name = "S3.3">3.3 Records</a></h4>
-
-Applications execute requests from a Web server using a simple
-protocol. Details of the protocol depend upon the application's role,
-but roughly speaking the Web server first sends parameters and other
-data to the application, then the application sends result data to the
-Web server, and finally the application sends the Web server an
-indication that the request is complete.<p>
-
-All data that flows over the transport connection is carried in
-<i>FastCGI records</i>. FastCGI records accomplish two
-things. First, records multiplex the transport connection between
-several independent FastCGI requests. This multiplexing supports
-applications that are able to process concurrent requests using
-event-driven or multi-threaded programming techniques. Second,
-records provide several independent data streams in each direction
-within a single request. This way, for instance, both <tt>stdout</tt>
-and <tt>stderr</tt> data can pass over a single transport connection
-from the application to the Web server, rather than requiring separate
-connections.<p>
-
-<pre>
- typedef struct {
- unsigned char version;
- unsigned char type;
- unsigned char requestIdB1;
- unsigned char requestIdB0;
- unsigned char contentLengthB1;
- unsigned char contentLengthB0;
- unsigned char paddingLength;
- unsigned char reserved;
- unsigned char contentData[contentLength];
- unsigned char paddingData[paddingLength];
- } FCGI_Record;
-</pre>
-
-A FastCGI record consists of a fixed-length prefix followed by a
-variable number of content and padding bytes. A record contains seven
-components:<p>
-
-<ul type=square>
- <li><tt>version</tt>:
-
- Identifies the FastCGI protocol version. This specification
- documents <tt>FCGI_VERSION_1</tt>.<p>
-
- <li><tt>type</tt>:
-
- Identifies the FastCGI record type, i.e. the general function
- that the record performs. Specific record types and their
- functions are detailed in later sections.<p>
-
- <li><tt>requestId</tt>:
-
- Identifies the <i>FastCGI request</i> to which the record
- belongs.<p>
-
- <li><tt>contentLength</tt>:
-
- The number of bytes in the <tt>contentData</tt> component of the
- record.<p>
-
- <li><tt>paddingLength</tt>:
-
- The number of bytes in the <tt>paddingData</tt> component of the
- record.<p>
-
- <li><tt>contentData</tt>:
-
- Between 0 and 65535 bytes of data, interpreted
- according to the record type.<p>
-
- <li><tt>paddingData</tt>:
-
- Between 0 and 255 bytes of data, which are ignored.<p>
-</ul>
-
-We use a relaxed C <tt>struct</tt> initializer syntax to specify
-constant FastCGI records. We omit the <tt>version</tt> component,
-ignore padding, and treat
-<tt>requestId</tt> as a number. Thus <tt>{FCGI_END_REQUEST, 1,
-{FCGI_REQUEST_COMPLETE,0}}</tt> is a record with <tt>type ==
-FCGI_END_REQUEST</tt>, <tt>requestId == 1</tt>, and <tt>contentData ==
-{FCGI_REQUEST_COMPLETE,0}</tt>.<p>
-
-
-<h5>Padding</h5>
-
-The protocol allows senders to pad the records they send, and requires
-receivers to interpret the <tt>paddingLength</tt> and skip the
-<tt>paddingData</tt>. Padding allows senders to keep data aligned
-for more efficient processing. Experience with the X window
-system protocols shows the performance benefit of such alignment.<p>
-
-We recommend that records be placed on boundaries that are multiples
-of eight bytes. The fixed-length portion of a <tt>FCGI_Record</tt>
-is eight bytes.<p>
-
-
-<h5>Managing Request IDs</h5>
-
-The Web server re-uses FastCGI request IDs; the application keeps
-track of the current state of each request ID on a given transport
-connection. A request ID <tt>R</tt> becomes active when the application
-receives a record <tt>{FCGI_BEGIN_REQUEST, R, ...}</tt> and
-becomes inactive when the application sends a record
-<tt>{FCGI_END_REQUEST, R, ...}</tt> to the Web server.<p>
-
-While a request ID <tt>R</tt> is inactive, the application ignores
-records with <tt>requestId == R</tt>, except for <tt>FCGI_BEGIN_REQUEST</tt>
-records as just described.<p>
-
-The Web server attempts to keep FastCGI request IDs small. That way
-the application can keep track of request ID states using a short
-array rather than a long array or a hash table. An application
-also has the option of accepting only one request at a time.
-In this case the application simply checks incoming <tt>requestId</tt>
-values against the current request ID.<p>
-
-
-<h5>Types of Record Types</h5>
-
-There are two useful ways of classifying FastCGI record types.<p>
-
-The first distinction is between <i>management</i> records and
-<i>application</i> records. A management record contains information
-that is not specific to any Web server request, such as information
-about the protocol capabilities of the application.
-An application record contains information
-about a particular request, identified by the <tt>requestId</tt>
-component.<p>
-
-Management records have a <tt>requestId</tt> value of zero,
-also called the <i>null request ID</i>. Application
-records have a nonzero <tt>requestId</tt>.<p>
-
-The second distinction is between <i>discrete</i> and <i>stream</i>
-records. A discrete record contains a meaningful unit of data all by
-itself. A stream record is part of a <i>stream</i>, i.e. a series of
-zero or more non-empty records (<tt>length != 0</tt>) of the stream
-type, followed by an empty record (<tt>length == 0</tt>) of the stream
-type. The <tt>contentData</tt> components of a stream's records, when
-concatenated, form a byte sequence; this byte sequence is the value of
-the stream. Therefore the value of a stream is independent of how
-many records it contains or how its bytes are divided among the
-non-empty records.<p>
-
-These two classifications are independent. Among the
-record types defined in this version of the FastCGI protocol,
-all management record types are also discrete record types,
-and nearly all application record types are stream record types.
-But three application record types are discrete, and nothing
-prevents defining a management record type that's a stream
-in some later version of the protocol.<p>
-
-
-<h4><a name = "S3.4">3.4 Name-Value Pairs</a></h4>
-
-In many of their roles, FastCGI applications need to read and write
-varying numbers of variable-length values. So it is useful to adopt a
-standard format for encoding a name-value pair.<p>
-
-FastCGI transmits a name-value pair as the length of the name,
-followed by the length of the value, followed by the name,
-followed by the value. Lengths of 127 bytes and less can be encoded
-in one byte, while longer lengths are always encoded in four bytes:<p>
-
-<pre>
- typedef struct {
- unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */
- unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */
- unsigned char nameData[nameLength];
- unsigned char valueData[valueLength];
- } FCGI_NameValuePair11;
-
- typedef struct {
- unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */
- unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */
- unsigned char valueLengthB2;
- unsigned char valueLengthB1;
- unsigned char valueLengthB0;
- unsigned char nameData[nameLength];
- unsigned char valueData[valueLength
- ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
- } FCGI_NameValuePair14;
-
- typedef struct {
- unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */
- unsigned char nameLengthB2;
- unsigned char nameLengthB1;
- unsigned char nameLengthB0;
- unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */
- unsigned char nameData[nameLength
- ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
- unsigned char valueData[valueLength];
- } FCGI_NameValuePair41;
-
- typedef struct {
- unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */
- unsigned char nameLengthB2;
- unsigned char nameLengthB1;
- unsigned char nameLengthB0;
- unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */
- unsigned char valueLengthB2;
- unsigned char valueLengthB1;
- unsigned char valueLengthB0;
- unsigned char nameData[nameLength
- ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
- unsigned char valueData[valueLength
- ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];
- } FCGI_NameValuePair44;
-</pre>
-
-The high-order bit of the first byte of a length indicates the length's
-encoding. A high-order zero implies a one-byte encoding, a one a four-byte
-encoding.<p>
-
-This name-value pair format allows the sender to transmit binary values
-without additional encoding, and enables the receiver to allocate the correct
-amount of storage immediately even for large values.<p>
-
-
-<h4><a name = "S3.5">3.5 Closing Transport Connections</a></h4>
-
-The Web server controls the lifetime of transport connections.
-The Web server can close a connection when no requests are active.
-Or the Web server can delegate close authority to the application
-(see <tt>FCGI_BEGIN_REQUEST</tt>).
-In this case the application closes the connection at the end of
-a specified request.<p>
-
-This flexibility accommodates a variety of application styles.
-Simple applications will process one request at a time and
-accept a new transport connection for each request. More
-complex applications
-will process concurrent requests, over one or multiple transport
-connections, and will keep transport connections open for long
-periods of time.<p>
-
-A simple application gets a significant performance boost by
-closing the transport connection when it has finished writing its
-response. The Web server needs to control the connection lifetime
-for long-lived connections.<p>
-
-When an application closes a connection or finds that a connection
-has closed, the application initiates a new connection.<p>
-
-
-
-<h3><a name = "S4">4. Management Record Types</a></h3>
-
-
-<h4><a name = "S4.1">4.1 <tt>FCGI_GET_VALUES, FCGI_GET_VALUES_RESULT</tt></a></h4>
-
-The Web server can query specific variables within the application.
-The server will typically perform a query on application startup
-in order to to automate certain aspects of system configuration.<p>
-
-The application receives a query as a record <tt>{FCGI_GET_VALUES, 0,
-...}</tt>. The <tt>contentData</tt> portion of a <tt>FCGI_GET_VALUES</tt>
-record contains a sequence of name-value pairs with empty values.<p>
-
-The application responds by sending a record
-<tt>{FCGI_GET_VALUES_RESULT, 0, ...}</tt> with the values supplied. If the
-application doesn't understand a variable name that was
-included in the query, it omits that name from the
-response.<p>
-
-<tt>FCGI_GET_VALUES</tt> is designed to allow an open-ended
-set of variables. The initial set provides information to help
-the server perform application and connection management:<p>
-
-<ul type=square>
- <li><tt>FCGI_MAX_CONNS</tt>:
- The maximum number of concurrent transport connections this
- application will accept, e.g.
- <tt>"1"</tt> or <tt>"10"</tt>.<p>
-
- <li><tt>FCGI_MAX_REQS</tt>:
- The maximum number of concurrent requests this application
- will accept, e.g.
- <tt>"1"</tt> or <tt>"50"</tt>.<p>
-
- <li><tt>FCGI_MPXS_CONNS</tt>:
- <tt>"0"</tt> if this application does not multiplex
- connections (i.e. handle concurrent requests over each
- connection), <tt>"1"</tt> otherwise.<p>
-</ul>
-
-An application may receive a <tt>FCGI_GET_VALUES</tt> record at any
-time. The application's response should not involve the application
-proper but only the FastCGI library.<p>
-
-
-<h4><a name = "S4.2">4.2 <tt>FCGI_UNKNOWN_TYPE</tt></a></h4>
-
-The set of management record types is likely to grow in future versions
-of this protocol. To provide for this evolution, the protocol
-includes the <tt>FCGI_UNKNOWN_TYPE</tt> management record.
-When an application receives a management record whose type <tt>T</tt>
-it does not understand, the application responds with
-<tt>{FCGI_UNKNOWN_TYPE, 0, {T}}</tt>.<p>
-
-The <tt>contentData</tt> component of a <tt>FCGI_UNKNOWN_TYPE</tt> record
-has the form:
-<pre>
- typedef struct {
- unsigned char type;
- unsigned char reserved[7];
- } FCGI_UnknownTypeBody;
-</pre>
-<p>
-
-The <tt>type</tt> component is the type of the unrecognized management
-record.<p>
-
-
-
-<h3><a name = "S5">5. Application Record Types</a></h3>
-
-
-<h4><a name = "S5.1">5.1 <tt>FCGI_BEGIN_REQUEST</tt></a></h4>
-
-The Web server sends a <tt>FCGI_BEGIN_REQUEST</tt> record
-to start a request.<p>
-
-The <tt>contentData</tt> component of a <tt>FCGI_BEGIN_REQUEST</tt> record
-has the form:
-<pre>
- typedef struct {
- unsigned char roleB1;
- unsigned char roleB0;
- unsigned char flags;
- unsigned char reserved[5];
- } FCGI_BeginRequestBody;
-</pre>
-<p>
-
-The <tt>role</tt> component sets the role the Web server expects
-the application to play. The currently-defined roles are:<p>
-
-<ul type=square>
- <li><tt>FCGI_RESPONDER</tt>
- <li><tt>FCGI_AUTHORIZER</tt>
- <li><tt>FCGI_FILTER</tt>
-</ul>
-
-Roles are described in more detail in
-<a href = "#S6">Section 6</a> below.<p>
-
-The <tt>flags</tt> component contains a bit that
-controls connection shutdown:<p>
-
-<ul type=square>
- <li><tt>flags & FCGI_KEEP_CONN</tt>:
- If zero, the application closes the connection after responding to
- this request. If not zero, the application does not close
- the connection after responding to this request; the Web server
- retains responsibility for the connection.<p>
-</ul>
-
-
-<h4><a name = "S5.2">5.2 Name-Value Pair Stream: <tt>FCGI_PARAMS</tt></a></h4>
-
-<tt>FCGI_PARAMS</tt> is a stream record type used in sending
-name-value pairs from the Web server to the application.
-The name-value pairs are sent down the stream one after the other,
-in no specified order.<p>
-
-
-<h4><a name = "S5.3">5.3 Byte Streams: <tt>FCGI_STDIN</tt>, <tt>FCGI_DATA</tt>, <tt>FCGI_STDOUT</tt>, <tt>FCGI_STDERR</tt></a></h4>
-
-<tt>FCGI_STDIN</tt> is a stream record type used in sending arbitrary
-data from the Web server to the application. <tt>FCGI_DATA</tt>
-is a second stream record type used to send additional
-data to the application.<p>
-
-<tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt> are stream record types
-for sending arbitrary data and error data respectively from the
-application to the Web server.<p>
-
-
-<h4><a name = "S5.4">5.4 <tt>FCGI_ABORT_REQUEST</tt></a></h4>
-
-The Web server sends a <tt>FCGI_ABORT_REQUEST</tt> record to
-abort a request. After receiving <tt>{FCGI_ABORT_REQUEST, R}</tt>,
-the application responds as soon as possible with
-<tt>{FCGI_END_REQUEST, R, {FCGI_REQUEST_COMPLETE, appStatus}}</tt>.
-This is truly a response from the application, not a low-level
-acknowledgement from the FastCGI library.<p>
-
-A Web server aborts a FastCGI request when an HTTP client closes its
-transport connection while the FastCGI request is running on behalf of
-that client. The situation may seem unlikely; most FastCGI
-requests will have short response times, with the Web server providing
-output buffering if the client is slow. But the FastCGI application
-may be delayed communicating with another system, or performing a
-server push.<p>
-
-When a Web server is not multiplexing requests over a transport
-connection, the Web server can abort a request by closing the request's
-transport connection. But with multiplexed requests, closing the
-transport connection has the unfortunate effect of aborting <i>all</i>
-the requests on the connection.<p>
-
-
-<h4><a name = "S5.5">5.5 <tt>FCGI_END_REQUEST</tt></a></h4>
-
-The application sends a <tt>FCGI_END_REQUEST</tt> record
-to terminate a request, either because the application
-has processed the request or because the application has rejected
-the request.<p>
-
-The <tt>contentData</tt> component of a <tt>FCGI_END_REQUEST</tt> record
-has the form:
-<pre>
- typedef struct {
- unsigned char appStatusB3;
- unsigned char appStatusB2;
- unsigned char appStatusB1;
- unsigned char appStatusB0;
- unsigned char protocolStatus;
- unsigned char reserved[3];
- } FCGI_EndRequestBody;
-</pre>
-<p>
-
-The <tt>appStatus</tt> component is an application-level status code.
-Each role documents its usage of <tt>appStatus</tt>.<p>
-
-The <tt>protocolStatus</tt> component is a protocol-level status code;
-the possible <tt>protocolStatus</tt> values are:<p>
-
-<ul type=square>
- <li><tt>FCGI_REQUEST_COMPLETE</tt>:
- normal end of request.<p>
-
- <li><tt>FCGI_CANT_MPX_CONN</tt>:
- rejecting a new request. This happens when a Web server sends
- concurrent requests over one connection to an application that
- is designed to process one request at a time per
- connection.<p>
-
- <li><tt>FCGI_OVERLOADED</tt>:
- rejecting a new request. This happens when the application
- runs out of some resource, e.g. database connections.<p>
-
- <li><tt>FCGI_UNKNOWN_ROLE</tt>:
- rejecting a new request. This happens when the Web server
- has specified a role that is unknown to the application.<p>
-</ul>
-
-
-
-<h3><a name = "S6">6. Roles</a></h3>
-
-
-<h4><a name = "S6.1">6.1 Role Protocols</a></h4>
-
-Role protocols only include records with application record
-types. They transfer essentially all data using streams.<p>
-
-To make the protocols reliable and to simplify application
-programming, role protocols are designed to use <i>nearly sequential
-marshalling</i>. In a protocol with strictly sequential marshalling,
-the application receives its first input, then its second, etc. until
-it has received them all. Similarly, the application sends its first
-output, then its second, etc. until it has sent them all. Inputs are
-not interleaved with each other, and outputs are not interleaved with
-each other.<p>
-
-The sequential marshalling rule is too restrictive for some
-FastCGI roles, because CGI programs can write to both <tt>stdout</tt>
-and <tt>stderr</tt> without timing restrictions. So role
-protocols that use both <tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt>
-allow these two streams to be interleaved.<p>
-
-All role protocols use the <tt>FCGI_STDERR</tt> stream just the way
-<tt>stderr</tt> is used in conventional applications programming: to
-report application-level errors in an intelligible way. Use of the
-<tt>FCGI_STDERR</tt> stream is always optional. If an application has
-no errors to report, it sends either no <tt>FCGI_STDERR</tt> records or
-one zero-length <tt>FCGI_STDERR</tt> record.<p>
-
-When a role protocol calls for transmitting a stream other than
-<tt>FCGI_STDERR</tt>, at least one record of the stream type is always
-transmitted, even if the stream is empty.<p>
-
-Again in the interests of reliable protocols and simplified application
-programming, role protocols are designed to be <i>nearly
-request-response</i>. In a truly request-response protocol, the
-application receives all of its input records before sending its first
-output record. Request-response protocols don't allow pipelining.<p>
-
-The request-response rule is too restrictive for some FastCGI roles;
-after all, CGI programs aren't restricted to read all of
-<tt>stdin</tt> before starting to write <tt>stdout</tt>. So some role
-protocols allow that specific possibility. First the application
-receives all of its inputs except for a final stream input. As the
-application begins to receive the final stream input, it can
-begin writing its output.<p>
-
-When a role protocol uses <tt>FCGI_PARAMS</tt> to transmit textual
-values, such as the values that CGI programs obtain from environment
-variables, the length of the value does not include the terminating
-null byte, and the value itself does not include a null byte. An
-application that needs to provide <tt>environ(7)</tt> format
-name-value pairs must insert an equal sign between the name and value
-and append a null byte after the value.<p>
-
-Role protocols do not support the non-parsed header feature
-of CGI. FastCGI applications set response status using
-the <tt>Status</tt> and <tt>Location</tt> CGI headers.<p>
-
-
-<h4><a name = "S6.2">6.2 Responder</a></h4>
-
-A Responder FastCGI application has the same purpose as a CGI/1.1 program:
-It receives all the information associated with an HTTP request and
-generates an HTTP response.<p>
-
-It suffices to explain how each element of CGI/1.1 is emulated by a
-Responder:<p>
-<ul type=square>
- <li>
- The Responder application receives CGI/1.1 environment variables from
- the Web server over <tt>FCGI_PARAMS</tt>.<p>
- <li>
- Next the Responder application receives CGI/1.1
- <tt>stdin</tt> data from
- the Web server over <tt>FCGI_STDIN</tt>. The application receives
- at most <tt>CONTENT_LENGTH</tt> bytes from this stream before
- receiving the end-of-stream indication. (The application
- receives less than <tt>CONTENT_LENGTH</tt> bytes only if the
- HTTP client fails to provide them, e.g. because the client
- crashed.)<p>
- <li>
- The Responder application sends CGI/1.1
- <tt>stdout</tt> data to the Web
- server over <tt>FCGI_STDOUT</tt>, and CGI/1.1 <tt>stderr</tt> data
- over <tt>FCGI_STDERR</tt>. The application sends these
- concurrently, not one after the other. The application must
- wait to finish reading <tt>FCGI_PARAMS</tt> before it begins
- writing <tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt>, but
- it needn't finish reading from <tt>FCGI_STDIN</tt> before it
- begins writing these two streams.<p>
- <li>
- After sending all its <tt>stdout</tt> and <tt>stderr</tt> data,
- the Responder application sends a <tt>FCGI_END_REQUEST</tt> record.
- The application sets the <tt>protocolStatus</tt> component to
- <tt>FCGI_REQUEST_COMPLETE</tt> and the <tt>appStatus</tt> component
- to the status code that the CGI program would have returned
- via the <tt>exit</tt> system call.<p>
-</ul>
-
-A Responder performing an update, e.g. implementing a <tt>POST</tt>
-method, should compare the number of bytes received on <tt>FCGI_STDIN</tt>
-with <tt>CONTENT_LENGTH</tt> and abort the update if the two numbers
-are not equal.<p>
-
-
-<h4><a name = "S6.3">6.3 Authorizer</a></h4>
-
-An Authorizer FastCGI application receives all the information
-associated with an HTTP request and generates an
-authorized/unauthorized decision. In case of an authorized
-decision the Authorizer can also associate name-value pairs
-with the HTTP request; when giving an unauthorized
-decision the Authorizer sends a complete response to the HTTP client.
-<p>
-
-Since CGI/1.1 defines a perfectly good way to represent the information
-associated with an HTTP request, Authorizers use the same
-representation:<p>
-
-<ul type=square>
- <li>
- The Authorizer application receives
- HTTP request information from the Web
- server on the <tt>FCGI_PARAMS</tt> stream,
- in the same format as a Responder. The Web server does not
- send <tt>CONTENT_LENGTH</tt>,
- <tt>PATH_INFO</tt>, <tt>PATH_TRANSLATED</tt>, and
- <tt>SCRIPT_NAME</tt> headers.<p>
- <li>
- The Authorizer application sends
- <tt>stdout</tt> and <tt>stderr</tt> data in
- the same manner as a Responder. The CGI/1.1 response
- status specifies the disposition of the request. If the
- application sends status 200 (OK), the Web server allows
- access. Depending upon its configuration the Web server
- may proceed with other access checks, including requests to other
- Authorizers.<p>
-
- An Authorizer application's 200 response may include headers
- whose names are prefixed with <tt>Variable-</tt>. These
- headers communicate name-value pairs from the
- application to the Web server. For instance, the response header
-<pre>
- Variable-AUTH_METHOD: database lookup
-</pre>
- transmits the value <tt>"database lookup"</tt> with name
- <tt>AUTH-METHOD</tt>. The server associates such name-value
- pairs with the HTTP request and includes them in subsequent
- CGI or FastCGI requests performed in processing the HTTP
- request. When the application gives a 200 response, the
- server ignores response headers whose names aren't prefixed
- with <tt>Variable-</tt> prefix, and ignores any response
- content.<p>
-
- For Authorizer response status values other than "200" (OK), the
- Web server denies access and sends
- the response status, headers, and content
- back to the HTTP client.<p>
-</ul>
-
-
-<h4><a name = "S6.4">6.4 Filter</a></h4>
-
-A Filter FastCGI application receives all the information associated
-with an HTTP request, plus an extra stream of data from a file stored
-on the Web server, and generates a "filtered" version of the data
-stream as an HTTP response.<p>
-
-A Filter is similar in functionality to a Responder that takes a data
-file as a parameter. The difference is that with a Filter, both the
-data file and the Filter itself can be access controlled using the Web
-server's access control mechanisms, while a Responder that takes the
-name of a data file as a parameter must perform its own access control
-checks on the data file.<p>
-
-The steps taken by a Filter are similar to those of a Responder.
-The server presents the Filter with environment variables first,
-then standard input (normally form <tt>POST</tt> data), finally
-the data file input:<p>
-<ul type=square>
- <li>
- Like a Responder, the Filter application receives name-value
- pairs from the Web server over <tt>FCGI_PARAMS</tt>.
- Filter applications receive two Filter-specific variables:
- <tt>FCGI_DATA_LAST_MOD</tt> and <tt>FCGI_DATA_LENGTH</tt>.<p>
- <li>
- Next the Filter application receives CGI/1.1 <tt>stdin</tt> data from
- the Web server over <tt>FCGI_STDIN</tt>. The application receives
- at most <tt>CONTENT_LENGTH</tt> bytes from this stream before
- receiving the end-of-stream indication. (The application
- receives less than <tt>CONTENT_LENGTH</tt> bytes only if the
- HTTP client fails to provide them, e.g. because the client
- crashed.)<p>
- <li>
- Next the Filter application receives the file data from the
- Web server over <tt>FCGI_DATA</tt>. This file's last
- modification time (expressed as an integer number of seconds
- since the epoch January 1, 1970 UTC) is
- <tt>FCGI_DATA_LAST_MOD</tt>; the application may consult
- this variable and respond from a cache without reading
- the file data. The application
- reads at most <tt>FCGI_DATA_LENGTH</tt> bytes from this stream
- before receiving the end-of-stream indication.<p>
- <li>
- The Filter application sends CGI/1.1 <tt>stdout</tt> data to the Web
- server over <tt>FCGI_STDOUT</tt>, and CGI/1.1 <tt>stderr</tt> data
- over <tt>FCGI_STDERR</tt>. The application sends these
- concurrently, not one after the other. The application must
- wait to finish reading <tt>FCGI_STDIN</tt> before it begins
- writing <tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt>, but
- it needn't finish reading from <tt>FCGI_DATA</tt> before it
- begins writing these two streams.<p>
- <li>
- After sending all its <tt>stdout</tt> and <tt>stderr</tt> data,
- the application sends a <tt>FCGI_END_REQUEST</tt> record.
- The application sets the <tt>protocolStatus</tt> component to
- <tt>FCGI_REQUEST_COMPLETE</tt> and the <tt>appStatus</tt> component
- to the status code that a similar CGI program would have returned
- via the <tt>exit</tt> system call.<p>
-</ul>
-
-A Filter should compare the number of bytes received on <tt>FCGI_STDIN</tt>
-with <tt>CONTENT_LENGTH</tt> and on <tt>FCGI_DATA</tt>
-with <tt>FCGI_DATA_LENGTH</tt>. If the numbers don't match
-and the Filter is a query, the Filter
-response should provide an indication that data is missing.
-If the numbers don't match and the Filter is an update, the Filter
-should abort the update.<p>
-
-
-
-<h3><a name = "S7">7. Errors</a></h3>
-
-A FastCGI application exits with zero status to indicate that it
-terminated on purpose, e.g. in order to perform a crude form of
-garbage collection. A FastCGI application that exits with nonzero
-status is assumed to have crashed. How a Web server or other
-application manager responds to
-applications that exit with zero or nonzero status is outside the
-scope of this specification.<p>
-
-A Web server can request that a FastCGI application exit by sending it
-<tt>SIGTERM</tt>. If the application ignores <tt>SIGTERM</tt> the Web
-server can resort to <tt>SIGKILL</tt>.<p>
-
-FastCGI applications report application-level errors with the
-<tt>FCGI_STDERR</tt> stream and the <tt>appStatus</tt> component of
-the <tt>FCGI_END_REQUEST</tt> record. In many cases an error will be
-reported directly to the user via the <tt>FCGI_STDOUT</tt> stream.<p>
-
-On Unix, applications report lower-level errors, including
-FastCGI protocol errors and syntax errors in FastCGI environment
-variables, to <tt>syslog</tt>. Depending upon the severity
-of the error, the application may either continue or
-exit with nonzero status.<p>
-
-
-
-<h3><a name = "S8">8. Types and Constants</a></h3>
-<pre>
-/*
- * Listening socket file number
- */
-#define FCGI_LISTENSOCK_FILENO 0
-
-typedef struct {
- unsigned char version;
- unsigned char type;
- unsigned char requestIdB1;
- unsigned char requestIdB0;
- unsigned char contentLengthB1;
- unsigned char contentLengthB0;
- unsigned char paddingLength;
- unsigned char reserved;
-} FCGI_Header;
-
-/*
- * Number of bytes in a FCGI_Header. Future versions of the protocol
- * will not reduce this number.
- */
-#define FCGI_HEADER_LEN 8
-
-/*
- * Value for version component of FCGI_Header
- */
-#define FCGI_VERSION_1 1
-
-/*
- * Values for type component of FCGI_Header
- */
-#define FCGI_BEGIN_REQUEST 1
-#define FCGI_ABORT_REQUEST 2
-#define FCGI_END_REQUEST 3
-#define FCGI_PARAMS 4
-#define FCGI_STDIN 5
-#define FCGI_STDOUT 6
-#define FCGI_STDERR 7
-#define FCGI_DATA 8
-#define FCGI_GET_VALUES 9
-#define FCGI_GET_VALUES_RESULT 10
-#define FCGI_UNKNOWN_TYPE 11
-#define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE)
-
-/*
- * Value for requestId component of FCGI_Header
- */
-#define FCGI_NULL_REQUEST_ID 0
-
-typedef struct {
- unsigned char roleB1;
- unsigned char roleB0;
- unsigned char flags;
- unsigned char reserved[5];
-} FCGI_BeginRequestBody;
-
-typedef struct {
- FCGI_Header header;
- FCGI_BeginRequestBody body;
-} FCGI_BeginRequestRecord;
-
-/*
- * Mask for flags component of FCGI_BeginRequestBody
- */
-#define FCGI_KEEP_CONN 1
-
-/*
- * Values for role component of FCGI_BeginRequestBody
- */
-#define FCGI_RESPONDER 1
-#define FCGI_AUTHORIZER 2
-#define FCGI_FILTER 3
-
-typedef struct {
- unsigned char appStatusB3;
- unsigned char appStatusB2;
- unsigned char appStatusB1;
- unsigned char appStatusB0;
- unsigned char protocolStatus;
- unsigned char reserved[3];
-} FCGI_EndRequestBody;
-
-typedef struct {
- FCGI_Header header;
- FCGI_EndRequestBody body;
-} FCGI_EndRequestRecord;
-
-/*
- * Values for protocolStatus component of FCGI_EndRequestBody
- */
-#define FCGI_REQUEST_COMPLETE 0
-#define FCGI_CANT_MPX_CONN 1
-#define FCGI_OVERLOADED 2
-#define FCGI_UNKNOWN_ROLE 3
-
-/*
- * Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT records
- */
-#define FCGI_MAX_CONNS "FCGI_MAX_CONNS"
-#define FCGI_MAX_REQS "FCGI_MAX_REQS"
-#define FCGI_MPXS_CONNS "FCGI_MPXS_CONNS"
-
-typedef struct {
- unsigned char type;
- unsigned char reserved[7];
-} FCGI_UnknownTypeBody;
-
-typedef struct {
- FCGI_Header header;
- FCGI_UnknownTypeBody body;
-} FCGI_UnknownTypeRecord;
-</pre>
-<p>
-
-
-
-<h3><a name = "S9">9. References</a></h3>
-
-
-National Center for Supercomputer Applications,
-<a href = "http://hoohoo.ncsa.uiuc.edu/cgi/">The Common Gateway Interface</a>,
-version CGI/1.1.<p>
-
-D.R.T. Robinson,
-<a href = "http://ds.internic.net/internet-drafts/draft-robinson-www-interface-01.txt">The WWW Common Gateway Interface Version 1.1</a>, Internet-Draft, 15 February 1996.<p>
-
-
-
-<h3><a name = "SA">A. Table: Properties of the record types</a></h3>
-
-The following chart lists all of the record types and
-indicates these properties of each:<p>
-
-<ul type=square>
- <li><tt>WS->App</tt>:
- records of this type can only be sent by the Web server to the
- application. Records of other types can only be sent by the
- application to the Web server.<p>
- <li><tt>management</tt>:
- records of this type contain information that is not specific
- to a Web server request, and use the null request ID. Records
- of other types contain request-specific information, and cannot
- use the null request ID.<p>
- <li><tt>stream</tt>:
- records of this type form a stream, terminated by a
- record with empty <tt>contentData</tt>. Records of other types
- are discrete; each carries a meaningful unit of data.<p>
-</ul>
-<pre>
-
- WS->App management stream
-
- FCGI_GET_VALUES x x
- FCGI_GET_VALUES_RESULT x
- FCGI_UNKNOWN_TYPE x
-
- FCGI_BEGIN_REQUEST x
- FCGI_ABORT_REQUEST x
- FCGI_END_REQUEST
- FCGI_PARAMS x x
- FCGI_STDIN x x
- FCGI_DATA x x
- FCGI_STDOUT x
- FCGI_STDERR x
-
-
-</pre>
-<p>
-
-
-
-<h3><a name = "SB">B. Typical Protocol Message Flow</a></h3>
-
-Additional notational conventions for the examples:
-
-<ul>
- <li>The <tt>contentData</tt> of stream records (<tt>FCGI_PARAMS</tt>,
- <tt>FCGI_STDIN</tt>, <tt>FCGI_STDOUT</tt>, and <tt>FCGI_STDERR</tt>)
- is represented as a character string. A string ending in
- <tt>" ... "</tt> is too long to display, so only a prefix is shown.
-
- <li>Messages sent to the Web server are indented
- with respect to messages received from the Web server.
-
- <li>Messages are shown in the time sequence experienced
- by the application.
-</ul>
-
-1. A simple request with no data on <tt>stdin</tt>, and a successful response:
-<pre>
-{FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, 0}}
-{FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
-{FCGI_PARAMS, 1, ""}
-{FCGI_STDIN, 1, ""}
-
- {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n<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:
-<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:
-<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:
-<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>
-
-<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
+ <!--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