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