Commit | Line | Data |
0198fd3c |
1 | <html> |
2 | <!--Copyright (c) 1996 Open Market, Inc. --> |
3 | <!--See the file "LICENSE.TERMS" for information on usage and redistribution--> |
4 | <!--of this file, and for a DISCLAIMER OF ALL WARRANTIES. --> |
5 | <head> |
6 | <title>FastCGI Specification</title> |
7 | </head> |
8 | |
9 | <body> |
10 | <center> |
11 | <h2>FastCGI Specification</h2> |
12 | </center> |
13 | |
14 | <center> |
15 | Mark R. Brown<br> |
16 | Open Market, Inc.<br> |
17 | <p> |
18 | |
19 | Document Version: 1.0<br> |
20 | 29 April 1996<br> |
21 | </center> |
22 | <p> |
23 | |
24 | <h5 align=center> |
25 | Copyright © 1996 Open Market, Inc. 245 First Street, Cambridge, |
26 | MA 02142 U.S.A.<br> |
27 | Tel: 617-621-9500 Fax: 617-621-1703 URL: |
28 | <a href="http://www.openmarket.com/">http://www.openmarket.com/</a><br> |
29 | <br> |
6791223e |
30 | $Id: fcgi-spec.html,v 1.2 2001/05/14 13:00:30 robs Exp $ |
0198fd3c |
31 | </h5> |
32 | <hr> |
33 | |
34 | |
35 | <ul type=square> |
36 | <li><a HREF = "#S1">1. Introduction</a> |
37 | <li><a HREF = "#S2">2. Initial Process State</a> |
38 | <ul type=square> |
39 | <li><a HREF = "#S2.1">2.1 Argument list</a> |
40 | <li><a HREF = "#S2.2">2.2 File descriptors</a> |
41 | <li><a HREF = "#S2.3">2.3 Environment variables</a> |
42 | <li><a HREF = "#S2.4">2.4 Other state</a> |
43 | </ul> |
44 | <li><a HREF = "#S3">3. Protocol Basics</a> |
45 | <ul type=square> |
46 | <li><a HREF = "#S3.1">3.1 Notation</a> |
47 | <li><a HREF = "#S3.2">3.2 Accepting Transport Connections</a> |
48 | <li><a HREF = "#S3.3">3.3 Records</a> |
49 | <li><a HREF = "#S3.4">3.4 Name-Value Pairs</a> |
50 | <li><a HREF = "#S3.5">3.5 Closing Transport Connections</a> |
51 | </ul> |
52 | <li><a HREF = "#S4">4. Management Record Types</a> |
53 | <ul type=square> |
54 | <li><a HREF = "#S4.1">4.1 <tt>FCGI_GET_VALUES, FCGI_GET_VALUES_RESULT</tt></a> |
55 | <li><a HREF = "#S4.2">4.2 <tt>FCGI_UNKNOWN_TYPE</tt></a> |
56 | </ul> |
57 | <li><a HREF = "#S5">5. Application Record Types</a> |
58 | <ul type=square> |
59 | <li><a HREF = "#S5.1">5.1 <tt>FCGI_BEGIN_REQUEST</tt></a> |
60 | <li><a HREF = "#S5.2">5.2 Name-Value Pair Streams: <tt>FCGI_PARAMS</tt>, <tt>FCGI_RESULTS</tt></a> |
61 | <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> |
62 | <li><a HREF = "#S5.4">5.4 <tt>FCGI_ABORT_REQUEST</tt></a> |
63 | <li><a HREF = "#S5.5">5.5 <tt>FCGI_END_REQUEST</tt></a> |
64 | </ul> |
65 | <li><a HREF = "#S6">6. Roles</a> |
66 | <ul type=square> |
67 | <li><a HREF = "#S6.1">6.1 Role Protocols</a> |
68 | <li><a HREF = "#S6.2">6.2 Responder</a> |
69 | <li><a HREF = "#S6.3">6.3 Authorizer</a> |
6791223e |
70 | <li><a HREF = "#S6.4">6.4 Filter</a> |
0198fd3c |
71 | </ul> |
72 | <li><a HREF = "#S7">7. Errors</a> |
73 | <li><a HREF = "#S8">8. Types and Constants</a> |
74 | <li><a HREF = "#S9">9. References</a> |
75 | <li><a HREF = "#SA">A. Table: Properties of the record types</a> |
76 | <li><a HREF = "#SB">B. Typical Protocol Message Flow</a> |
77 | </ul> |
78 | <p> |
79 | |
80 | <hr> |
81 | |
82 | |
83 | <h3><a name = "S1">1. Introduction</a></h3> |
84 | |
85 | FastCGI is an open extension to CGI that provides high performance |
86 | for all Internet applications without the penalties of Web server |
87 | APIs.<p> |
88 | |
89 | This specification has narrow |
90 | goal: to specify, from an application perspective, the |
91 | interface between a FastCGI application and a Web server that supports |
92 | FastCGI. Many Web server features related to FastCGI, |
93 | e.g. application management facilities, have nothing to do with the |
94 | application to Web server interface, and are not described here.<p> |
95 | |
96 | This specification is for Unix (more precisely, for POSIX systems that support |
97 | Berkeley Sockets). The bulk of the specification is a simple |
98 | communications protocol that is independent of byte ordering |
99 | and will extend to other systems.<p> |
100 | |
101 | We'll introduce FastCGI by comparing it with conventional Unix |
102 | implementations of CGI/1.1. |
103 | |
104 | FastCGI is designed to support long-lived application processes, |
105 | i.e. <i>application servers</i>. That's a major difference |
106 | compared with conventional Unix implementations of CGI/1.1, |
107 | which construct an application process, use |
108 | it respond to one request, and have it exit.<p> |
109 | |
110 | The initial state of a FastCGI process is more spartan than the initial |
111 | state of a CGI/1.1 process, because the FastCGI process doesn't begin life |
112 | connected to anything. It doesn't have the conventional open files |
113 | <tt>stdin</tt>, <tt>stdout</tt>, and <tt>stderr</tt>, and it doesn't |
114 | receive much information through environment variables. The key |
115 | piece of initial state in a FastCGI process is a listening |
116 | socket, through which it accepts connections from a Web server.<p> |
117 | |
118 | After a FastCGI process accepts a connection on its listening socket, |
119 | the process executes a simple protocol to receive and send data. The |
120 | protocol serves two purposes. First, the protocol |
121 | multiplexes a single transport connection between several independent |
122 | FastCGI requests. This supports applications that are able to process |
123 | concurrent requests using event-driven or multi-threaded programming |
124 | techniques. Second, within each request the protocol provides several |
125 | independent data streams in each direction. This way, for instance, |
126 | both <tt>stdout</tt> and <tt>stderr</tt> data pass over a single |
127 | transport connection from the application to the Web server, rather |
128 | than requiring separate pipes as with CGI/1.1.<p> |
129 | |
130 | A FastCGI application plays one of several well-defined <i>roles</i>. |
131 | The most familiar is the <i>Responder</i> role, in which the |
132 | application receives all the information associated with an HTTP |
133 | request and generates an HTTP response; that's the role CGI/1.1 |
134 | programs play. A second role is <i>Authorizer</i>, in which the |
135 | application receives all the information associated with an HTTP |
136 | request and generates an authorized/unauthorized decision. |
137 | A third role is <i>Filter</i>, in which the |
138 | application receives all the information associated with an HTTP |
139 | request, plus an extra stream of data from a file stored on the Web |
140 | server, and generates a "filtered" version of the data stream as |
141 | an HTTP response. The framework is extensible so that more FastCGI |
142 | can be defined later.<p> |
143 | |
144 | In the remainder of this specification the terms "FastCGI |
145 | application," "application process," or "application server" are |
146 | abbreviated to "application" whenever that won't cause confusion.<p> |
147 | |
148 | |
149 | |
150 | <h3><a name = "S2">2. Initial Process State</a></h3> |
151 | |
152 | |
153 | <h4><a name = "S2.1">2.1 Argument list</a></h4> |
154 | |
155 | By default the Web server creates an argument list containing a single |
156 | element, the name of the application, taken to be the last component |
157 | of the executable's path name. The Web server may provide a way |
158 | to specify a different application name, or a more elaborate argument |
159 | list.<p> |
160 | |
161 | Note that the file executed by the Web server might be an interpreter |
162 | file (a text file that starts with the characters <tt>#!</tt>), in |
163 | which case the application's argument list is constructed as described |
164 | in the <tt>execve</tt> manpage.<p> |
165 | |
166 | |
167 | <h4><a name = "S2.2">2.2 File descriptors</a></h4> |
168 | |
169 | The Web server leaves a single file descriptor, |
170 | <tt>FCGI_LISTENSOCK_FILENO</tt>, open when the application begins |
171 | execution. This descriptor refers to a listening socket created by |
172 | the Web server.<p> |
173 | |
174 | <tt>FCGI_LISTENSOCK_FILENO</tt> equals <tt>STDIN_FILENO</tt>. |
175 | The standard descriptors |
176 | <tt>STDOUT_FILENO</tt> and <tt>STDERR_FILENO</tt> are closed when |
177 | the application begins execution. A reliable method for an application |
178 | to determine whether it was invoked using CGI or FastCGI is to call |
179 | <tt>getpeername(FCGI_LISTENSOCK_FILENO)</tt>, which returns |
180 | -1 with <tt>errno</tt> set to <tt>ENOTCONN</tt> for |
181 | a FastCGI application.<p> |
182 | |
183 | The Web server's choice of reliable transport, Unix stream pipes |
184 | (<tt>AF_UNIX</tt>) or TCP/IP (<tt>AF_INET</tt>), is implicit in the |
185 | internal state of the <tt>FCGI_LISTENSOCK_FILENO</tt> socket.<p> |
186 | |
187 | |
188 | <h4><a name = "S2.3">2.3 Environment variables</a></h4> |
189 | |
190 | The Web server may use environment variables to pass parameters |
191 | to the application. This specification defines one such |
192 | variable, <tt>FCGI_WEB_SERVER_ADDRS</tt>; we expect more to |
193 | be defined as the specification evolves. |
194 | |
195 | The Web server may provide a way to bind other environment |
196 | variables, such as the <tt>PATH</tt> variable.<p> |
197 | |
198 | |
199 | <h4><a name = "S2.4">2.4 Other state</a></h4> |
200 | |
201 | The Web server may provide a way to specify other components of an |
202 | application's initial process state, such as the priority, |
203 | user ID, group ID, root directory, and working directory of the |
204 | process.<p> |
205 | |
206 | |
207 | |
208 | <h3><a name = "S3">3. Protocol Basics</a></h3> |
209 | |
210 | |
211 | <h4><a name = "S3.1">3.1 Notation</a></h4> |
212 | |
213 | We use C language notation to define protocol message |
214 | formats. All structure elements are defined in terms |
215 | of the <tt>unsigned char</tt> type, and are arranged |
216 | so that an ISO C compiler lays them out in the obvious |
217 | manner, with no padding. The first byte defined in the |
218 | structure is transmitted first, the second byte second, etc.<p> |
219 | |
220 | We use two conventions to abbreviate our definitions.<p> |
221 | |
222 | First, when two adjacent structure components are named identically |
223 | except for the suffixes "<tt>B1</tt>" and "<tt>B0</tt>," it means that |
224 | the two components may be viewed as a single number, computed as |
225 | <tt>B1<<8 + B0</tt>. The name of this single number is the name of |
226 | the components, minus the suffixes. This convention generalizes in an |
227 | obvious way to handle numbers represented in more than two bytes.<p> |
228 | |
229 | Second, we extend C <tt>struct</tt>s to allow the form |
230 | <pre> |
231 | struct { |
232 | unsigned char mumbleLengthB1; |
233 | unsigned char mumbleLengthB0; |
234 | ... /* other stuff */ |
235 | unsigned char mumbleData[mumbleLength]; |
236 | }; |
237 | </pre> |
238 | meaning a structure of varying length, where the length of |
239 | a component is determined by the values of the indicated |
240 | earlier component or components.<p> |
241 | |
242 | |
243 | <h4><a name = "S3.2">3.2 Accepting Transport Connections</a></h4> |
244 | |
245 | A FastCGI application calls <tt>accept()</tt> on the socket referred to |
246 | by file descriptor <tt>FCGI_LISTENSOCK_FILENO</tt> to accept a new |
247 | transport connection. |
248 | |
249 | If the <tt>accept()</tt> succeeds, and the <tt>FCGI_WEB_SERVER_ADDRS</tt> |
250 | environment variable is bound, the application |
251 | application immediately performs the following |
252 | special processing:<p> |
253 | |
254 | <ul type=square> |
255 | <li><tt>FCGI_WEB_SERVER_ADDRS</tt>: |
256 | |
257 | The value is a list of valid IP addresses for the Web server.<p> |
258 | |
259 | If <tt>FCGI_WEB_SERVER_ADDRS</tt> |
260 | was bound, the application checks the peer |
261 | IP address of the new connection for membership in the list. |
262 | If the check fails (including the possibility that the |
263 | connection didn't use TCP/IP transport), the application |
264 | responds by closing the connection.<p> |
265 | |
266 | <tt>FCGI_WEB_SERVER_ADDRS</tt> |
267 | is expressed as a comma-separated list of IP |
268 | addresses. Each IP address is written as four decimal numbers |
269 | in the range [0..255] separated by decimal points. So one |
270 | legal binding for this variable is |
271 | <tt>FCGI_WEB_SERVER_ADDRS=199.170.183.28,199.170.183.71</tt>.<p> |
272 | </ul> |
273 | |
274 | An application may accept several concurrent transport |
275 | connections, but it need not do so.<p> |
276 | |
277 | |
278 | <h4><a name = "S3.3">3.3 Records</a></h4> |
279 | |
280 | Applications execute requests from a Web server using a simple |
281 | protocol. Details of the protocol depend upon the application's role, |
282 | but roughly speaking the Web server first sends parameters and other |
283 | data to the application, then the application sends result data to the |
284 | Web server, and finally the application sends the Web server an |
285 | indication that the request is complete.<p> |
286 | |
287 | All data that flows over the transport connection is carried in |
288 | <i>FastCGI records</i>. FastCGI records accomplish two |
289 | things. First, records multiplex the transport connection between |
290 | several independent FastCGI requests. This multiplexing supports |
291 | applications that are able to process concurrent requests using |
292 | event-driven or multi-threaded programming techniques. Second, |
293 | records provide several independent data streams in each direction |
294 | within a single request. This way, for instance, both <tt>stdout</tt> |
295 | and <tt>stderr</tt> data can pass over a single transport connection |
296 | from the application to the Web server, rather than requiring separate |
297 | connections.<p> |
298 | |
299 | <pre> |
300 | typedef struct { |
301 | unsigned char version; |
302 | unsigned char type; |
303 | unsigned char requestIdB1; |
304 | unsigned char requestIdB0; |
305 | unsigned char contentLengthB1; |
306 | unsigned char contentLengthB0; |
307 | unsigned char paddingLength; |
308 | unsigned char reserved; |
309 | unsigned char contentData[contentLength]; |
310 | unsigned char paddingData[paddingLength]; |
311 | } FCGI_Record; |
312 | </pre> |
313 | |
314 | A FastCGI record consists of a fixed-length prefix followed by a |
315 | variable number of content and padding bytes. A record contains seven |
316 | components:<p> |
317 | |
318 | <ul type=square> |
319 | <li><tt>version</tt>: |
320 | |
321 | Identifies the FastCGI protocol version. This specification |
322 | documents <tt>FCGI_VERSION_1</tt>.<p> |
323 | |
324 | <li><tt>type</tt>: |
325 | |
326 | Identifies the FastCGI record type, i.e. the general function |
327 | that the record performs. Specific record types and their |
328 | functions are detailed in later sections.<p> |
329 | |
330 | <li><tt>requestId</tt>: |
331 | |
332 | Identifies the <i>FastCGI request</i> to which the record |
333 | belongs.<p> |
334 | |
335 | <li><tt>contentLength</tt>: |
336 | |
337 | The number of bytes in the <tt>contentData</tt> component of the |
338 | record.<p> |
339 | |
340 | <li><tt>paddingLength</tt>: |
341 | |
342 | The number of bytes in the <tt>paddingData</tt> component of the |
343 | record.<p> |
344 | |
345 | <li><tt>contentData</tt>: |
346 | |
347 | Between 0 and 65535 bytes of data, interpreted |
348 | according to the record type.<p> |
349 | |
350 | <li><tt>paddingData</tt>: |
351 | |
352 | Between 0 and 255 bytes of data, which are ignored.<p> |
353 | </ul> |
354 | |
355 | We use a relaxed C <tt>struct</tt> initializer syntax to specify |
356 | constant FastCGI records. We omit the <tt>version</tt> component, |
357 | ignore padding, and treat |
358 | <tt>requestId</tt> as a number. Thus <tt>{FCGI_END_REQUEST, 1, |
359 | {FCGI_REQUEST_COMPLETE,0}}</tt> is a record with <tt>type == |
360 | FCGI_END_REQUEST</tt>, <tt>requestId == 1</tt>, and <tt>contentData == |
361 | {FCGI_REQUEST_COMPLETE,0}</tt>.<p> |
362 | |
363 | |
364 | <h5>Padding</h5> |
365 | |
366 | The protocol allows senders to pad the records they send, and requires |
367 | receivers to interpret the <tt>paddingLength</tt> and skip the |
368 | <tt>paddingData</tt>. Padding allows senders to keep data aligned |
369 | for more efficient processing. Experience with the X window |
370 | system protocols shows the performance benefit of such alignment.<p> |
371 | |
372 | We recommend that records be placed on boundaries that are multiples |
373 | of eight bytes. The fixed-length portion of a <tt>FCGI_Record</tt> |
374 | is eight bytes.<p> |
375 | |
376 | |
377 | <h5>Managing Request IDs</h5> |
378 | |
379 | The Web server re-uses FastCGI request IDs; the application keeps |
380 | track of the current state of each request ID on a given transport |
381 | connection. A request ID <tt>R</tt> becomes active when the application |
382 | receives a record <tt>{FCGI_BEGIN_REQUEST, R, ...}</tt> and |
383 | becomes inactive when the application sends a record |
384 | <tt>{FCGI_END_REQUEST, R, ...}</tt> to the Web server.<p> |
385 | |
386 | While a request ID <tt>R</tt> is inactive, the application ignores |
387 | records with <tt>requestId == R</tt>, except for <tt>FCGI_BEGIN_REQUEST</tt> |
388 | records as just described.<p> |
389 | |
390 | The Web server attempts to keep FastCGI request IDs small. That way |
391 | the application can keep track of request ID states using a short |
392 | array rather than a long array or a hash table. An application |
393 | also has the option of accepting only one request at a time. |
394 | In this case the application simply checks incoming <tt>requestId</tt> |
395 | values against the current request ID.<p> |
396 | |
397 | |
398 | <h5>Types of Record Types</h5> |
399 | |
400 | There are two useful ways of classifying FastCGI record types.<p> |
401 | |
402 | The first distinction is between <i>management</i> records and |
403 | <i>application</i> records. A management record contains information |
404 | that is not specific to any Web server request, such as information |
405 | about the protocol capabilities of the application. |
406 | An application record contains information |
407 | about a particular request, identified by the <tt>requestId</tt> |
408 | component.<p> |
409 | |
410 | Management records have a <tt>requestId</tt> value of zero, |
411 | also called the <i>null request ID</i>. Application |
412 | records have a nonzero <tt>requestId</tt>.<p> |
413 | |
414 | The second distinction is between <i>discrete</i> and <i>stream</i> |
415 | records. A discrete record contains a meaningful unit of data all by |
416 | itself. A stream record is part of a <i>stream</i>, i.e. a series of |
417 | zero or more non-empty records (<tt>length != 0</tt>) of the stream |
418 | type, followed by an empty record (<tt>length == 0</tt>) of the stream |
419 | type. The <tt>contentData</tt> components of a stream's records, when |
420 | concatenated, form a byte sequence; this byte sequence is the value of |
421 | the stream. Therefore the value of a stream is independent of how |
422 | many records it contains or how its bytes are divided among the |
423 | non-empty records.<p> |
424 | |
425 | These two classifications are independent. Among the |
426 | record types defined in this version of the FastCGI protocol, |
427 | all management record types are also discrete record types, |
428 | and nearly all application record types are stream record types. |
429 | But three application record types are discrete, and nothing |
430 | prevents defining a management record type that's a stream |
431 | in some later version of the protocol.<p> |
432 | |
433 | |
434 | <h4><a name = "S3.4">3.4 Name-Value Pairs</a></h4> |
435 | |
436 | In many of their roles, FastCGI applications need to read and write |
437 | varying numbers of variable-length values. So it is useful to adopt a |
438 | standard format for encoding a name-value pair.<p> |
439 | |
440 | FastCGI transmits a name-value pair as the length of the name, |
441 | followed by the length of the value, followed by the name, |
442 | followed by the value. Lengths of 127 bytes and less can be encoded |
443 | in one byte, while longer lengths are always encoded in four bytes:<p> |
444 | |
445 | <pre> |
446 | typedef struct { |
447 | unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */ |
448 | unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */ |
449 | unsigned char nameData[nameLength]; |
450 | unsigned char valueData[valueLength]; |
451 | } FCGI_NameValuePair11; |
452 | |
453 | typedef struct { |
454 | unsigned char nameLengthB0; /* nameLengthB0 >> 7 == 0 */ |
455 | unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */ |
456 | unsigned char valueLengthB2; |
457 | unsigned char valueLengthB1; |
458 | unsigned char valueLengthB0; |
459 | unsigned char nameData[nameLength]; |
460 | unsigned char valueData[valueLength |
461 | ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0]; |
462 | } FCGI_NameValuePair14; |
463 | |
464 | typedef struct { |
465 | unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */ |
466 | unsigned char nameLengthB2; |
467 | unsigned char nameLengthB1; |
468 | unsigned char nameLengthB0; |
469 | unsigned char valueLengthB0; /* valueLengthB0 >> 7 == 0 */ |
470 | unsigned char nameData[nameLength |
471 | ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0]; |
472 | unsigned char valueData[valueLength]; |
473 | } FCGI_NameValuePair41; |
474 | |
475 | typedef struct { |
476 | unsigned char nameLengthB3; /* nameLengthB3 >> 7 == 1 */ |
477 | unsigned char nameLengthB2; |
478 | unsigned char nameLengthB1; |
479 | unsigned char nameLengthB0; |
480 | unsigned char valueLengthB3; /* valueLengthB3 >> 7 == 1 */ |
481 | unsigned char valueLengthB2; |
482 | unsigned char valueLengthB1; |
483 | unsigned char valueLengthB0; |
484 | unsigned char nameData[nameLength |
485 | ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0]; |
486 | unsigned char valueData[valueLength |
487 | ((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0]; |
488 | } FCGI_NameValuePair44; |
489 | </pre> |
490 | |
491 | The high-order bit of the first byte of a length indicates the length's |
492 | encoding. A high-order zero implies a one-byte encoding, a one a four-byte |
493 | encoding.<p> |
494 | |
495 | This name-value pair format allows the sender to transmit binary values |
496 | without additional encoding, and enables the receiver to allocate the correct |
497 | amount of storage immediately even for large values.<p> |
498 | |
499 | |
500 | <h4><a name = "S3.5">3.5 Closing Transport Connections</a></h4> |
501 | |
502 | The Web server controls the lifetime of transport connections. |
503 | The Web server can close a connection when no requests are active. |
504 | Or the Web server can delegate close authority to the application |
505 | (see <tt>FCGI_BEGIN_REQUEST</tt>). |
506 | In this case the application closes the connection at the end of |
507 | a specified request.<p> |
508 | |
509 | This flexibility accommodates a variety of application styles. |
510 | Simple applications will process one request at a time and |
511 | accept a new transport connection for each request. More |
512 | complex applications |
513 | will process concurrent requests, over one or multiple transport |
514 | connections, and will keep transport connections open for long |
515 | periods of time.<p> |
516 | |
517 | A simple application gets a significant performance boost by |
518 | closing the transport connection when it has finished writing its |
519 | response. The Web server needs to control the connection lifetime |
520 | for long-lived connections.<p> |
521 | |
522 | When an application closes a connection or finds that a connection |
523 | has closed, the application initiates a new connection.<p> |
524 | |
525 | |
526 | |
527 | <h3><a name = "S4">4. Management Record Types</a></h3> |
528 | |
529 | |
530 | <h4><a name = "S4.1">4.1 <tt>FCGI_GET_VALUES, FCGI_GET_VALUES_RESULT</tt></a></h4> |
531 | |
532 | The Web server can query specific variables within the application. |
533 | The server will typically perform a query on application startup |
534 | in order to to automate certain aspects of system configuration.<p> |
535 | |
536 | The application receives a query as a record <tt>{FCGI_GET_VALUES, 0, |
537 | ...}</tt>. The <tt>contentData</tt> portion of a <tt>FCGI_GET_VALUES</tt> |
538 | record contains a sequence of name-value pairs with empty values.<p> |
539 | |
540 | The application responds by sending a record |
541 | <tt>{FCGI_GET_VALUES_RESULT, 0, ...}</tt> with the values supplied. If the |
542 | application doesn't understand a variable name that was |
543 | included in the query, it omits that name from the |
544 | response.<p> |
545 | |
546 | <tt>FCGI_GET_VALUES</tt> is designed to allow an open-ended |
547 | set of variables. The initial set provides information to help |
548 | the server perform application and connection management:<p> |
549 | |
550 | <ul type=square> |
551 | <li><tt>FCGI_MAX_CONNS</tt>: |
552 | The maximum number of concurrent transport connections this |
553 | application will accept, e.g. |
554 | <tt>"1"</tt> or <tt>"10"</tt>.<p> |
555 | |
556 | <li><tt>FCGI_MAX_REQS</tt>: |
557 | The maximum number of concurrent requests this application |
558 | will accept, e.g. |
559 | <tt>"1"</tt> or <tt>"50"</tt>.<p> |
560 | |
561 | <li><tt>FCGI_MPXS_CONNS</tt>: |
562 | <tt>"0"</tt> if this application does not multiplex |
563 | connections (i.e. handle concurrent requests over each |
564 | connection), <tt>"1"</tt> otherwise.<p> |
565 | </ul> |
566 | |
567 | An application may receive a <tt>FCGI_GET_VALUES</tt> record at any |
568 | time. The application's response should not involve the application |
569 | proper but only the FastCGI library.<p> |
570 | |
571 | |
572 | <h4><a name = "S4.2">4.2 <tt>FCGI_UNKNOWN_TYPE</tt></a></h4> |
573 | |
574 | The set of management record types is likely to grow in future versions |
575 | of this protocol. To provide for this evolution, the protocol |
576 | includes the <tt>FCGI_UNKNOWN_TYPE</tt> management record. |
577 | When an application receives a management record whose type <tt>T</tt> |
578 | it does not understand, the application responds with |
579 | <tt>{FCGI_UNKNOWN_TYPE, 0, {T}}</tt>.<p> |
580 | |
581 | The <tt>contentData</tt> component of a <tt>FCGI_UNKNOWN_TYPE</tt> record |
582 | has the form: |
583 | <pre> |
584 | typedef struct { |
585 | unsigned char type; |
586 | unsigned char reserved[7]; |
587 | } FCGI_UnknownTypeBody; |
588 | </pre> |
589 | <p> |
590 | |
591 | The <tt>type</tt> component is the type of the unrecognized management |
592 | record.<p> |
593 | |
594 | |
595 | |
596 | <h3><a name = "S5">5. Application Record Types</a></h3> |
597 | |
598 | |
599 | <h4><a name = "S5.1">5.1 <tt>FCGI_BEGIN_REQUEST</tt></a></h4> |
600 | |
601 | The Web server sends a <tt>FCGI_BEGIN_REQUEST</tt> record |
602 | to start a request.<p> |
603 | |
604 | The <tt>contentData</tt> component of a <tt>FCGI_BEGIN_REQUEST</tt> record |
605 | has the form: |
606 | <pre> |
607 | typedef struct { |
608 | unsigned char roleB1; |
609 | unsigned char roleB0; |
610 | unsigned char flags; |
611 | unsigned char reserved[5]; |
612 | } FCGI_BeginRequestBody; |
613 | </pre> |
614 | <p> |
615 | |
616 | The <tt>role</tt> component sets the role the Web server expects |
617 | the application to play. The currently-defined roles are:<p> |
618 | |
619 | <ul type=square> |
620 | <li><tt>FCGI_RESPONDER</tt> |
621 | <li><tt>FCGI_AUTHORIZER</tt> |
622 | <li><tt>FCGI_FILTER</tt> |
623 | </ul> |
624 | |
625 | Roles are described in more detail in |
626 | <a href = "#S6">Section 6</a> below.<p> |
627 | |
628 | The <tt>flags</tt> component contains a bit that |
629 | controls connection shutdown:<p> |
630 | |
631 | <ul type=square> |
632 | <li><tt>flags & FCGI_KEEP_CONN</tt>: |
633 | If zero, the application closes the connection after responding to |
634 | this request. If not zero, the application does not close |
635 | the connection after responding to this request; the Web server |
636 | retains responsibility for the connection.<p> |
637 | </ul> |
638 | |
639 | |
640 | <h4><a name = "S5.2">5.2 Name-Value Pair Stream: <tt>FCGI_PARAMS</tt></a></h4> |
641 | |
642 | <tt>FCGI_PARAMS</tt> is a stream record type used in sending |
643 | name-value pairs from the Web server to the application. |
644 | The name-value pairs are sent down the stream one after the other, |
645 | in no specified order.<p> |
646 | |
647 | |
648 | <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> |
649 | |
650 | <tt>FCGI_STDIN</tt> is a stream record type used in sending arbitrary |
651 | data from the Web server to the application. <tt>FCGI_DATA</tt> |
652 | is a second stream record type used to send additional |
653 | data to the application.<p> |
654 | |
655 | <tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt> are stream record types |
656 | for sending arbitrary data and error data respectively from the |
657 | application to the Web server.<p> |
658 | |
659 | |
660 | <h4><a name = "S5.4">5.4 <tt>FCGI_ABORT_REQUEST</tt></a></h4> |
661 | |
662 | The Web server sends a <tt>FCGI_ABORT_REQUEST</tt> record to |
663 | abort a request. After receiving <tt>{FCGI_ABORT_REQUEST, R}</tt>, |
664 | the application responds as soon as possible with |
665 | <tt>{FCGI_END_REQUEST, R, {FCGI_REQUEST_COMPLETE, appStatus}}</tt>. |
666 | This is truly a response from the application, not a low-level |
667 | acknowledgement from the FastCGI library.<p> |
668 | |
669 | A Web server aborts a FastCGI request when an HTTP client closes its |
670 | transport connection while the FastCGI request is running on behalf of |
671 | that client. The situation may seem unlikely; most FastCGI |
672 | requests will have short response times, with the Web server providing |
673 | output buffering if the client is slow. But the FastCGI application |
674 | may be delayed communicating with another system, or performing a |
675 | server push.<p> |
676 | |
677 | When a Web server is not multiplexing requests over a transport |
678 | connection, the Web server can abort a request by closing the request's |
679 | transport connection. But with multiplexed requests, closing the |
680 | transport connection has the unfortunate effect of aborting <i>all</i> |
681 | the requests on the connection.<p> |
682 | |
683 | |
684 | <h4><a name = "S5.5">5.5 <tt>FCGI_END_REQUEST</tt></a></h4> |
685 | |
686 | The application sends a <tt>FCGI_END_REQUEST</tt> record |
687 | to terminate a request, either because the application |
688 | has processed the request or because the application has rejected |
689 | the request.<p> |
690 | |
691 | The <tt>contentData</tt> component of a <tt>FCGI_END_REQUEST</tt> record |
692 | has the form: |
693 | <pre> |
694 | typedef struct { |
695 | unsigned char appStatusB3; |
696 | unsigned char appStatusB2; |
697 | unsigned char appStatusB1; |
698 | unsigned char appStatusB0; |
699 | unsigned char protocolStatus; |
700 | unsigned char reserved[3]; |
701 | } FCGI_EndRequestBody; |
702 | </pre> |
703 | <p> |
704 | |
705 | The <tt>appStatus</tt> component is an application-level status code. |
706 | Each role documents its usage of <tt>appStatus</tt>.<p> |
707 | |
708 | The <tt>protocolStatus</tt> component is a protocol-level status code; |
709 | the possible <tt>protocolStatus</tt> values are:<p> |
710 | |
711 | <ul type=square> |
712 | <li><tt>FCGI_REQUEST_COMPLETE</tt>: |
713 | normal end of request.<p> |
714 | |
715 | <li><tt>FCGI_CANT_MPX_CONN</tt>: |
716 | rejecting a new request. This happens when a Web server sends |
717 | concurrent requests over one connection to an application that |
718 | is designed to process one request at a time per |
719 | connection.<p> |
720 | |
721 | <li><tt>FCGI_OVERLOADED</tt>: |
722 | rejecting a new request. This happens when the application |
723 | runs out of some resource, e.g. database connections.<p> |
724 | |
725 | <li><tt>FCGI_UNKNOWN_ROLE</tt>: |
726 | rejecting a new request. This happens when the Web server |
727 | has specified a role that is unknown to the application.<p> |
728 | </ul> |
729 | |
730 | |
731 | |
732 | <h3><a name = "S6">6. Roles</a></h3> |
733 | |
734 | |
735 | <h4><a name = "S6.1">6.1 Role Protocols</a></h4> |
736 | |
737 | Role protocols only include records with application record |
738 | types. They transfer essentially all data using streams.<p> |
739 | |
740 | To make the protocols reliable and to simplify application |
741 | programming, role protocols are designed to use <i>nearly sequential |
742 | marshalling</i>. In a protocol with strictly sequential marshalling, |
743 | the application receives its first input, then its second, etc. until |
744 | it has received them all. Similarly, the application sends its first |
745 | output, then its second, etc. until it has sent them all. Inputs are |
746 | not interleaved with each other, and outputs are not interleaved with |
747 | each other.<p> |
748 | |
749 | The sequential marshalling rule is too restrictive for some |
750 | FastCGI roles, because CGI programs can write to both <tt>stdout</tt> |
751 | and <tt>stderr</tt> without timing restrictions. So role |
752 | protocols that use both <tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt> |
753 | allow these two streams to be interleaved.<p> |
754 | |
755 | All role protocols use the <tt>FCGI_STDERR</tt> stream just the way |
756 | <tt>stderr</tt> is used in conventional applications programming: to |
757 | report application-level errors in an intelligible way. Use of the |
758 | <tt>FCGI_STDERR</tt> stream is always optional. If an application has |
759 | no errors to report, it sends either no <tt>FCGI_STDERR</tt> records or |
760 | one zero-length <tt>FCGI_STDERR</tt> record.<p> |
761 | |
762 | When a role protocol calls for transmitting a stream other than |
763 | <tt>FCGI_STDERR</tt>, at least one record of the stream type is always |
764 | transmitted, even if the stream is empty.<p> |
765 | |
766 | Again in the interests of reliable protocols and simplified application |
767 | programming, role protocols are designed to be <i>nearly |
768 | request-response</i>. In a truly request-response protocol, the |
769 | application receives all of its input records before sending its first |
770 | output record. Request-response protocols don't allow pipelining.<p> |
771 | |
772 | The request-response rule is too restrictive for some FastCGI roles; |
773 | after all, CGI programs aren't restricted to read all of |
774 | <tt>stdin</tt> before starting to write <tt>stdout</tt>. So some role |
775 | protocols allow that specific possibility. First the application |
776 | receives all of its inputs except for a final stream input. As the |
777 | application begins to receive the final stream input, it can |
778 | begin writing its output.<p> |
779 | |
780 | When a role protocol uses <tt>FCGI_PARAMS</tt> to transmit textual |
781 | values, such as the values that CGI programs obtain from environment |
782 | variables, the length of the value does not include the terminating |
783 | null byte, and the value itself does not include a null byte. An |
784 | application that needs to provide <tt>environ(7)</tt> format |
785 | name-value pairs must insert an equal sign between the name and value |
786 | and append a null byte after the value.<p> |
787 | |
788 | Role protocols do not support the non-parsed header feature |
789 | of CGI. FastCGI applications set response status using |
790 | the <tt>Status</tt> and <tt>Location</tt> CGI headers.<p> |
791 | |
792 | |
793 | <h4><a name = "S6.2">6.2 Responder</a></h4> |
794 | |
795 | A Responder FastCGI application has the same purpose as a CGI/1.1 program: |
796 | It receives all the information associated with an HTTP request and |
797 | generates an HTTP response.<p> |
798 | |
799 | It suffices to explain how each element of CGI/1.1 is emulated by a |
800 | Responder:<p> |
801 | <ul type=square> |
802 | <li> |
803 | The Responder application receives CGI/1.1 environment variables from |
804 | the Web server over <tt>FCGI_PARAMS</tt>.<p> |
805 | <li> |
806 | Next the Responder application receives CGI/1.1 |
807 | <tt>stdin</tt> data from |
808 | the Web server over <tt>FCGI_STDIN</tt>. The application receives |
809 | at most <tt>CONTENT_LENGTH</tt> bytes from this stream before |
810 | receiving the end-of-stream indication. (The application |
811 | receives less than <tt>CONTENT_LENGTH</tt> bytes only if the |
812 | HTTP client fails to provide them, e.g. because the client |
813 | crashed.)<p> |
814 | <li> |
815 | The Responder application sends CGI/1.1 |
816 | <tt>stdout</tt> data to the Web |
817 | server over <tt>FCGI_STDOUT</tt>, and CGI/1.1 <tt>stderr</tt> data |
818 | over <tt>FCGI_STDERR</tt>. The application sends these |
819 | concurrently, not one after the other. The application must |
820 | wait to finish reading <tt>FCGI_PARAMS</tt> before it begins |
821 | writing <tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt>, but |
822 | it needn't finish reading from <tt>FCGI_STDIN</tt> before it |
823 | begins writing these two streams.<p> |
824 | <li> |
825 | After sending all its <tt>stdout</tt> and <tt>stderr</tt> data, |
826 | the Responder application sends a <tt>FCGI_END_REQUEST</tt> record. |
827 | The application sets the <tt>protocolStatus</tt> component to |
828 | <tt>FCGI_REQUEST_COMPLETE</tt> and the <tt>appStatus</tt> component |
829 | to the status code that the CGI program would have returned |
830 | via the <tt>exit</tt> system call.<p> |
831 | </ul> |
832 | |
833 | A Responder performing an update, e.g. implementing a <tt>POST</tt> |
834 | method, should compare the number of bytes received on <tt>FCGI_STDIN</tt> |
835 | with <tt>CONTENT_LENGTH</tt> and abort the update if the two numbers |
836 | are not equal.<p> |
837 | |
838 | |
839 | <h4><a name = "S6.3">6.3 Authorizer</a></h4> |
840 | |
841 | An Authorizer FastCGI application receives all the information |
842 | associated with an HTTP request and generates an |
843 | authorized/unauthorized decision. In case of an authorized |
844 | decision the Authorizer can also associate name-value pairs |
845 | with the HTTP request; when giving an unauthorized |
846 | decision the Authorizer sends a complete response to the HTTP client. |
847 | <p> |
848 | |
849 | Since CGI/1.1 defines a perfectly good way to represent the information |
850 | associated with an HTTP request, Authorizers use the same |
851 | representation:<p> |
852 | |
853 | <ul type=square> |
854 | <li> |
855 | The Authorizer application receives |
856 | HTTP request information from the Web |
857 | server on the <tt>FCGI_PARAMS</tt> stream, |
858 | in the same format as a Responder. The Web server does not |
859 | send <tt>CONTENT_LENGTH</tt>, |
860 | <tt>PATH_INFO</tt>, <tt>PATH_TRANSLATED</tt>, and |
861 | <tt>SCRIPT_NAME</tt> headers.<p> |
862 | <li> |
863 | The Authorizer application sends |
864 | <tt>stdout</tt> and <tt>stderr</tt> data in |
865 | the same manner as a Responder. The CGI/1.1 response |
866 | status specifies the disposition of the request. If the |
867 | application sends status 200 (OK), the Web server allows |
868 | access. Depending upon its configuration the Web server |
869 | may proceed with other access checks, including requests to other |
870 | Authorizers.<p> |
871 | |
872 | An Authorizer application's 200 response may include headers |
873 | whose names are prefixed with <tt>Variable-</tt>. These |
874 | headers communicate name-value pairs from the |
875 | application to the Web server. For instance, the response header |
876 | <pre> |
877 | Variable-AUTH_METHOD: database lookup |
878 | </pre> |
879 | transmits the value <tt>"database lookup"</tt> with name |
880 | <tt>AUTH-METHOD</tt>. The server associates such name-value |
881 | pairs with the HTTP request and includes them in subsequent |
882 | CGI or FastCGI requests performed in processing the HTTP |
883 | request. When the application gives a 200 response, the |
884 | server ignores response headers whose names aren't prefixed |
885 | with <tt>Variable-</tt> prefix, and ignores any response |
886 | content.<p> |
887 | |
888 | For Authorizer response status values other than "200" (OK), the |
889 | Web server denies access and sends |
890 | the response status, headers, and content |
891 | back to the HTTP client.<p> |
892 | </ul> |
893 | |
894 | |
895 | <h4><a name = "S6.4">6.4 Filter</a></h4> |
896 | |
897 | A Filter FastCGI application receives all the information associated |
898 | with an HTTP request, plus an extra stream of data from a file stored |
899 | on the Web server, and generates a "filtered" version of the data |
900 | stream as an HTTP response.<p> |
901 | |
902 | A Filter is similar in functionality to a Responder that takes a data |
903 | file as a parameter. The difference is that with a Filter, both the |
904 | data file and the Filter itself can be access controlled using the Web |
905 | server's access control mechanisms, while a Responder that takes the |
906 | name of a data file as a parameter must perform its own access control |
907 | checks on the data file.<p> |
908 | |
909 | The steps taken by a Filter are similar to those of a Responder. |
910 | The server presents the Filter with environment variables first, |
911 | then standard input (normally form <tt>POST</tt> data), finally |
912 | the data file input:<p> |
913 | <ul type=square> |
914 | <li> |
915 | Like a Responder, the Filter application receives name-value |
916 | pairs from the Web server over <tt>FCGI_PARAMS</tt>. |
917 | Filter applications receive two Filter-specific variables: |
918 | <tt>FCGI_DATA_LAST_MOD</tt> and <tt>FCGI_DATA_LENGTH</tt>.<p> |
919 | <li> |
920 | Next the Filter application receives CGI/1.1 <tt>stdin</tt> data from |
921 | the Web server over <tt>FCGI_STDIN</tt>. The application receives |
922 | at most <tt>CONTENT_LENGTH</tt> bytes from this stream before |
923 | receiving the end-of-stream indication. (The application |
924 | receives less than <tt>CONTENT_LENGTH</tt> bytes only if the |
925 | HTTP client fails to provide them, e.g. because the client |
926 | crashed.)<p> |
927 | <li> |
928 | Next the Filter application receives the file data from the |
929 | Web server over <tt>FCGI_DATA</tt>. This file's last |
930 | modification time (expressed as an integer number of seconds |
931 | since the epoch January 1, 1970 UTC) is |
932 | <tt>FCGI_DATA_LAST_MOD</tt>; the application may consult |
933 | this variable and respond from a cache without reading |
934 | the file data. The application |
935 | reads at most <tt>FCGI_DATA_LENGTH</tt> bytes from this stream |
936 | before receiving the end-of-stream indication.<p> |
937 | <li> |
938 | The Filter application sends CGI/1.1 <tt>stdout</tt> data to the Web |
939 | server over <tt>FCGI_STDOUT</tt>, and CGI/1.1 <tt>stderr</tt> data |
940 | over <tt>FCGI_STDERR</tt>. The application sends these |
941 | concurrently, not one after the other. The application must |
942 | wait to finish reading <tt>FCGI_STDIN</tt> before it begins |
943 | writing <tt>FCGI_STDOUT</tt> and <tt>FCGI_STDERR</tt>, but |
944 | it needn't finish reading from <tt>FCGI_DATA</tt> before it |
945 | begins writing these two streams.<p> |
946 | <li> |
947 | After sending all its <tt>stdout</tt> and <tt>stderr</tt> data, |
948 | the application sends a <tt>FCGI_END_REQUEST</tt> record. |
949 | The application sets the <tt>protocolStatus</tt> component to |
950 | <tt>FCGI_REQUEST_COMPLETE</tt> and the <tt>appStatus</tt> component |
951 | to the status code that a similar CGI program would have returned |
952 | via the <tt>exit</tt> system call.<p> |
953 | </ul> |
954 | |
955 | A Filter should compare the number of bytes received on <tt>FCGI_STDIN</tt> |
956 | with <tt>CONTENT_LENGTH</tt> and on <tt>FCGI_DATA</tt> |
957 | with <tt>FCGI_DATA_LENGTH</tt>. If the numbers don't match |
958 | and the Filter is a query, the Filter |
959 | response should provide an indication that data is missing. |
960 | If the numbers don't match and the Filter is an update, the Filter |
961 | should abort the update.<p> |
962 | |
963 | |
964 | |
965 | <h3><a name = "S7">7. Errors</a></h3> |
966 | |
967 | A FastCGI application exits with zero status to indicate that it |
968 | terminated on purpose, e.g. in order to perform a crude form of |
969 | garbage collection. A FastCGI application that exits with nonzero |
970 | status is assumed to have crashed. How a Web server or other |
971 | application manager responds to |
972 | applications that exit with zero or nonzero status is outside the |
973 | scope of this specification.<p> |
974 | |
975 | A Web server can request that a FastCGI application exit by sending it |
976 | <tt>SIGTERM</tt>. If the application ignores <tt>SIGTERM</tt> the Web |
977 | server can resort to <tt>SIGKILL</tt>.<p> |
978 | |
979 | FastCGI applications report application-level errors with the |
980 | <tt>FCGI_STDERR</tt> stream and the <tt>appStatus</tt> component of |
981 | the <tt>FCGI_END_REQUEST</tt> record. In many cases an error will be |
982 | reported directly to the user via the <tt>FCGI_STDOUT</tt> stream.<p> |
983 | |
984 | On Unix, applications report lower-level errors, including |
985 | FastCGI protocol errors and syntax errors in FastCGI environment |
986 | variables, to <tt>syslog</tt>. Depending upon the severity |
987 | of the error, the application may either continue or |
988 | exit with nonzero status.<p> |
989 | |
990 | |
991 | |
992 | <h3><a name = "S8">8. Types and Constants</a></h3> |
993 | <pre> |
994 | /* |
995 | * Listening socket file number |
996 | */ |
997 | #define FCGI_LISTENSOCK_FILENO 0 |
998 | |
999 | typedef struct { |
1000 | unsigned char version; |
1001 | unsigned char type; |
1002 | unsigned char requestIdB1; |
1003 | unsigned char requestIdB0; |
1004 | unsigned char contentLengthB1; |
1005 | unsigned char contentLengthB0; |
1006 | unsigned char paddingLength; |
1007 | unsigned char reserved; |
1008 | } FCGI_Header; |
1009 | |
1010 | /* |
1011 | * Number of bytes in a FCGI_Header. Future versions of the protocol |
1012 | * will not reduce this number. |
1013 | */ |
1014 | #define FCGI_HEADER_LEN 8 |
1015 | |
1016 | /* |
1017 | * Value for version component of FCGI_Header |
1018 | */ |
1019 | #define FCGI_VERSION_1 1 |
1020 | |
1021 | /* |
1022 | * Values for type component of FCGI_Header |
1023 | */ |
1024 | #define FCGI_BEGIN_REQUEST 1 |
1025 | #define FCGI_ABORT_REQUEST 2 |
1026 | #define FCGI_END_REQUEST 3 |
1027 | #define FCGI_PARAMS 4 |
1028 | #define FCGI_STDIN 5 |
1029 | #define FCGI_STDOUT 6 |
1030 | #define FCGI_STDERR 7 |
1031 | #define FCGI_DATA 8 |
1032 | #define FCGI_GET_VALUES 9 |
1033 | #define FCGI_GET_VALUES_RESULT 10 |
1034 | #define FCGI_UNKNOWN_TYPE 11 |
1035 | #define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE) |
1036 | |
1037 | /* |
1038 | * Value for requestId component of FCGI_Header |
1039 | */ |
1040 | #define FCGI_NULL_REQUEST_ID 0 |
1041 | |
1042 | typedef struct { |
1043 | unsigned char roleB1; |
1044 | unsigned char roleB0; |
1045 | unsigned char flags; |
1046 | unsigned char reserved[5]; |
1047 | } FCGI_BeginRequestBody; |
1048 | |
1049 | typedef struct { |
1050 | FCGI_Header header; |
1051 | FCGI_BeginRequestBody body; |
1052 | } FCGI_BeginRequestRecord; |
1053 | |
1054 | /* |
1055 | * Mask for flags component of FCGI_BeginRequestBody |
1056 | */ |
1057 | #define FCGI_KEEP_CONN 1 |
1058 | |
1059 | /* |
1060 | * Values for role component of FCGI_BeginRequestBody |
1061 | */ |
1062 | #define FCGI_RESPONDER 1 |
1063 | #define FCGI_AUTHORIZER 2 |
1064 | #define FCGI_FILTER 3 |
1065 | |
1066 | typedef struct { |
1067 | unsigned char appStatusB3; |
1068 | unsigned char appStatusB2; |
1069 | unsigned char appStatusB1; |
1070 | unsigned char appStatusB0; |
1071 | unsigned char protocolStatus; |
1072 | unsigned char reserved[3]; |
1073 | } FCGI_EndRequestBody; |
1074 | |
1075 | typedef struct { |
1076 | FCGI_Header header; |
1077 | FCGI_EndRequestBody body; |
1078 | } FCGI_EndRequestRecord; |
1079 | |
1080 | /* |
1081 | * Values for protocolStatus component of FCGI_EndRequestBody |
1082 | */ |
1083 | #define FCGI_REQUEST_COMPLETE 0 |
1084 | #define FCGI_CANT_MPX_CONN 1 |
1085 | #define FCGI_OVERLOADED 2 |
1086 | #define FCGI_UNKNOWN_ROLE 3 |
1087 | |
1088 | /* |
1089 | * Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT records |
1090 | */ |
1091 | #define FCGI_MAX_CONNS "FCGI_MAX_CONNS" |
1092 | #define FCGI_MAX_REQS "FCGI_MAX_REQS" |
1093 | #define FCGI_MPXS_CONNS "FCGI_MPXS_CONNS" |
1094 | |
1095 | typedef struct { |
1096 | unsigned char type; |
1097 | unsigned char reserved[7]; |
1098 | } FCGI_UnknownTypeBody; |
1099 | |
1100 | typedef struct { |
1101 | FCGI_Header header; |
1102 | FCGI_UnknownTypeBody body; |
1103 | } FCGI_UnknownTypeRecord; |
1104 | </pre> |
1105 | <p> |
1106 | |
1107 | |
1108 | |
1109 | <h3><a name = "S9">9. References</a></h3> |
1110 | |
1111 | |
1112 | National Center for Supercomputer Applications, |
1113 | <a href = "http://hoohoo.ncsa.uiuc.edu/cgi/">The Common Gateway Interface</a>, |
1114 | version CGI/1.1.<p> |
1115 | |
1116 | D.R.T. Robinson, |
1117 | <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> |
1118 | |
1119 | |
1120 | |
1121 | <h3><a name = "SA">A. Table: Properties of the record types</a></h3> |
1122 | |
1123 | The following chart lists all of the record types and |
1124 | indicates these properties of each:<p> |
1125 | |
1126 | <ul type=square> |
1127 | <li><tt>WS->App</tt>: |
1128 | records of this type can only be sent by the Web server to the |
1129 | application. Records of other types can only be sent by the |
1130 | application to the Web server.<p> |
1131 | <li><tt>management</tt>: |
1132 | records of this type contain information that is not specific |
1133 | to a Web server request, and use the null request ID. Records |
1134 | of other types contain request-specific information, and cannot |
1135 | use the null request ID.<p> |
1136 | <li><tt>stream</tt>: |
1137 | records of this type form a stream, terminated by a |
1138 | record with empty <tt>contentData</tt>. Records of other types |
1139 | are discrete; each carries a meaningful unit of data.<p> |
1140 | </ul> |
1141 | <pre> |
1142 | |
1143 | WS->App management stream |
1144 | |
1145 | FCGI_GET_VALUES x x |
1146 | FCGI_GET_VALUES_RESULT x |
1147 | FCGI_UNKNOWN_TYPE x |
1148 | |
1149 | FCGI_BEGIN_REQUEST x |
1150 | FCGI_ABORT_REQUEST x |
1151 | FCGI_END_REQUEST |
1152 | FCGI_PARAMS x x |
1153 | FCGI_STDIN x x |
1154 | FCGI_DATA x x |
1155 | FCGI_STDOUT x |
1156 | FCGI_STDERR x |
1157 | |
1158 | |
1159 | </pre> |
1160 | <p> |
1161 | |
1162 | |
1163 | |
1164 | <h3><a name = "SB">B. Typical Protocol Message Flow</a></h3> |
1165 | |
1166 | Additional notational conventions for the examples: |
1167 | |
1168 | <ul> |
1169 | <li>The <tt>contentData</tt> of stream records (<tt>FCGI_PARAMS</tt>, |
1170 | <tt>FCGI_STDIN</tt>, <tt>FCGI_STDOUT</tt>, and <tt>FCGI_STDERR</tt>) |
1171 | is represented as a character string. A string ending in |
1172 | <tt>" ... "</tt> is too long to display, so only a prefix is shown. |
1173 | |
1174 | <li>Messages sent to the Web server are indented |
1175 | with respect to messages received from the Web server. |
1176 | |
1177 | <li>Messages are shown in the time sequence experienced |
1178 | by the application. |
1179 | </ul> |
1180 | |
1181 | 1. A simple request with no data on <tt>stdin</tt>, and a successful response: |
1182 | <pre> |
1183 | {FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, 0}} |
1184 | {FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "} |
1185 | {FCGI_PARAMS, 1, ""} |
1186 | {FCGI_STDIN, 1, ""} |
1187 | |
1188 | {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n<html>\n<head> ... "} |
1189 | {FCGI_STDOUT, 1, ""} |
1190 | {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}} |
1191 | </pre><p> |
1192 | |
1193 | 2. Similar to example 1, but this time with data on <tt>stdin</tt>. |
1194 | The Web server chooses to send the |
1195 | parameters using more <tt>FCGI_PARAMS</tt> records than before: |
1196 | <pre> |
1197 | {FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, 0}} |
1198 | {FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SER"} |
1199 | {FCGI_PARAMS, 1, "VER_ADDR199.170.183.42 ... "} |
1200 | {FCGI_PARAMS, 1, ""} |
1201 | {FCGI_STDIN, 1, "quantity=100&item=3047936"} |
1202 | {FCGI_STDIN, 1, ""} |
1203 | |
1204 | {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n<html>\n<head> ... "} |
1205 | {FCGI_STDOUT, 1, ""} |
1206 | {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}} |
1207 | </pre><p> |
1208 | |
1209 | 3. Similar to example 1, but this time the application detects an error. |
1210 | The application logs a message to |
1211 | <tt>stderr</tt>, returns a page to the client, and returns |
1212 | non-zero exit status to the Web server. The application |
1213 | chooses to send the page using more <tt>FCGI_STDOUT</tt> records: |
1214 | <pre> |
1215 | {FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, 0}} |
1216 | {FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "} |
1217 | {FCGI_PARAMS, 1, ""} |
1218 | {FCGI_STDIN, 1, ""} |
1219 | |
1220 | {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n<ht"} |
1221 | {FCGI_STDERR, 1, "config error: missing SI_UID\n"} |
1222 | {FCGI_STDOUT, 1, "ml>\n<head> ... "} |
1223 | {FCGI_STDOUT, 1, ""} |
1224 | {FCGI_STDERR, 1, ""} |
1225 | {FCGI_END_REQUEST, 1, {938, FCGI_REQUEST_COMPLETE}} |
1226 | </pre><p> |
1227 | |
1228 | 4. Two instances of example 1, multiplexed onto a single connection. |
1229 | The first request is more difficult than the second, so the |
1230 | application finishes the requests out of order: |
1231 | <pre> |
1232 | {FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, FCGI_KEEP_CONN}} |
1233 | {FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "} |
1234 | {FCGI_PARAMS, 1, ""} |
1235 | {FCGI_BEGIN_REQUEST, 2, {FCGI_RESPONDER, FCGI_KEEP_CONN}} |
1236 | {FCGI_PARAMS, 2, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "} |
1237 | {FCGI_STDIN, 1, ""} |
1238 | |
1239 | {FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n"} |
1240 | |
1241 | {FCGI_PARAMS, 2, ""} |
1242 | {FCGI_STDIN, 2, ""} |
1243 | |
1244 | {FCGI_STDOUT, 2, "Content-type: text/html\r\n\r\n<html>\n<head> ... "} |
1245 | {FCGI_STDOUT, 2, ""} |
1246 | {FCGI_END_REQUEST, 2, {0, FCGI_REQUEST_COMPLETE}} |
1247 | {FCGI_STDOUT, 1, "<html>\n<head> ... "} |
1248 | {FCGI_STDOUT, 1, ""} |
1249 | {FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}} |
1250 | </pre><p> |
1251 | |
1252 | <hr> |
1253 | |
1254 | <address> |
1255 | © 1995, 1996 Open Market, Inc. / mbrown@openmarket.com |
1256 | </address> |
1257 | |
1258 | </body> |
1259 | </html> |