Commit | Line | Data |
0198fd3c |
1 | <HTML>\r |
2 | \r |
3 | <HEAD>\r |
4 | \r |
5 | <TITLE>FastCGI</TITLE>\r |
6 | \r |
7 | <META NAME="GENERATOR" CONTENT="Internet Assistant for Microsoft Word 2.0z">\r |
8 | </HEAD> |
9 | |
10 | <!--Copyright (c) 1996 Open Market, Inc. --> |
11 | <!--See the file "LICENSE.TERMS" for information on usage and redistribution--> |
12 | <!--of this file, and for a DISCLAIMER OF ALL WARRANTIES. --> |
13 | <!-- $Id: fastcgi.htm,v 1.1 1997/09/16 15:36:27 stanleyg Exp $ --> |
14 | |
15 | <BODY>\r |
16 | \r |
17 | <P>\r |
18 | Open Market, Inc.</FONT>\r |
19 | <P>\r |
20 | <CENTER><FONT SIZE=4 COLOR=#FFFFFF FACE="Impact">Technical White\r |
21 | Paper<BR>\r |
22 | </FONT></CENTER>\r |
23 | <H1>FastCGI:<BR>\r |
24 | A High-Performance Web Server Interface</H1>\r |
25 | \r |
26 | <P>\r |
27 | April 1996<!--Please send comments to:--></FONT>\r |
28 | <HR>\r |
29 | <!-- payne@openmarket.com-->\r |
30 | <H2>1. Introduction</H2>\r |
31 | \r |
32 | <P>\r |
33 | The surge in the use of the Web by business has created\r |
34 | a tremendous need for server extension applications that create\r |
35 | dynamic content. These are the applications that will allow businesses\r |
36 | to deliver products, services, and messages whose shape and content\r |
37 | are in part determined by the interaction with, and knowledge\r |
38 | of, the customers to which they are delivered.</FONT>\r |
39 | <P>\r |
40 | This important movement away from static Web content\r |
41 | is pushing the limits and exposing the weaknesses of the environment\r |
42 | in which these applications are currently bound: CGI (Common Gateway\r |
43 | Interface). Most importantly it does not offer the performance\r |
44 | these applications require. A new communication infrastructure\r |
45 | is needed to connect Web servers with these new applications.\r |
46 | This is what led Open Market to develop FastCGI.</FONT>\r |
47 | <P>\r |
48 | FastCGI is a fast, open, and secure Web server interface\r |
49 | that solves the performance problems inherent in CGI, without\r |
50 | introducing the overhead and complexity of proprietary APIs (Application\r |
51 | Programming Interfaces). </FONT>\r |
52 | <P>\r |
53 | This paper assumes that the reader has basic familiarity\r |
54 | with Web technology and developing Web applications.</FONT>\r |
55 | <H3>Common Gateway Interface</H3>\r |
56 | \r |
57 | <P>\r |
58 | The de facto standard interface for Web server applications\r |
59 | is CGI, which was first implemented in the NCSA server. CGI has\r |
60 | many benefits: </FONT>\r |
61 | <UL>\r |
62 | <LI><B>Simplicity. </FONT></B><FONT>It is\r |
63 | easy to understand.</FONT>\r |
64 | <LI><B>Language independence.</FONT></B>\r |
65 | CGI applications can be written in nearly any language.</FONT>\r |
66 | <LI><B>Process isolation.</FONT></B>\r |
67 | Since applications run in separate processes, buggy applications\r |
68 | cannot crash the Web server or access the server's private internal\r |
69 | state.</FONT>\r |
70 | <LI><B>Open standard.</FONT></B> Some\r |
71 | form of CGI has been implemented on every Web server.</FONT>\r |
72 | <LI><B>Architecture independence.</FONT></B>\r |
73 | CGI is not tied to any particular server architecture (single\r |
74 | threaded, multi-threaded, etc.).</FONT>\r |
75 | </UL>\r |
76 | \r |
77 | <P>\r |
78 | CGI also has some significant drawbacks. The leading\r |
79 | problem is performance: Since a new process is created for each\r |
80 | request and thrown away when the request is done, efficiency is\r |
81 | poor.</FONT>\r |
82 | <P>\r |
83 | CGI also has limited functionality: It only supports\r |
84 | a simple "responder" role, where the application generates\r |
85 | the response that is returned to the client. CGI programs can't\r |
86 | link into other stages of Web server request processing, such\r |
87 | as authorization and logging.</FONT>\r |
88 | <H3>Server APIs</H3>\r |
89 | \r |
90 | <P>\r |
91 | In response to the performance problems for CGI,\r |
92 | several vendors have developed APIs for their servers. The two\r |
93 | most notable are NSAPI from Netscape and ISAPI from Microsoft.\r |
94 | The freely available Apache server also has an API.</FONT>\r |
95 | <P>\r |
96 | Applications linked into the server API may be significantly\r |
97 | faster than CGI programs. The CGI startup/initialization problem\r |
98 | is improved, because the application runs in the server process\r |
99 | and is persistent across requests. Web server APIs also offer\r |
100 | more functionality than CGI: you can write extensions that perform\r |
101 | access control, get access to the server's log file, and link\r |
102 | in to other stages in the server's request processing.</FONT>\r |
103 | <P>\r |
104 | However, APIs sacrifice all of CGI's benefits. Vendor\r |
105 | APIs have the following problems:</FONT>\r |
106 | <UL>\r |
107 | <LI><B>Complexity.</FONT></B> Vendor\r |
108 | APIs introduce a steep learning curve, with increased implementation\r |
109 | and maintenance costs.</FONT>\r |
110 | <LI><B>Language dependence.</FONT></B>\r |
111 | Applications have to be written in a language supported by the\r |
112 | vendor API (usually C/C++). Perl, the most popular language for\r |
113 | CGI programs, can't be used with any existing vendor API.</FONT>\r |
114 | <LI><B>No process isolation. </FONT></B><FONT>Since\r |
115 | the applications run in the server's address space, buggy applications\r |
116 | can corrupt the core server (or each other). A malicious or buggy\r |
117 | application can compromise server security, and bugs in the core\r |
118 | server can corrupt applications.</FONT>\r |
119 | <LI><B>Proprietary.</FONT></B> Coding\r |
120 | your application to a particular API locks you into a particular\r |
121 | vendor's server.</FONT>\r |
122 | <LI><B>Tie-in to server architecture.</FONT></B>\r |
123 | API applications have to share the same architecture as the server:\r |
124 | If the Web server is multi-threaded, the application has to be\r |
125 | thread-safe. If the Web server has single-threaded processes,\r |
126 | multi-threaded applications don't gain any performance advantage.\r |
127 | Also, when the vendor changes the server's architecture, the\r |
128 | API will usually have to change, and applications will have to\r |
129 | be adapted or rewritten.</FONT>\r |
130 | </UL>\r |
131 | \r |
132 | <H3>FastCGI</H3>\r |
133 | \r |
134 | <P>\r |
135 | The FastCGI interface combines the best aspects of\r |
136 | CGI and vendor APIs. Like CGI, FastCGI applications run in separate,\r |
137 | isolated processes. FastCGI's advantages include:</FONT>\r |
138 | <UL>\r |
139 | <LI><B>Performance.</FONT></B> FastCGI\r |
140 | processes are persistent-they are reused to handle multiple requests.\r |
141 | This solves the CGI performance problem of creating new processes\r |
142 | for each request.</FONT>\r |
143 | <LI><B>Simplicity, with easy migration from CGI.</FONT></B>\r |
144 | The FastCGI application library (described on page 9) simplifies\r |
145 | the migration of existing CGI applications. Applications built\r |
146 | with the application library can also run as CGI programs, for\r |
147 | backward compatibility with old Web servers.</FONT>\r |
148 | <LI><B>Language independence.</FONT></B>\r |
149 | Like CGI, FastCGI applications can be written in any language,\r |
150 | not just languages supported by the vendor API.</FONT>\r |
151 | <LI><B>Process isolation.</FONT></B>\r |
152 | A buggy FastCGI application cannot crash or corrupt the core server\r |
153 | or other applications. A malicious FastCGI application cannot\r |
154 | steal any secrets (such as session keys for encryption) from the\r |
155 | Web server.</FONT>\r |
156 | <LI><B>Non-proprietary.</FONT></B> \r |
157 | FastCGI is supported in all of Open Market's server products,\r |
158 | and support is under development for other Web servers, including\r |
159 | the freely available Apache and NCSA servers, as well as commercial\r |
160 | servers from Microsoft and Netscape.</FONT>\r |
161 | <LI><B>Architecture independence.</FONT></B>\r |
162 | The FastCGI interface is not tied to a particular server architecture.\r |
163 | Any Web server can implement the FastCGI interface. Also, FastCGI\r |
164 | does not impose any architecture on the application: applications\r |
165 | can be single or multi-threaded, regardless of the threading architecture\r |
166 | of the Web server.</FONT>\r |
167 | <LI><B>Support for distributed computing.</FONT></B>\r |
168 | FastCGI provides the ability to run applications remotely, which\r |
169 | is useful for distributing load and managing external Web sites.</FONT>\r |
170 | </UL>\r |
171 | \r |
172 | <P>\r |
173 | The following sections describe the FastCGI interface,\r |
174 | protocol, application library, and support in Open Market's WebServer\r |
175 | products.</FONT>\r |
176 | <H2>2. FastCGI Interface</H2>\r |
177 | \r |
178 | <P>\r |
179 | The functionality provided by the FastCGI interface\r |
180 | is very similar to that provided by CGI. To best understand the\r |
181 | FastCGI protocol, we review the CGI interface here. Basic CGI\r |
182 | request processing proceeds as follows:</FONT>\r |
183 | <OL>\r |
184 | <LI>For each request, the server creates a new process\r |
185 | and the process initializes itself.</FONT>\r |
186 | <LI>The Web server passes the request information\r |
187 | (such as remote host, username, HTTP headers, etc.) to the CGI\r |
188 | program in environment variables.</FONT>\r |
189 | <LI>The Web server sends any client input (such as\r |
190 | user-entered field values from an HTML form) to the CGI program's\r |
191 | standard input.</FONT>\r |
192 | <LI>The CGI program writes any output to be returned\r |
193 | to the client on standard output. Error information written to\r |
194 | standard error is logged by the Web server.</FONT>\r |
195 | <LI>When the CGI process exits, the request is complete.</FONT>\r |
196 | </OL>\r |
197 | \r |
198 | <P>\r |
199 | FastCGI is conceptually very similar to CGI, with\r |
200 | two major differences:</FONT>\r |
201 | <UL>\r |
202 | <LI>FastCGI processes are persistent: after finishing\r |
203 | a request, they wait for a new request instead of exiting.</FONT>\r |
204 | <LI>Instead of using operating system environment\r |
205 | variables and pipes, the FastCGI protocol multiplexes the environment\r |
206 | information, standard input, output and error over a single full-duplex\r |
207 | connection. This allows FastCGI programs to run on remote machines,\r |
208 | using TCP connections between the Web server and the FastCGI application.</FONT>\r |
209 | </UL>\r |
210 | \r |
211 | <P>\r |
212 | Request processing in a single-threaded FastCGI application\r |
213 | proceeds as follows:</FONT>\r |
214 | <OL>\r |
215 | <LI>The Web server creates FastCGI application processes\r |
216 | to handle requests. The processes may be created at startup,\r |
217 | or created on demand.</FONT>\r |
218 | <LI>The FastCGI program initializes itself, and waits\r |
219 | for a new connection from the Web server.</FONT>\r |
220 | <LI>When a client request comes in, the Web server\r |
221 | opens a connection to the FastCGI process. The server sends the\r |
222 | CGI environment variable information and standard input over the\r |
223 | connection.</FONT>\r |
224 | <LI>The FastCGI process sends the standard output\r |
225 | and error information back to the server over the same connection.</FONT>\r |
226 | <LI>When the FastCGI process closes the connection,\r |
227 | the request is complete. The FastCGI process then waits for another\r |
228 | connection from the Web server.</FONT>\r |
229 | </OL>\r |
230 | \r |
231 | <P>\r |
232 | FastCGI applications can run locally (on the same\r |
233 | machine as the Web server) or remotely. For local applications,\r |
234 | the server uses a full-duplex pipe to connect to the FastCGI application\r |
235 | process. For remote applications, the server uses a TCP connection.</FONT>\r |
236 | <P>\r |
237 | FastCGI applications can be single-threaded or multi-threaded.\r |
238 | For single threaded applications, the Web server maintains a\r |
239 | pool of processes (if the application is running locally) to\r |
240 | handle client requests. The size of the pool is user configurable.\r |
241 | Multi-threaded FastCGI applications may accept multiple connections\r |
242 | from the Web server and handle them simultaneously in a single\r |
243 | process. (For example, Java's built-in multi-threading, garbage\r |
244 | collection, synchronization primitives, and platform independence\r |
245 | make it a natural implementation language for multi-threaded FastCGI\r |
246 | applications.)</FONT>\r |
247 | <H3>Remote FastCGI</H3>\r |
248 | \r |
249 | <P>\r |
250 | FastCGI's ability to run applications remotely (over\r |
251 | a TCP connection) provides some major benefits. These benefits\r |
252 | are described in this section, along with some of the security\r |
253 | issues that affect remote FastCGI applications.</FONT>\r |
254 | <H4>FastCGI with Firewalls</H4>\r |
255 | \r |
256 | <P>\r |
257 | Applications that run on organizational (external) Web servers\r |
258 | and depend on internal databases can be a challenge to administer.\r |
259 | Figure 1 shows a typical organization, with an external Web server,\r |
260 | a firewall restricting access to the internal network, and internal\r |
261 | databases and applications.\r |
262 | <P>\r |
263 | <CENTER><IMG SRC="img00001.gif"><A NAME="_Ref352505891">Figure\r |
264 | 1</A></CENTER>\r |
265 | <P>\r |
266 | With CGI and vendor APIs, the application has to run on the Web\r |
267 | server machine. This means the server administrator has to replicate\r |
268 | the necessary database information onto the system hosting the\r |
269 | Web server (which may be difficult to do in an automated way without\r |
270 | compromising firewall security). Or, the administrator may build\r |
271 | a "bridge" that allows access through the Web server\r |
272 | to internal databases and applications (which is effectively re-inventing\r |
273 | remote FastCGI).\r |
274 | <P>\r |
275 | With remote FastCGI, the applications can run on the internal\r |
276 | network, simplifying the administrator's job. When used with\r |
277 | appropriate firewall configuration and auditing, this approach\r |
278 | provides a secure, high-performance, scalable way to bring internal\r |
279 | applications and data to the external network.\r |
280 | <H4>Load Distribution</H4>\r |
281 | \r |
282 | <P>\r |
283 | For resource-intensive CGI and API applications, the Web server\r |
284 | machine quickly becomes the bottleneck for overall throughput.\r |
285 | The usual way to solve this performance problem is to buy a bigger,\r |
286 | faster Web server machine, or to partition the Web site across\r |
287 | several Web servers.\r |
288 | <P>\r |
289 | With remote FastCGI, the resource-intensive applications can be\r |
290 | moved off the Web server machine, giving the server administrator\r |
291 | additional flexibility in configuring the Web server. The administrator\r |
292 | can configure FastCGI applications "behind the scenes"\r |
293 | without having to change any content links or the external view\r |
294 | of the Web site. The administrator can use several smaller, inexpensive\r |
295 | server machines for applications, and can tailor each machine\r |
296 | to the application it is hosting.\r |
297 | <H4>Security Issues with Remote FastCGI</H4>\r |
298 | \r |
299 | <P>\r |
300 | The two security issues with remote FastCGI connections are authentication\r |
301 | and privacy. FastCGI applications should only accept connections\r |
302 | from Web servers that they trust (the application library includes\r |
303 | support for IP address validation). Future versions of the protocol\r |
304 | will include support for applications authenticating Web servers,\r |
305 | as well as support for running remote connections over secure\r |
306 | transport protocols such as SSL or PCT.<!--This pargraph needs to be made stronger, going into the issues in a little more detail.-->\r |
307 | \r |
308 | <H3>The FastCGI Protocol</H3>\r |
309 | \r |
310 | <P>\r |
311 | This section offers a brief introduction to the protocol\r |
312 | used on the connection between the Web server and FastCGI application.\r |
313 | Most application developers will use the FastCGI application\r |
314 | library and won't have to worry about the protocol details. However,\r |
315 | specialized applications are free to implement the FastCGI protocol\r |
316 | directly.</FONT>\r |
317 | <P>\r |
318 | FastCGI uses a simple packet record format on the\r |
319 | connection between the application and the Web server. The same\r |
320 | record format is used in both directions and is outlined in Figure 2.</FONT>\r |
321 | <P>\r |
322 | <CENTER><IMG SRC="img00002.gif"><A NAME="_Ref352404075">Figure\r |
323 | 2</FONT></A></CENTER>\r |
324 | <P>\r |
325 | The protocol version field specifies the version\r |
326 | of the FastCGI protocol that is in use. The type field specifies\r |
327 | the type of the record (described in the following section). \r |
328 | The request ID identifies this record to a particular request,\r |
329 | allowing multiple requests to be multiplexed over a single connection.\r |
330 | The data length field specifies the number of data bytes that\r |
331 | follow.</FONT>\r |
332 | <P>\r |
333 | The different FastCGI packet types are:</FONT>\r |
334 | <TABLE>\r |
335 | \r |
336 | <TR><TD WIDTH=186><TT><FONT FACE="Courier">FCGI_PARAMS</FONT></TT>\r |
337 | </TD><TD WIDTH=228>Used for sending name/value pairs (CGI environment variables) from the Web server to the application.\r |
338 | </TD></TR>\r |
339 | \r |
340 | <TR><TD WIDTH=186><TT><FONT FACE="Courier">FCGI_STDIN</FONT></TT>\r |
341 | </TD><TD WIDTH=228>Used for sending the standard input from the Web server to the application.\r |
342 | </TD></TR>\r |
343 | \r |
344 | <TR><TD WIDTH=186><TT><FONT FACE="Courier">FCGI_DATA</FONT></TT>\r |
345 | </TD><TD WIDTH=228>Used for sending filter data to the application (for more information, see the filter role described on page 7.)\r |
346 | </TD></TR>\r |
347 | \r |
348 | <TR><TD WIDTH=186><TT><FONT FACE="Courier">FCGI_STDOUT</FONT></TT>\r |
349 | </TD><TD WIDTH=228>Used to send standard output from the application to the Web server.\r |
350 | </TD></TR>\r |
351 | \r |
352 | <TR><TD WIDTH=186><TT><FONT FACE="Courier">FCGI_STDERR</FONT></TT>\r |
353 | </TD><TD WIDTH=228>Used to send standard error information from the application to the Web server.\r |
354 | </TD></TR>\r |
355 | \r |
356 | <TR><TD WIDTH=186><TT><FONT FACE="Courier">FCGI_END_REQUEST</FONT></TT>\r |
357 | </TD><TD WIDTH=228>Ends the request (can be sent by either the server or the application).\r |
358 | </TD></TR>\r |
359 | \r |
360 | </TABLE>\r |
361 | \r |
362 | <P>\r |
363 | \r |
364 | <P>\r |
365 | For complete protocol details, see the <I>FastCGI Protocol Specification</I>,\r |
366 | available from the Web site listed at the end of this paper.\r |
367 | <H2>3. Application Roles</H2>\r |
368 | \r |
369 | <P>\r |
370 | A major problem with CGI is its limited functionality:\r |
371 | CGI programs can only provide simple responses to requests. \r |
372 | FastCGI provides expanded functionality with support for three\r |
373 | different application "roles":</FONT>\r |
374 | <UL>\r |
375 | <LI><B>Responder.</FONT></B> This is\r |
376 | the basic FastCGI role, and corresponds to the simple functionality\r |
377 | offered by CGI today.</FONT>\r |
378 | <LI><B>Filter.</FONT></B> The FastCGI\r |
379 | application filters the requested Web server file before sending\r |
380 | it to the client.</FONT>\r |
381 | <LI><B>Authorizer.</FONT></B> The FastCGI\r |
382 | program performs an access control decision for the request (such\r |
383 | as performing a username/password database lookup). </FONT>\r |
384 | </UL>\r |
385 | \r |
386 | <P>\r |
387 | Other roles will be defined in the future. For instance,\r |
388 | a "logger" role would be useful, where the FastCGI program\r |
389 | would receive the server's log entries for real-time processing\r |
390 | and analysis.</FONT>\r |
391 | <P>\r |
392 | The roles are described in more detail in the following\r |
393 | sections.</FONT>\r |
394 | <H3>Responder Role</H3>\r |
395 | \r |
396 | <P>\r |
397 | FastCGI's Responder role is identical to the functionality\r |
398 | provided by CGI today. When a request comes into the server,\r |
399 | the FastCGI program generates the response that's returned to\r |
400 | the client (typically an HTML page).</FONT>\r |
401 | <H3><A NAME="_Ref352404524">Filter Role</A></H3>\r |
402 | \r |
403 | <P>\r |
404 | The Filter role allows a FastCGI application to process\r |
405 | a requested file before it is returned to the client. </FONT>\r |
406 | <P>\r |
407 | Let's assume that the Web server is configured so\r |
408 | that all files with the .</FONT><TT><FONT FACE="Courier">sgml\r |
409 | </FONT></TT>extension are processed by a SGML-to-HTML\r |
410 | FastCGI filter application, and the user accesses the following\r |
411 | URL:</FONT>\r |
412 | <P>\r |
413 | </FONT><TT><FONT FACE="Courier">/document.sgml</FONT></TT>\r |
414 | <P>\r |
415 | After the Web server makes an access control decision\r |
416 | and maps this URL to a content file, it invokes the FastCGI filter\r |
417 | application with this file available as input. The FastCGI program's\r |
418 | HTML output is sent back to the client, just as in the responder\r |
419 | role. The process is outlined in Figure 3.</FONT>\r |
420 | <P>\r |
421 | <CENTER><IMG SRC="img00003.gif"><A NAME="_Ref352560526">Figure\r |
422 | 3</FONT></A></CENTER>\r |
423 | <P>\r |
424 | Filter applications can significantly improve performance\r |
425 | by caching filter results (the server provides the modification\r |
426 | time in the request information so that applications can flush\r |
427 | the cache when the server file has been modified).</FONT>\r |
428 | <P>\r |
429 | The Filter role is useful for:</FONT>\r |
430 | <UL>\r |
431 | <LI>On-the-fly format conversions</FONT>\r |
432 | <LI>Dynamic documents (such as documents with embedded\r |
433 | SQL queries, or dynamic advertisement insertion)</FONT>\r |
434 | <LI>Applying a standard template: headers, footers,\r |
435 | and backgrounds</FONT>\r |
436 | </UL>\r |
437 | \r |
438 | <H3>Authorizer Role</H3>\r |
439 | \r |
440 | <P>\r |
441 | The Authorizer role allows a FastCGI application\r |
442 | to make an access control decision for a request. The FastCGI\r |
443 | application is invoked with all of the request information, just\r |
444 | as in the Responder role. If the authorizer application generates\r |
445 | a "200 OK" HTTP result, the Web server assumes that\r |
446 | access is allowed and proceeds with the request. (The Web server\r |
447 | may process other access checks, including other FastCGI authorizers,\r |
448 | before access is ultimately allowed.) If the application generates\r |
449 | any other response, that response is returned to the client and\r |
450 | the request is ended. The response can be any valid HTTP response,\r |
451 | including "Access Denied" or "Redirect".</FONT>\r |
452 | <P>\r |
453 | The Authorizer role is useful for:</FONT>\r |
454 | <UL>\r |
455 | <LI>Access control based on username and password,\r |
456 | where the user information is looked up in an external database.</FONT>\r |
457 | <LI>Complex access policies, such as time-of-day\r |
458 | based access.</FONT>\r |
459 | <LI>Smart-card challenge/response authentication.</FONT>\r |
460 | <LI>Dynamic redirects, where the user is sent to\r |
461 | different pages based on the request profile. </FONT>\r |
462 | </UL>\r |
463 | \r |
464 | <H2><A NAME="_Ref352251764">4. FastCGI Application Library</A></H2>\r |
465 | \r |
466 | <P>\r |
467 | Open Market has developed a FastCGI application library\r |
468 | that implements the FastCGI protocol (hiding the protocol details\r |
469 | from the developer). This library makes implementing FastCGI programs\r |
470 | as easy as writing CGI applications.</FONT>\r |
471 | <P>\r |
472 | The application library provides a replacement for\r |
473 | the C language standard I/O (stdio) routines, such as </FONT><TT><FONT FACE="Courier">printf()</FONT></TT>\r |
474 | and </FONT><TT><FONT FACE="Courier">gets()</FONT></TT>.\r |
475 | The library converts references to standard input, standard output,\r |
476 | and standard error to the FastCGI protocol. References to other\r |
477 | files "fall through" to the underlying operating system\r |
478 | standard I/O routines.</FONT>\r |
479 | <P>\r |
480 | This approach has several benefits:</FONT>\r |
481 | <UL>\r |
482 | <LI>Developers don't have to learn a new API to develop\r |
483 | FastCGI applications.</FONT>\r |
484 | <LI>Existing CGI programs can be migrated with minimal\r |
485 | source changes (CGI migration is described in more detail in the\r |
486 | following section).</FONT>\r |
487 | <LI>FastCGI interpreters for Perl, Tcl, and other\r |
488 | interpreted languages can be built without modifying the interpreter\r |
489 | source code.</FONT>\r |
490 | </UL>\r |
491 | \r |
492 | <P>\r |
493 | Here's a simple FastCGI application:<P> |
494 | <PRE> |
495 | #include <fcgi_stdio.h> |
496 | |
497 | void main(void) |
498 | { |
499 | int count = 0; |
500 | while(FCGI_Accept() >= 0) { |
501 | printf("Content-type: text/html\r\n"); |
502 | printf("\r\n"); |
503 | printf("Hello world!<br>\r\n"); |
504 | printf("Request number %d.", count++); |
505 | } |
506 | exit(0); |
507 | } |
508 | </PRE> |
509 | This application returns a "Hello world"\r |
510 | HTML response to the client. It also keeps a counter of the number\r |
511 | of times it has been accessed, displaying the value of the counter\r |
512 | at each request.</FONT>\r |
513 | <P>\r |
514 | The <TT>fcgi_stdio.h</TT>\r |
515 | header file provides the FastCGI replacement routines for the\r |
516 | C standard I/O library. The <TT>FCGI_Accept()</TT>\r |
517 | routine accepts a new request from the Web server.</FONT>\r |
518 | <H3>Migrating Existing CGI Programs</H3>\r |
519 | \r |
520 | <P>\r |
521 | The application library was designed to make migration\r |
522 | of existing CGI programs as simple as possible. Many applications\r |
523 | can be converted by adding a loop around the main request processing\r |
524 | code and recompiling with the FastCGI application library. FastCGI\r |
525 | applications have the following structure, with an initialization\r |
526 | section and a request processing loop:<p> |
527 | \r |
528 | <I>Initialize application;<BR>\r |
529 | </I><TT>while(FCGI_Accept() >= 0) {</TT><BR>\r |
530 | <I>Process request</I>;<BR>\r |
531 | <TT>}</TT>\r |
532 | <P>\r |
533 | To ease migration to FastCGI, executables built with\r |
534 | the application library can run as either CGI or FastCGI programs,\r |
535 | depending on how they are invoked. The library detects the execution\r |
536 | environment and automatically selects FastCGI or regular I/O routines,\r |
537 | as appropriate.</FONT>\r |
538 | <P>\r |
539 | After migration, developers can clean up their FastCGI\r |
540 | applications for best performance:</FONT>\r |
541 | <UL>\r |
542 | <LI>Fix any resource leaks. Many CGI programs do\r |
543 | not attempt to manage memory or close files, because they assume\r |
544 | the world is going to be cleaned up when they exit. (If you don't\r |
545 | want to clean up your program, you can just have your process\r |
546 | assume that it is leaking memory and exit after processing some\r |
547 | fixed number of requests.) Purify from Pure Software is one of\r |
548 | a number of excellent tools for finding leaks and other memory\r |
549 | use problems.</FONT>\r |
550 | <LI>Fix any problems with retained application state.\r |
551 | The application must ensure that any state that it creates in\r |
552 | processing one request has no unintended effects on later requests.\r |
553 | </FONT>\r |
554 | <LI>Collapse functionality. A common practice with\r |
555 | CGI applications is to implement many small programs, with one\r |
556 | function per program. CGI encourages this, because smaller programs\r |
557 | load faster. With FastCGI, it's better to have related functionality\r |
558 | in a single executable, so there are fewer processes to manage\r |
559 | and applications can take advantage of sharing cached information\r |
560 | across functions.</FONT>\r |
561 | </UL>\r |
562 | \r |
563 | <P>\r |
564 | Applications written in Perl, Tcl, and other scripting\r |
565 | languages can be migrated by using a language interpreter built\r |
566 | with the application library. FastCGI-integrated Tcl and Perl\r |
567 | interpreters for popular Unix platforms are available from Open\r |
568 | Market. The interpreters are backward-compatible: They can run\r |
569 | standard Tcl and Perl applications. </FONT>\r |
570 | <H2>5. FastCGI in the Open Market WebServer</H2>\r |
571 | \r |
572 | <P>\r |
573 | This section describes the FastCGI support in the\r |
574 | following Open Market server products:</FONT>\r |
575 | <UL>\r |
576 | <LI>Open Market WebServer V2.0</FONT>\r |
577 | <LI>Open Market Secure WebServer V2.0</FONT>\r |
578 | <LI>Open Market Secure WebServer (Global) V2.0</FONT>\r |
579 | </UL>\r |
580 | \r |
581 | <P>\r |
582 | For more information about FastCGI support, see\r |
583 | the <I>Open Market WebServer Installation and Configuration Guide</I>.</FONT>\r |
584 | <H3>Server Configuration</H3>\r |
585 | \r |
586 | <P>\r |
587 | FastCGI applications are configured with the server's\r |
588 | configuration file. Configuration has two parts.</FONT>\r |
589 | <P>\r |
590 | First, the server administrator defines an <I>application\r |
591 | class</I>. For local applications, the application class specifies\r |
592 | the details of running the FastCGI application, such as:</FONT>\r |
593 | <UL>\r |
594 | <LI>The pathname of the application executable.</FONT>\r |
595 | <LI>Any arguments and environment variables to pass\r |
596 | to the process at startup.</FONT>\r |
597 | <LI>The number of processes to run.</FONT>\r |
598 | </UL>\r |
599 | \r |
600 | <P>\r |
601 | For remote applications, the class configuration\r |
602 | information includes the host and TCP port to connect to. The\r |
603 | Web server assumes that the FastCGI application has been started\r |
604 | on the remote host. If a request comes in and the server can't\r |
605 | connect to the FastCGI TCP port, the server logs an error and\r |
606 | returns an error page to the client.</FONT>\r |
607 | <P>\r |
608 | The second configuration step is mapping the application\r |
609 | class to a role:</FONT>\r |
610 | <UL>\r |
611 | <LI>For responder roles, the administrator configures\r |
612 | some part of the URL space to be handled by the FastCGI application.\r |
613 | For example, all URLs beginning with </FONT><FONT FACE="Courier">/rollcall/</FONT>\r |
614 | might be handled by the employee database application.</FONT>\r |
615 | <LI>For filter roles, the administrator configures\r |
616 | a file extension to be handled by a filter application. For example,\r |
617 | all files with the </FONT><FONT FACE="Courier">.sql</FONT>\r |
618 | extension could be handled by a SQL query lookup filter. </FONT>\r |
619 | <LI>For authorizer roles, the administrator configures\r |
620 | an authorizer application in the same manner as other access methods\r |
621 | (hostname, username/password, etc.) A request must pass <I>all\r |
622 | </I>access control checks (possibly including multiple FastCGI\r |
623 | authorizers) before access is allowed. </FONT>\r |
624 | </UL>\r |
625 | \r |
626 | <H3>Basic FastCGI</H3>\r |
627 | \r |
628 | <P>\r |
629 | To simplify migration for existing CGI programs,\r |
630 | the WebServer provides a simple way to install new FastCGI programs\r |
631 | without having to reconfigure the server. However, this approach\r |
632 | doesn't offer all of the performance benefits of FastCGI application\r |
633 | classes.</FONT>\r |
634 | <P>\r |
635 | The WebServer treats any file with the extension\r |
636 | </FONT><FONT FACE="Courier">.fcg</FONT> as\r |
637 | a FastCGI application. When a request corresponds to such a file,\r |
638 | the WebServer creates a new FastCGI process to handle the request,\r |
639 | and shuts down the process when the request is complete (just\r |
640 | as in CGI). In this mode of operation performance is comparable\r |
641 | to CGI. Future versions of the WebServer will improve performance\r |
642 | by automatically caching processes and re-using them for subsequent\r |
643 | requests.</FONT>\r |
644 | <H3>Session Affinity</H3>\r |
645 | \r |
646 | <P>\r |
647 | FastCGI programs can improve performance by caching\r |
648 | information in the application process. For applications that\r |
649 | require frequent but expensive operations such as validating a\r |
650 | username/password in an external database for each request, this\r |
651 | technique can significantly improve performance.</FONT>\r |
652 | <P>\r |
653 | To improve the effectiveness of this technique, the\r |
654 | WebServer implements <I>session affinity</I>. When session affinity\r |
655 | is enabled, the WebServer arranges for all requests in a user\r |
656 | session to be handled by the same FastCGI application process.\r |
657 | What constitutes a "session" is configurable. The\r |
658 | default configuration uses the WebServer's built-in session tracking\r |
659 | facility to identify user sessions. However, the server administrator\r |
660 | can use any part of the request information for the session affinity\r |
661 | mapping: the URL path, the client's hostname, the username, etc.<!--Talk about applications that need to hold onto resources for the user (such as open connections to the database).--></FONT>\r |
662 | \r |
663 | <H2>6. FastCGI Performance Analysis</H2>\r |
664 | \r |
665 | <P>\r |
666 | How fast is FastCGI? The answer depends on the application.\r |
667 | This section contains some real FastCGI performance measurements,\r |
668 | as well as guidelines for estimating the FastCGI speedup. </FONT>\r |
669 | <H3>FastCGI vs CGI</H3>\r |
670 | \r |
671 | <P>\r |
672 | We measured the relative performance of CGI, FastCGI,\r |
673 | and static files on the Open Market WebServer, using a simple\r |
674 | application that generates a fixed number of output bytes. The\r |
675 | following table shows the measured request processing time for\r |
676 | different request types on a typical platform. The times are\r |
677 | measured from the client perspective and include client, server,\r |
678 | and application processing time.</FONT>\r |
679 | <TABLE BORDERCOLOR=#000000 BORDER=2>\r |
680 | \r |
681 | <TR><TD WIDTH=72><CENTER><FONT SIZE=2 FACE="Arial Narrow">Static file</FONT></CENTER>\r |
682 | </TD><TD WIDTH=180><CENTER><FONT SIZE=2 FACE="Arial Narrow">21ms + 0.19ms per Kbyte</FONT></CENTER>\r |
683 | </TD></TR>\r |
684 | \r |
685 | <TR><TD WIDTH=72><CENTER><FONT SIZE=2 FACE="Arial Narrow">FastCGI</FONT></CENTER>\r |
686 | </TD><TD WIDTH=180><CENTER><FONT SIZE=2 FACE="Arial Narrow">22ms + 0.28ms per Kbyte</FONT></CENTER>\r |
687 | </TD></TR>\r |
688 | \r |
689 | <TR><TD WIDTH=72><CENTER><FONT SIZE=2 FACE="Arial Narrow">CGI</FONT></CENTER>\r |
690 | </TD><TD WIDTH=180><CENTER><FONT SIZE=2 FACE="Arial Narrow">59ms + 0.37ms per Kbyte</FONT></CENTER>\r |
691 | </TD></TR>\r |
692 | \r |
693 | </TABLE>\r |
694 | \r |
695 | <P>\r |
696 | FastCGI performance is comparable to serving static files, and\r |
697 | significantly better than CGI (clearly showing the high overhead\r |
698 | for process creation). Real applications have an additional time\r |
699 | component: process initialization, which should be added to overall\r |
700 | request processing time.\r |
701 | <P>\r |
702 | Let's use this data to estimate the speedup from migrating a typical\r |
703 | database CGI application to FastCGI. Assume the application takes\r |
704 | 50ms to initialize the database connection and generates 5K of\r |
705 | output data. Request performance can be computed as follows:\r |
706 | <TABLE>\r |
707 | \r |
708 | <TR><TD WIDTH=108>CGI </TD><TD WIDTH=331>59ms + 50ms + (0.37ms)(5) = 111ms\r |
709 | </TD></TR>\r |
710 | \r |
711 | <TR><TD WIDTH=108>FastCGI</TD><TD WIDTH=331>22ms + (0.28ms)(5) = 23ms\r |
712 | </TD></TR>\r |
713 | \r |
714 | </TABLE>\r |
715 | \r |
716 | <P>\r |
717 | In this example, FastCGI has a 5x performance advantage over CGI,\r |
718 | mostly due to savings from not having to create and initialize\r |
719 | new processes for each request.<!--Need to talk about FastCGI vs proprietary APIs.-->\r |
720 | \r |
721 | <H2>7. Conclusions</H2>\r |
722 | \r |
723 | <P>\r |
724 | Today's Web business applications need a platform\r |
725 | that's fast, open, maintainable, straightforward, stable, and\r |
726 | secure. FastCGI's design meets these requirements, and provides\r |
727 | for a logical extension from proven and widely deployed CGI technology.\r |
728 | This allows developers to take advantage of FastCGI's benefits\r |
729 | without losing their existing investment in CGI applications.<!--Need to talk about NT.--></FONT>\r |
730 | <!--Need to give "more punch" to this conclusion: include info about uses for FastCGI (accessing legacy data in databases, access control, distributed applications, apps that have to run in multiple OS environments. -->\r |
731 | <H2>8. For More Information</H2>\r |
732 | \r |
733 | <P>\r |
734 | For more information about Open Market and our products,\r |
735 | visit our Web site at:</FONT><FONT FACE="Courier">http://www.openmarket.com/</FONT>\r |
736 | <P>\r |
737 | For more information about the FastCGI protocol and\r |
738 | the developer's kit, and the latest information about FastCGI\r |
739 | standardization and support in other Web servers, visit the FastCGI\r |
740 | project page at:</FONT><FONT FACE="Courier">http://www.openmarket.com/fastcgi/</FONT>\r |
741 | </BODY>\r |
742 | \r |
743 | </HTML>\r |