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