📄 fcgi-spec.html
字号:
<P> Applications execute requests from a Web server using a simple protocol. Details of the protocol depend upon the application's role, but roughly speaking the Web server first sends parameters and other data to the application, then the application sends result data to the Web server, and finally the application sends the Web server an indication that the request is complete. </P> <P> All data that flows over the transport connection is carried in <I>FastCGI records</I>. FastCGI records accomplish two things. First, records multiplex the transport connection between several independent FastCGI requests. This multiplexing supports applications that are able to process concurrent requests using event-driven or multi-threaded programming techniques. Second, records provide several independent data streams in each direction within a single request. This way, for instance, both <TT>stdout</TT> and <TT>stderr</TT> data can pass over a single transport connection from the application to the Web server, rather than requiring separate connections. </P> <P> </P><PRE> typedef struct { unsigned char version; unsigned char type; unsigned char requestIdB1; unsigned char requestIdB0; unsigned char contentLengthB1; unsigned char contentLengthB0; unsigned char paddingLength; unsigned char reserved; unsigned char contentData[contentLength]; unsigned char paddingData[paddingLength]; } FCGI_Record;</PRE> <P> A FastCGI record consists of a fixed-length prefix followed by a variable number of content and padding bytes. A record contains seven components: </P> <P> </P> <UL TYPE="square"> <LI> <TT>version</TT>: Identifies the FastCGI protocol version. This specification documents <TT>FCGI_VERSION_1</TT>. <P> </P> </LI> <LI> <TT>type</TT>: Identifies the FastCGI record type, i.e. the general function that the record performs. Specific record types and their functions are detailed in later sections. <P> </P> </LI> <LI> <TT>requestId</TT>: Identifies the <I>FastCGI request</I> to which the record belongs. <P> </P> </LI> <LI> <TT>contentLength</TT>: The number of bytes in the <TT>contentData</TT> component of the record. <P> </P> </LI> <LI> <TT>paddingLength</TT>: The number of bytes in the <TT>paddingData</TT> component of the record. <P> </P> </LI> <LI> <TT>contentData</TT>: Between 0 and 65535 bytes of data, interpreted according to the record type. <P> </P> </LI> <LI> <TT>paddingData</TT>: Between 0 and 255 bytes of data, which are ignored.<BR> <BR> </LI> </UL> <P> We use a relaxed C <TT>struct</TT> initializer syntax to specify constant FastCGI records. We omit the <TT>version</TT> component, ignore padding, and treat <TT>requestId</TT> as a number. Thus <TT>{FCGI_END_REQUEST, 1, {FCGI_REQUEST_COMPLETE,0}}</TT> is a record with <TT>type == FCGI_END_REQUEST</TT>, <TT>requestId == 1</TT>, and <TT>contentData == {FCGI_REQUEST_COMPLETE,0}</TT>. </P> <P> </P> <H5> Padding </H5> <P> The protocol allows senders to pad the records they send, and requires receivers to interpret the <TT>paddingLength</TT> and skip the <TT>paddingData</TT>. Padding allows senders to keep data aligned for more efficient processing. Experience with the X window system protocols shows the performance benefit of such alignment. </P> <P> We recommend that records be placed on boundaries that are multiples of eight bytes. The fixed-length portion of a <TT>FCGI_Record</TT> is eight bytes. </P> <P> </P> <H5> Managing Request IDs </H5> <P> The Web server re-uses FastCGI request IDs; the application keeps track of the current state of each request ID on a given transport connection. A request ID <TT>R</TT> becomes active when the application receives a record <TT>{FCGI_BEGIN_REQUEST, R, ...}</TT> and becomes inactive when the application sends a record <TT>{FCGI_END_REQUEST, R, ...}</TT> to the Web server. </P> <P> While a request ID <TT>R</TT> is inactive, the application ignores records with <TT>requestId == R</TT>, except for <TT>FCGI_BEGIN_REQUEST</TT> records as just described. </P> <P> The Web server attempts to keep FastCGI request IDs small. That way the application can keep track of request ID states using a short array rather than a long array or a hash table. An application also has the option of accepting only one request at a time. In this case the application simply checks incoming <TT>requestId</TT> values against the current request ID. </P> <P> </P> <H5> Types of Record Types </H5> <P> There are two useful ways of classifying FastCGI record types. </P> <P> The first distinction is between <I>management</I> records and <I>application</I> records. A management record contains information that is not specific to any Web server request, such as information about the protocol capabilities of the application. An application record contains information about a particular request, identified by the <TT>requestId</TT> component. </P> <P> Management records have a <TT>requestId</TT> value of zero, also called the <I>null request ID</I>. Application records have a nonzero <TT>requestId</TT>. </P> <P> The second distinction is between <I>discrete</I> and <I>stream</I> records. A discrete record contains a meaningful unit of data all by itself. A stream record is part of a <I>stream</I>, i.e. a series of zero or more non-empty records (<TT>length != 0</TT>) of the stream type, followed by an empty record (<TT>length == 0</TT>) of the stream type. The <TT>contentData</TT> components of a stream's records, when concatenated, form a byte sequence; this byte sequence is the value of the stream. Therefore the value of a stream is independent of how many records it contains or how its bytes are divided among the non-empty records. </P> <P> These two classifications are independent. Among the record types defined in this version of the FastCGI protocol, all management record types are also discrete record types, and nearly all application record types are stream record types. But three application record types are discrete, and nothing prevents defining a management record type that's a stream in some later version of the protocol. </P> <P> </P> <H4> <A NAME="S3.4">3.4 Name-Value Pairs</A> </H4> <P> In many of their roles, FastCGI applications need to read and write varying numbers of variable-length values. So it is useful to adopt a standard format for encoding a name-value pair. </P> <P> FastCGI transmits a name-value pair as the length of the name, followed by the length of the value, followed by the name, followed by the value. Lengths of 127 bytes and less can be encoded in one byte, while longer lengths are always encoded in four bytes: </P> <P> </P><PRE> typedef struct { unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */ unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */ unsigned char nameData[nameLength]; unsigned char valueData[valueLength]; } FCGI_NameValuePair11; typedef struct { unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */ unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */ unsigned char valueLengthB2; unsigned char valueLengthB1; unsigned char valueLengthB0; unsigned char nameData[nameLength]; unsigned char valueData[valueLength ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0]; } FCGI_NameValuePair14; typedef struct { unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */ unsigned char nameLengthB2; unsigned char nameLengthB1; unsigned char nameLengthB0; unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */ unsigned char nameData[nameLength ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0]; unsigned char valueData[valueLength]; } FCGI_NameValuePair41; typedef struct { unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */ unsigned char nameLengthB2; unsigned char nameLengthB1; unsigned char nameLengthB0; unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */ unsigned char valueLengthB2; unsigned char valueLengthB1; unsigned char valueLengthB0; unsigned char nameData[nameLength ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0]; unsigned char valueData[valueLength ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0]; } FCGI_NameValuePair44;</PRE> <P> The high-order bit of the first byte of a length indicates the length's encoding. A high-order zero implies a one-byte encoding, a one a four-byte encoding. </P> <P> This name-value pair format allows the sender to transmit binary values without additional encoding, and enables the receiver to allocate the correct amount of storage immediately even for large values. </P> <P> </P> <H4> <A NAME="S3.5">3.5 Closing Transport Connections</A> </H4> <P> The Web server controls the lifetime of transport connections. The Web server can close a connection when no requests are active. Or the Web server can delegate close authority to the application (see <TT>FCGI_BEGIN_REQUEST</TT>). In this case the application closes the connection at the end of a specified request. </P> <P> This flexibility accommodates a variety of application styles. Simple applications will process one request at a time and accept a new transport connection for each request. More complex applications will process concurrent requests, over one or multiple transport connections, and will keep transport connections open for long periods of time. </P> <P> A simple application gets a significant performance boost by closing the transport connection when it has finished writing its response. The Web server needs to control the connection lifetime for long-lived connections. </P> <P> When an application closes a connection or finds that a connection has closed, the application initiates a new connection. </P> <P> </P> <H3> <A NAME="S4">4. Management Record Types</A> </H3> <H4> <A NAME="S4.1">4.1 <TT>FCGI_GET_VALUES, FCGI_GET_VALUES_RESULT</TT></A> </H4> <P> The Web server can query specific variables within the application. The server will typically perform a query on application startup in order to to automate certain aspects of system configuration. </P> <P> The application receives a query as a record <TT>{FCGI_GET_VALUES, 0, ...}</TT>. The <TT>contentData</TT> portion of a <TT>FCGI_GET_VALUES</TT> record contains a sequence of name-value pairs with empty values. </P> <P> The application responds by sending a record <TT>{FCGI_GET_VALUES_RESULT, 0, ...}</TT> with the values supplied. If the application doesn't understand a variable name that was included in the query, it omits that name from the response. </P> <P> <TT>FCGI_GET_VALUES</TT> is designed to allow an open-ended set of variables. The initial set provides information to help the server perform application and connection management: </P> <P> </P> <UL TYPE="square"> <LI> <TT>FCGI_MAX_CONNS</TT>: The maximum number of concurrent transport connections this application will accept, e.g. <TT>"1"</TT> or <TT>"10"</TT>. <P> </P> </LI> <LI> <TT>FCGI_MAX_REQS</TT>: The maximum number of concurrent requests this application will accept, e.g. <TT>"1"</TT> or <TT>"50"</TT>. <P> </P> </LI> <LI> <TT>FCGI_MPXS_CONNS</TT>: <TT>"0"</TT> if this application does not multiplex connections (i.e. handle concurrent requests over each connection), <TT>"1"</TT> otherwise.<BR> <BR> </LI> </UL> <P> An application may receive a <TT>FCGI_GET_VALUES</TT> record at any time. The application's response should not involve the application proper but only the FastCGI library. </P> <P> </P> <H4> <A NAME="S4.2">4.2 <TT>FCGI_UNKNOWN_TYPE</TT></A> </H4> <P> The set of management record types is likely to grow in future versions of this protocol. To provide for this evolution, the protocol includes the <TT>FCGI_UNKNOWN_TYPE</TT> management record. When an application receives a management record whose type <TT>T</TT> it does not understand, the application responds with <TT>{FCGI_UNKNOWN_TYPE, 0, {T}}</TT>. </P> <P> The <TT>contentData</TT> component of a <TT>FCGI_UNKNOWN_TYPE</TT> record has the form: </P><PRE> typedef struct { unsigned char type; unsigned char reserved[7]; } FCGI_UnknownTypeBody;</PRE> <P> The <TT>type</TT> component is the type of the unrecognized management record. </P> <P> </P> <H3> <A NAME="S5">5. Application Record Types</A> </H3> <H4> <A NAME="S5.1">5.1 <TT>FCGI_BEGIN_REQUEST</TT></A> </H4> <P> The Web server sends a <TT>FCGI_BEGIN_REQUEST</TT> record to start a request. </P> <P> The <TT>contentData</TT> component of a <TT>FCGI_BEGIN_REQUEST</TT> record has the form: </P><PRE> typedef struct { unsigned char roleB1; unsigned char roleB0; unsigned char flags;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -