1<?xml version="1.0" encoding="UTF-8"?>
2
3<section id="fastcgi"><title>The &fastcgi-link; Interface</title>
4
5<simpara>
6The &fastcgi-link; module speeds up &clisp; CGI
7scripts launched by a Web server.  Working with a
8&fastcgi-link;-enabled Web server such as &apache; with
9&mod-fastcgi;, a &clisp; program using the &fastcgi-link;
10protocol will run many times faster than a conventional CGI program.
11The performance improvements stem from the fact that the script's
12process remains running across &http; requests, eliminating startup
13overhead and allowing for caching of data structures and other resources.  This
14is the same approach used is in other languages (e.g., <ulink
15url="http://perl.apache.org">mod_perl</ulink> for Perl).  </simpara>
16
17<simpara>When this module is present, &features-my; contains the
18 symbol <constant>:FASTCGI</constant>.</simpara>
19
20<section id="fcgi-overview"><title>Overview of &fastcgi-link;</title>
21
22<para>
23Traditional CGI programs work by doing input/output with the Web
24server via the following channels:
25<orderedlist>
26<listitem><simpara>
27Examining environment variables; e.g., <envar>HTTP_USER_AGENT</envar> is the
28variable set by the Web server to name the browser used
29</simpara></listitem>
30<listitem><simpara>
31Reading from standard input.  E.g., to get input data in a "method=POST" request
32</simpara></listitem>
33<listitem><simpara>
34Writing an &http; response document (usually "Content-type:
35text/html") to the standard output, for eventual transmission
36back to the browser client
37</simpara></listitem>
38<listitem><simpara>
39Writing error messages to the standard error, usually captured
40by the Web server and logged in its log files.
41</simpara></listitem>
42</orderedlist>
43</para>
44
45<simpara>
46&fastcgi-link; involves replacing calls the standard routines to do
47the above with calls in the <quote role="package">FASTCGI</quote> package.  These calls will then
48work exactly as before when the program is invoked as a CGI, but will
49also work when invoked by a &fastcgi-link;-enabled Web server.
50</simpara>
51<simpara>
52&fastcgi-link; programs persist across &http; requests, and thus incur
53startup overhead costs only once.  For Lisp Web programs, this overhead
54can be substantial: code must be
55compiled and loaded, files and databases must be opened, etc.  Further,
56because the program stays running from &http; request to &http; request,
57it can cache information in memory such as database connections
58or large in-memory data structures.
59
60</simpara>
61
62</section>
63
64
65<section id="fcgi-functionality"><title>Functions in Package <quote role="package">FASTCGI</quote></title>
66<para>Access to
67&fastcgi-link; is via these functions in package <quote role="package">FASTCGI</quote>.
68
69<variablelist>
70
71<!-- IS-CGI -->
72<varlistentry><term><code>(FASTCGI:IS-CGI)</code></term>
73<listitem><simpara>
74Returns &t; if the &clisp; program has been launched as a traditional
75CGI rather than in &fastcgi-link;.  In traditional CGI, program I/O is
76via operating system environment variables and standard file streams.
77Under &fastcgi-link;, I/O is done directly with the Web server via
78the &fastcgi-link; protocol.
79</simpara></listitem></varlistentry>
80
81<!-- ACCEPT -->
82<varlistentry><term>
83<code>(FASTCGI:ACCEPT)</code> <replaceable>cgi-forms</replaceable>
84<code>(FASTCGI:FINISH)</code>
85</term>
86<listitem>
87<simpara>
88In &fastcgi-link; mode, the program loops,
89<function>ACCEPT</function>ing to begin the execution of an &http;
90request, and <function>FINISH</function>ing to signal that the script
91is finished writing its response to the &http; request.  <function>ACCEPT</function>
92blocks until the next &http; request comes in, returning &t; if there is
93a new request to handle, and &nil; if no more &http; requests will
94occur, usually because the Web server itself has terminated, in which
95case the &fastcgi-link; server loop should also exit.
96</simpara>
97<para>
98A typical &fastcgi-link; top-level server loop looks like:
99<programlisting language="lisp">
100(do ()
101    ((not (fastcgi:accept)))
102  (run-my-script)
103  (fastcgi:finish))
104</programlisting>
105
106</para></listitem></varlistentry>
107
108<!-- GETENV -->
109<varlistentry><term><code>(FASTCGI:GETENV
110<replaceable>varname</replaceable>)</code></term>
111<listitem><simpara>
112Use in place of &getenv; to get the value of the environment variable
113named <replaceable>varname</replaceable>, which should be a string.
114Unlike &getenv;, which accesses the actual host operating system environment,
115<function>FASTCGI:GETENV</function> obtains its environment via
116the Web server, over its FastCGI communications channel.
117For more information, see the &fastcgi-link; Web site.
118Returns &nil; if <replaceable>varname</replaceable> is not defined in
119the operating system environment.  See <ulink
120url="http://www.cgi101.com/class/ch3/text.html">here</ulink> for a
121list of useful variables.  You must first have called
122<function>ACCEPT</function> and not yet have called
123<function>FINISH</function>.  </simpara></listitem></varlistentry>
124
125<!-- WRITE-STDOUT -->
126<varlistentry><term><code>(FASTCGI:WRITE-STDOUT
127&string-r;)</code></term>
128<listitem><simpara>
129Use in place of standard Lisp calls which print to standard output
130(i.e., as part of the &http; response).
131You must first have called <function>ACCEPT</function> and not yet have
132called <function>FINISH</function>.
133</simpara></listitem></varlistentry>
134
135<!-- WRITE-STDERR -->
136<varlistentry><term><code>(FASTCGI:WRITE-STDERR
137&string-r;)</code></term>
138<listitem><simpara>
139Use in place of standard Lisp calls which print to
140standard error. Rather than being part of
141the &http; response, data written to standard error are usually
142collected by the Web server in its error log.  This is useful
143for diagnostic purposes.
144</simpara></listitem></varlistentry>
145
146<!-- SLURP-STDIN -->
147<varlistentry><term><code>(FASTCGI:SLURP-STDIN)</code></term>
148<listitem><simpara>
149Reads in the entirety of standard input and returns it as a string.
150This is usually done for &http; requests with
151<literal>METHOD="post"</literal>, when the data are passed to the CGI
152script via standard input rather than via the environment variable
153<envar>QUERY_STRING</envar>.  There is no way to read standard input
154in pieces, which could be a problem, say, for &http; uploads of very large files.
155</simpara></listitem></varlistentry>
156
157<!-- OUT -->
158<varlistentry><term><code>(FASTCGI:OUT
159<replaceable>tree</replaceable>)</code></term>
160<listitem><simpara>
161Like <function>WRITE-STDOUT</function>, except that
162<replaceable>tree</replaceable>
163may be an arbitrarily nested list structure containing (at the leaves)
164numbers and strings.  For example,
165<literal>(FASTCGI:OUT '("foo" (" " 10 " " 20)))</literal>
166will write the string <literal>"foo 10 20"</literal>.  This function
167is useful when building strings in memory for display.
168</simpara></listitem></varlistentry>
169
170</variablelist>
171
172</para>
173
174</section>
175
176<section id="fcgi-example"><title>&fastcgi-link; Example</title>
177
178<para>
179
180Below is a simple example CGI script using &fastcgi-link;.
181
182<programlisting language="lisp">
183#!/usr/local/bin/clisp -q -K full
184
185(do ((count 1 (1+ count)))
186    ((not (fastcgi:accept)) nil)
187  (fastcgi:out "Content-type: text/plain" #\Newline #\Newline)
188  (fastcgi:out
189   "I am running in mode: " (if (fastcgi:is-cgi) "CGI" "FastCGI") #\Newline
190   "This is execution no.: " count #\Newline
191   "The browser string is '" (fastcgi:getenv "HTTP_USER_AGENT") "'" #\Newline)
192  (fastcgi:finish))
193</programlisting>
194
195</para>
196</section>
197
198<section id="fcgi-build"><title>Building and configuring the
199  &fastcgi-link; Interface</title>
200<para>
201It is necessary to download the &fastcgi-link; developers' kit, build it,
202and install it, before building &clisp; with &fastcgi-link; support.
203You also need to upgrade your Web server to speak the &fastcgi-link;
204protocol.  For &apache; this means building in &mod-fastcgi;, either statically
205or dynamically, and then adding a line to your &apache; config like:
206<programlisting language="apache">
207     Addhandler fastcgi-script .fcgi
208</programlisting>
209After that, you can convert <filename>foo.cgi</filename> by linking it
210to a script names <filename>foo.fcgi</filename>.  Since a &fastcgi-link;
211script is also a valid CGI script, it can be run unmodified in either
212mode.
213</para>
214
215</section>
216
217
218</section>
219