Put handler-case for usocket:connection-aborted-error around the right
[hunchentoot.git] / doc / index.xml
blob98853b71cab38f4d9e49d0e8473096b6ca51d66c
1 <?xml version="1.0" encoding="ISO-8859-1"?>\r
2 <?xml-stylesheet type="text/xsl" href="clixdoc.xsl" ?>\r
3 \r
4   <clix:documentation xmlns='http://www.w3.org/1999/xhtml' xmlns:clix='http://bknr.net/clixdoc'>\r
5     <clix:title>HUNCHENTOOT - The Common Lisp web server formerly known as TBNL</clix:title>\r
6   <clix:short-description>\r
7     A fully-featured web server written in Common Lisp offering things\r
8     like HTTP/1.1 chunking, persistent connections, and SSL.  Includes\r
9     a framework for building dynamic websites interactively.\r
10   </clix:short-description>\r
12   <h2>\r
13     <a href="http://www.htg1.de/hunchentoot/hunchentoot.html"\r
14        title="Click here for the Hunchentoot logo"\r
15        class="noborder">\r
16       <img align="top" width="93" height="45" border="0" src="hunchentoot.gif" />\r
17     </a>\r
18     HUNCHENTOOT - The Common Lisp web server formerly known as TBNL\r
19   </h2>\r
20     <blockquote>\r
21       <clix:chapter name='abstract' title='Abstract'>\r
23     <p>\r
24       Hunchentoot is a web server written in Common Lisp and at the\r
25       same time a toolkit for building dynamic websites.  As a\r
26       stand-alone web server, Hunchentoot is capable of HTTP/1.1\r
27       chunking (both directions), persistent connections\r
28       (keep-alive), and SSL.\r
29     </p>\r
30     <p>\r
31       Hunchentoot provides facilities like automatic session\r
32       handling (with and without cookies), logging, customizable\r
33       error handling, and easy access to GET and POST parameters\r
34       sent by the client. It does <em>not</em> include functionality\r
35       to programmatically generate HTML output. For this task you\r
36       can use any library you like, e.g. (shameless self-plug)\r
37       <a href="http://weitz.de/cl-who/">CL-WHO</a> or\r
38       <a href="http://weitz.de/html-template/">HTML-TEMPLATE</a>.\r
39     </p>\r
40     <p>\r
41       Hunchentoot talks with its front-end or with the client over\r
42       TCP/IP sockets and optionally uses multiprocessing to handle\r
43       several requests at the same time.  Therefore, it cannot be\r
44       implemented completely in\r
45       <a href="http://www.lispworks.com/documentation/HyperSpec/Front/index.htm">portable\r
46         Common Lisp</a>.  It currently works "natively" with \r
47       <a href="http://www.lispworks.com/">LispWorks</a> (which is the\r
48       main development and testing platform), and additionally on all\r
49       Lisps which are supported by the compatibility\r
50       layers <a href="http://common-lisp.net/project/usocket/">usocket</a>\r
51       and <a href="http://common-lisp.net/project/bordeaux-threads/">Bordeaux\r
52       Threads</a>.\r
53     </p>\r
54     <p>\r
55       Hunchentoot comes with a \r
56       <a href="http://www.opensource.org/licenses/bsd-license.php">BSD-style\r
57         license</a> so you can basically do with it whatever you want.\r
58     </p>\r
59     <p>\r
60       Hunchentoot is for example used by \r
61       <a href="http://www.thoughtcrime.us/tp/">Trip Planner</a>, \r
62       <a href="http://clutu.com/">clutu</a>, \r
63       <a href="http://twitterbuzz.com/">TwitterBuzz</a>, \r
64       <a href="http://www.jalat.com/">Jalat</a>, \r
65       <a href="http://heikestephan.de/">Heike Stephan</a>, \r
66       <a href="http://www.memetrics.com/">xOs</a>, and \r
67       <a href="http://syseng.nist.gov/moss">the</a> \r
68       <a href="http://syseng.nist.gov/se-interop">NIST</a>.\r
69     </p>\r
70     <p>\r
71       <font color="red">Download shortcut:</font>\r
72       <a href="http://weitz.de/files/hunchentoot.tar.gz">http://weitz.de/files/hunchentoot.tar.gz</a>.\r
73     </p>\r
74       </clix:chapter>\r
75     </blockquote>\r
76     <clix:chapter name='contents' title='Contents'></clix:chapter>\r
77     <clix:contents></clix:contents>\r
78   <clix:chapter name="install" title="Download and installation">\r
80     Hunchentoot depends on a couple of other Lisp libraries which you'll need\r
81     to install first:\r
82     <ul>\r
83       <li>Pierre R. Mai's <a href="http://www.cliki.net/md5">MD5</a>,</li>\r
84       <li>Kevin Rosenberg's <a href="http://www.cliki.net/cl-base64">CL-BASE64</a>,</li>\r
85       <li>Janis Dzerins' <a href="http://common-lisp.net/project/rfc2388/">RFC2388</a>,</li>\r
86       <li>Peter Seibel's <a href="http://weitz.de/cl-fad/">CL-FAD</a>,</li>\r
87       <li>Erik Huelsmann's <a href="http://common-lisp.net/project/usocket">usocket</a> (unless you're using LispWorks),</li>\r
88       <li>Greg Pfeil's <a href="http://common-lisp.net/project/bordeaux-threads/">Bordeaux\r
89           Threads</a> (unless you're using LispWorks),\r
90       </li>\r
91       <li>\r
92         David Lichteblau's <a href="http://common-lisp.net/project/cl-plus-ssl/">CL+SSL</a>\r
93         (unless you're using LispWorks),\r
94       </li>\r
95       <li>\r
96         and my own <a href="http://weitz.de/flexi-streams/">FLEXI-STREAMS</a> (0.12.0 or higher),\r
97         <a href="http://weitz.de/chunga/">Chunga</a> (1.0.0 or\r
98           higher), and <a href="http://weitz.de/cl-ppcre/">\r
99           CL-PPCRE</a> (plus\r
100         <a href="http://weitz.de/cl-who/">CL-WHO</a> for the <a href="#start">example code</a> and <a href="http://weitz.de/drakma/">Drakma</a> for the <a href="#testing">tests</a>.). \r
101       </li>\r
102     </ul>\r
104     Make sure to use the <em>newest</em> versions of all of these\r
105     libraries (which might themselves depend on other libraries) - try\r
106     the repository versions if you're in doubt.  Note: You can compile\r
107     Hunchentoot without SSL support - and thus without the need to\r
108     have CL+SSL - if you add\r
109     <code>:HUNCHENTOOT-NO-SSL</code> to\r
110     <a href="http://www.lispworks.com/documentation/HyperSpec/Body/v_featur.htm">\r
111       <code>*FEATURES*</code></a> <em>before</em> you compile it.\r
112     <p>\r
113       Hunchentoot will only work with Lisps where\r
114       the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#character_code">character\r
115       codes</a> of\r
116       all <a href="http://en.wikipedia.org/wiki/ISO_8859-1">Latin-1</a>\r
117       characters coincide with their\r
118       Unicode <a href="http://en.wikipedia.org/wiki/Code_point">code\r
119       points</a> (which is the case for all current implementations I\r
120       know).\r
121     </p>\r
122     <p>\r
123       Hunchentoot itself together with this documentation can be\r
124       downloaded from\r
125       <a href="http://weitz.de/files/hunchentoot.tar.gz">http://weitz.de/files/hunchentoot.tar.gz</a>.\r
126       The current version is 1.0.0.\r
127     </p>\r
128     <p>\r
129       The preferred method to compile and load Hunchentoot is via\r
130       <a href="http://www.cliki.net/asdf">ASDF</a>.  If you think that\r
131       it's too much work to find and download all the libraries\r
132       mentioned above, try something like\r
133       <a href="http://common-lisp.net/project/asdf-install/">ASDF-INSTALL</a>,\r
134       <a href="http://common-lisp.net/project/clbuild/">clbuild</a>,\r
135       or my own <a href="http://weitz.de/starter-pack/">Starter\r
136         Pack</a>.  There's also a port for\r
137       <a href="http://www.gentoo.org/proj/en/common-lisp/index.xml">Gentoo\r
138         Linux</a> thanks to Matthew Kennedy.\r
139     </p>\r
140     <p>\r
141       A <a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a>\r
142       repository of older versions is available at\r
143       <a href="http://arcanes.fr.eu.org/~pierre/2007/02/weitz/">http://arcanes.fr.eu.org/~pierre/2007/02/weitz/</a>\r
144       thanks to Pierre Thierry.\r
145     </p>\r
146     <p>\r
147       Luís Oliveira maintains a <a href="http://darcs.net/">darcs</a>\r
148       repository of Hunchentoot at\r
149       <a href="http://common-lisp.net/~loliveira/ediware/">http://common-lisp.net/~loliveira/ediware/</a>.\r
150     </p>\r
152     <clix:subchapter name="proxy" title="Hunchentoot behind a proxy">\r
154       If you're feeling unsecure about exposing Hunchentoot to the wild,\r
155       wild Internet or if your Lisp web application is part of a larger\r
156       website, you can hide it behind a\r
157       <a href="http://en.wikipedia.org/wiki/Proxy_server">proxy server</a>.\r
158       One approach that I have used several times is to employ Apache's\r
159       <a href="http://httpd.apache.org/docs/2.0/mod/mod_proxy.html">mod_proxy</a>\r
160       module with a configuration that looks like this:\r
162 <pre><a href="http://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypass" class="noborder">ProxyPass</a> /hunchentoot http://127.0.0.1:3000/hunchentoot\r
163 <a href="http://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypassreverse" class="noborder">ProxyPassReverse</a> /hunchentoot http://127.0.0.1:3000/hunchentoot</pre>\r
165       This will tunnel all requests where the URI path begins with\r
166       <code>"/hunchentoot"</code> to a (Hunchentoot) server listening on\r
167       port 3000 on the same machine.\r
169       <p>\r
170         Of course, there are\r
171         <a href="http://www.red-bean.com/pipermail/lispweb/2006-October/001342.html">several\r
172           other</a> (more lightweight) web proxies that you could use\r
173         instead of Apache.\r
174       </p>\r
175     </clix:subchapter>\r
176   </clix:chapter>\r
178   <clix:chapter name="mail" title="Support and mailing lists">\r
180     For questions, bug reports, feature requests, improvements, or\r
181     patches please use the\r
182     <a href="http://common-lisp.net/mailman/listinfo/tbnl-devel">tbnl-devel\r
183       mailing list</a>. If you want to be notified about future\r
184     releases subscribe to the\r
185     <a href="http://common-lisp.net/mailman/listinfo/tbnl-announce">tbnl-announce\r
186       mailing list</a>. These mailing lists were made available thanks\r
187     to the services of\r
188     <a href="http://common-lisp.net/">common-lisp.net</a>.  You can\r
189     <b>search</b> the devel mailing list\r
190     <a href="http://google.com/coop/cse?cx=002927904911724867201%3A0l5rif_cxj0">here</a>\r
191     (thanks to Tiarnán Ó Corráin).\r
192     <p>\r
193       If you want to send patches, please\r
194       <a href="http://weitz.de/patches.html">read this first</a>.\r
195     </p>\r
196   </clix:chapter>\r
198   <clix:chapter name="start" title="Your own webserver (the easy teen-age New York version)">\r
199     Starting your own web server is pretty easy.  Do something like this:\r
200 <pre>(hunchentoot:<a class="noborder" href="#start">start</a> (make-instance 'hunchentoot:<a class="noborder" href="#acceptor">acceptor</a> :port 4242))</pre>\r
201     That's it.  Now you should be able to enter the address\r
202     "<a href='http://127.0.0.1:4242/'><code>http://127.0.0.1:4242/</code></a>" in\r
203     your browser and see something, albeit nothing very interesting\r
204     for now.\r
206     <p>\r
207       Now be a bit more adventurous, try this\r
208 <pre>(hunchentoot:<a class="noborder" href="#define-easy-handler">define-easy-handler</a> (say-yo :uri "/yo") (name)\r
209   (setf (hunchentoot:<a class="noborder" href="#content-type*">content-type*</a>) "text/plain")\r
210   (format nil "Hey~@[ ~A~]!" name))</pre>\r
211       and see what happens at "<a href='http://127.0.0.1:4242/yo'><code>http://127.0.0.1:4242/yo</code></a>" or\r
212       "<a href='http://127.0.0.1:4242/yo?name=Dude'><code>http://127.0.0.1:4242/yo?name=Dude</code></a>" .\r
214     </p>\r
216     <p>\r
217     Hunchentoot comes with a little example website which you can use\r
218     to see if it works and which should also demonstrate a couple of\r
219     the things you can do with Hunchentoot.  To start the example\r
220     website, enter the following code into your listener:\r
222 <pre>(<a class="noborder" href="http://common-lisp.net/~mmommer/asdf-howto.shtml#sec11">asdf:oos</a> 'asdf:load-op :hunchentoot-test)</pre>\r
224     Now go to "<a href='http://127.0.0.1:4242/hunchentoot/test'><code>http://127.0.0.1:4242/hunchentoot/test</code></a>" and play a bit.\r
225     </p>\r
226   </clix:chapter>\r
228   <clix:chapter name="tutorials" title="Tutorials and add-ons">\r
230     <p>\r
231       Here are some Hunchentoot tutorials done by others:\r
232     </p>\r
233     <ul>\r
234       <li>\r
235         <a href="http://www.adampetersen.se/articles/lispweb.htm">"Lisp for the Web"</a> by Adam Petersen.\r
236       </li>\r
237       <li>\r
238         Two <a href="http://myblog.rsynnott.com/2007/09/getting-started-with-hunchento.html">getting</a>\r
239         <a href="http://myblog.rsynnott.com/2007/10/doing-more-with-hunchentoot-cl-server.html">started</a>\r
240         articles by Robert Synnott.\r
241       </li>\r
242       <li>\r
243         <a href="http://www.newartisans.com/blog_files/common.lisp.with.apache.php">Running Common Lisp\r
244           behind Apache</a> by John Wiegley.  (And there's a\r
245         <a href="http://www.newartisans.com/blog_files/hunchentoot.primer.php">second part</a>.)\r
246       </li>\r
247       <li>\r
248         A <a href="http://www.lispcast.com/index.php/2007/10/lispcast-writing-a-simple-reddit-clone-in-common-lisp/">"LispCast"</a>\r
249         by Eric Normand about writing a <a href="http://reddit.com/">Reddit</a> clone using\r
250         Hunchentoot.  Apparently the first part of a\r
251         <a href="http://bc.tech.coop/blog/071028.html">series</a>.\r
252       </li>\r
253       <li>\r
254         A <a href="http://roeim.net/vetle/docs/cl-webapp-intro/">tutorial</a> about\r
255         implementing a blog in Common Lisp by Vetle Roeim.\r
256       </li>\r
257       <li>\r
258         A <a href="http://www.jalat.com/blogs/lisp?id=3">tutorial</a> for (an older version of)\r
259         Hunchentoot by Asbjørn Bjørnstad.\r
260       </li>\r
261       <li>\r
262         A <a href="http://www.frank-buss.de/lisp/tbnl.html">TBNL tutorial</a> from Frank Buss.\r
263         (Hunchentoot is not <a href="http://weitz.de/tbnl/">TBNL</a>, but the two are similar enough\r
264         to make the tutorial worthwhile.)\r
265       </li>\r
266       <li>\r
267         For Win32, Bill\r
268         Clementson <a href="http://bc.tech.coop/blog/041105.html">explains</a>\r
269         how to set up Hunchentoot's\r
270         predecessor <a href="http://weitz.de/tbnl/">TBNL</a> with\r
271         Apache/mod_lisp.  See\r
272         also <a href="http://bc.tech.coop/blog/061013.html">http://bc.tech.coop/blog/061013.html</a>.\r
273       </li>\r
274     </ul>\r
276     Check the dates of these tutorials!  Many of them might not be a\r
277     perfect fit with the latest release of Hunchentoot as there have\r
278     been several changes to its API recently, especially in 2009.\r
279     Also, the fact that these tutorials are listed here doesn't\r
280     necessarily mean that I endorse them or think that they show\r
281     idiomatic Lisp code.  You'll have to decide yourself if they're\r
282     helpful to you or not.\r
284     <p>\r
285       Here is some software which extends Hunchentoot or is based on it:\r
286     </p>\r
287     <ul>\r
288       <li>\r
289         <a href="http://common-lisp.net/project/cl-weblocks/">Weblocks</a>\r
290         by Slava Akhmechet is a "continuations-based web framework" which is\r
291         based on Hunchentoot.\r
292       </li>\r
293       <li>\r
294         <a href="http://pen.two-bytes.com/misc/ht-ajax.html">HT-AJAX</a> is\r
295         an <a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29">Ajax</a>\r
296         framework for Hunchentoot by Ury Marshak.\r
297       </li>\r
298       <li>\r
299         Mac Chan\r
300         <a href="http://common-lisp.net/pipermail/tbnl-devel/2007-May/001324.html">has\r
301           ported <a href="http://lemonodor.com/">John Wiseman</a>'s\r
302           <a href="http://www.lemonodor.com/archives/000128.html">Lisp\r
303             Server Pages</a> to Hunchentoot.</a>\r
304       </li>\r
305       <li>\r
306         <a href="http://site.znain.com/dl/lisp/hunchentoot-dir-lister/">hunchentoot-dir-lister</a>\r
307         is a directory listing addition for Hunchentoot by Dimitre Liotev.\r
308       </li>\r
309       <li>\r
310         Cyrus Harmon's\r
311         <a href="http://cyrusharmon.org/blog/display?id=64">nuclblog</a> is a\r
312         <a href="http://en.wikipedia.org/wiki/Blog">blog</a> engine which uses Hunchentoot.\r
313       </li>\r
314       <li>\r
315         <a href="http://cyrusharmon.org/projects?project=hunchentoot-cgi">hunchentoot-cgi</a>\r
316         (also by Cyrus Harmon) provides\r
317         <a href="http://en.wikipedia.org/wiki/Common_Gateway_Interface">CGI</a>\r
318         handlers for Hunchentoot.\r
319       </li>\r
320       <li>\r
321         <a href="http://weitz.de/cl-webdav/">CL-WEBDAV</a> is a <a href="http://webdav.org/">WebDAV</a>\r
322         server based on Hunchentoot.\r
323       </li>\r
324     </ul>\r
325   </clix:chapter>\r
327   <clix:chapter name="reference" title="Function and variable reference">\r
329     <clix:subchapter name="acceptors" title="Acceptors">\r
331       If you want Hunchentoot to actually do something, you have to create and\r
332       <a href="#start">start</a> an <a href="#acceptor">acceptor</a>.\r
333       You can also run several acceptors in one image, each one\r
334       listening on a different different port.\r
336   <clix:class name='acceptor'>\r
337     <clix:description>To create a Hunchentoot webserver, you make an\r
338 instance of this class and use the generic function <clix:ref>START</clix:ref> to start it\r
339 (and <clix:ref>STOP</clix:ref> to stop it).  Use the <code>:port</code> initarg if you don&#039;t want to\r
340 listen on the default http port 80.  There are other initargs most of\r
341 which you probably won&#039;t need very often.  They are explained in\r
342 detail in the docstrings of the slot definitions for this class.\r
343 <p>\r
344 Unless you are in a Lisp without MP capabilities, you can have several\r
345 active instances of <clix:ref>ACCEPTOR</clix:ref> (listening on different ports) at the\r
346 same time.</p>\r
347     </clix:description>\r
348   </clix:class>\r
350   <clix:class name='ssl-acceptor'>\r
351     <clix:description>Create and <clix:ref>START</clix:ref> an instance of this class\r
352 (instead of <clix:ref>ACCEPTOR</clix:ref>) if you want an https server.  There are two\r
353 required initargs, <code>:SSL-CERTIFICATE-FILE</code> and <code>:SSL-PRIVATEKEY-FILE</code>, for\r
354 pathname designators denoting the certificate file and the key file in\r
355 PEM format.  On LispWorks, you can have both in one file in which case\r
356 the second initarg is optional.  You can also use the\r
357 <code>:SSL-PRIVATEKEY-PASSWORD</code> initarg to provide a password\r
358 (as a string) for the key file (or <code>NIL</code>, the default, for\r
359 no password).\r
360 <p>\r
361 The default port for <clix:ref>SSL-ACCEPTOR</clix:ref> instances is 443 instead of 80\r
362 </p>\r
363     </clix:description>\r
364   </clix:class>\r
366   <clix:function generic='true' name='start'>\r
367   <clix:lambda-list>acceptor\r
368   </clix:lambda-list>\r
369   <clix:returns>acceptor\r
370   </clix:returns>\r
371     <clix:description>Starts <clix:arg>acceptor</clix:arg> so that it begins accepting\r
372 connections.  Returns the acceptor.\r
373     </clix:description>\r
374   </clix:function>\r
376   <clix:function generic='true' name='stop'>\r
377   <clix:lambda-list>acceptor\r
378   </clix:lambda-list>\r
379   <clix:returns>acceptor\r
380   </clix:returns>\r
381     <clix:description>Stops <clix:arg>acceptor</clix:arg> so that it\r
382 no longer accepts requests.\r
383     </clix:description>\r
384   </clix:function>\r
386   <clix:special-variable name='*acceptor*'>\r
387     <clix:description>The current ACCEPTOR object in the context of a request.\r
388     </clix:description>\r
389   </clix:special-variable>\r
391   <clix:readers generic='true'>\r
392     <clix:listed-reader generic='true' name='acceptor-address'>\r
393     <clix:lambda-list>acceptor\r
394     </clix:lambda-list>\r
395     <clix:returns>address\r
396     </clix:returns>\r
397     </clix:listed-reader>\r
399     <clix:listed-reader generic='true' name='acceptor-port'>\r
400     <clix:lambda-list>acceptor\r
401     </clix:lambda-list>\r
402     <clix:returns>port\r
403     </clix:returns>\r
404     </clix:listed-reader>\r
406     <clix:listed-reader generic='true' name='acceptor-read-timeout'>\r
407     <clix:lambda-list>acceptor\r
408     </clix:lambda-list>\r
409     <clix:returns>read-timeout\r
410     </clix:returns>\r
411     </clix:listed-reader>\r
413     <clix:listed-reader generic='true' name='acceptor-ssl-certificate-file'>\r
414     <clix:lambda-list>ssl-acceptor\r
415     </clix:lambda-list>\r
416     <clix:returns>ssl-certificate-file\r
417     </clix:returns>\r
418     </clix:listed-reader>\r
420     <clix:listed-reader generic='true' name='acceptor-ssl-privatekey-file'>\r
421     <clix:lambda-list>ssl-acceptor\r
422     </clix:lambda-list>\r
423     <clix:returns>ssl-privatekey-file\r
424     </clix:returns>\r
425     </clix:listed-reader>\r
427     <clix:listed-reader generic='true' name='acceptor-ssl-privatekey-password'>\r
428     <clix:lambda-list>ssl-acceptor\r
429     </clix:lambda-list>\r
430     <clix:returns>ssl-privatekey-password\r
431     </clix:returns>\r
432     </clix:listed-reader>\r
434     <clix:listed-reader generic='true' name='acceptor-write-timeout'>\r
435     <clix:lambda-list>acceptor\r
436     </clix:lambda-list>\r
437     <clix:returns>write-timeout\r
438     </clix:returns>\r
439     </clix:listed-reader>\r
441     <clix:description>\r
442 These are readers for various slots of <clix:ref>ACCEPTOR</clix:ref>\r
443 objects (and some of them obviously only make sense\r
444 for <clix:ref>SSL-ACCEPTOR</clix:ref> objects).  See the docstrings of\r
445 these slots for more information and note that there are corresponding\r
446 initargs for all of them.\r
447     </clix:description>\r
448   </clix:readers>\r
450   <clix:accessors generic='true'>\r
451     <clix:listed-accessor generic='true' name='acceptor-access-logger'>\r
452     <clix:lambda-list>acceptor\r
453     </clix:lambda-list>\r
454     <clix:returns>access-logger\r
455     </clix:returns>\r
456     </clix:listed-accessor>\r
458     <clix:listed-accessor generic='true' name='acceptor-request-dispatcher'>\r
459     <clix:lambda-list>acceptor\r
460     </clix:lambda-list>\r
461     <clix:returns>request-dispatcher\r
462     </clix:returns>\r
463     </clix:listed-accessor>\r
465     <clix:listed-accessor generic='true' name='acceptor-input-chunking-p'>\r
466     <clix:lambda-list>acceptor\r
467     </clix:lambda-list>\r
468     <clix:returns>input-chunking-p\r
469     </clix:returns>\r
470     </clix:listed-accessor>\r
472     <clix:listed-accessor generic='true' name='acceptor-message-logger'>\r
473     <clix:lambda-list>acceptor\r
474     </clix:lambda-list>\r
475     <clix:returns>message-logger\r
476     </clix:returns>\r
477     </clix:listed-accessor>\r
479     <clix:listed-accessor generic='true' name='acceptor-name'>\r
480     <clix:lambda-list>acceptor\r
481     </clix:lambda-list>\r
482     <clix:returns>name\r
483     </clix:returns>\r
484     </clix:listed-accessor>\r
486     <clix:listed-accessor generic='true' name='acceptor-output-chunking-p'>\r
487     <clix:lambda-list>acceptor\r
488     </clix:lambda-list>\r
489     <clix:returns>output-chunking-p\r
490     </clix:returns>\r
491     </clix:listed-accessor>\r
493     <clix:listed-accessor generic='true' name='acceptor-persistent-connections-p'>\r
494     <clix:lambda-list>acceptor\r
495     </clix:lambda-list>\r
496     <clix:returns>persistent-connections-p\r
497     </clix:returns>\r
498     </clix:listed-accessor>\r
500     <clix:listed-accessor generic='true' name='acceptor-reply-class'>\r
501     <clix:lambda-list>acceptor\r
502     </clix:lambda-list>\r
503     <clix:returns>reply-class\r
504     </clix:returns>\r
505     </clix:listed-accessor>\r
507     <clix:listed-accessor generic='true' name='acceptor-request-class'>\r
508     <clix:lambda-list>acceptor\r
509     </clix:lambda-list>\r
510     <clix:returns>request-class\r
511     </clix:returns>\r
512     </clix:listed-accessor>\r
514     <clix:description>\r
515 These are accessors for various slots of <clix:ref>ACCEPTOR</clix:ref>\r
516 objects.  See the docstrings of these slots for more information and\r
517 note that there are corresponding initargs for all of them.\r
518     </clix:description>\r
519   </clix:accessors>\r
521   <clix:function generic='true' name='acceptor-ssl-p'>\r
522   <clix:lambda-list>acceptor\r
523   </clix:lambda-list>\r
524   <clix:returns>generalized-boolean\r
525   </clix:returns>\r
526     <clix:description>Returns a true value if <clix:arg>acceptor</clix:arg> uses SSL\r
527 connections.  The default is to unconditionally return <code>NIL</code> and\r
528 subclasses of <clix:ref>ACCEPTOR</clix:ref> must specialize this method to signal that\r
529 they&#039;re using secure connections - see the <clix:ref>SSL-ACCEPTOR</clix:ref> class.\r
530     </clix:description>\r
531   </clix:function>\r
533   <clix:special-variable name='*default-connection-timeout*'>\r
534     <clix:description>The default connection timeout used when an\r
535 acceptor is reading from and writing to a socket stream.  Note that\r
536 some Lisps allow you to set different timeouts for reading and writing\r
537 and you can specify both values via initargs when you create\r
538 an <a href="#acceptors">acceptor</a>.\r
539     </clix:description>\r
540   </clix:special-variable>\r
542     </clix:subchapter>\r
544     <clix:subchapter name="acceptor-behaviour" title="Customizing acceptor behaviour">\r
546 If you want to modify what acceptors do, you should\r
547 subclass <clix:ref>ACCEPTOR</clix:ref>\r
548 (or <clix:ref>SSL-ACCEPTOR</clix:ref>) and specialize the generic\r
549 functions that constitute their behaviour.  The life of an acceptor\r
550 looks like this: It is started with the function <clix:ref>START</clix:ref> which\r
551 immediately calls <clix:ref>START-LISTENING</clix:ref> and then applies the function\r
552 <clix:ref>EXECUTE-ACCEPTOR</clix:ref> to\r
553 its <a href="#taskmasters">taskmaster</a>.  This function will\r
554 eventually call <clix:ref>ACCEPT-CONNECTIONS</clix:ref> which is\r
555 responsible for settings things up to wait for clients to connect.\r
556 For each connection which comes\r
557 in, <clix:ref>HANDLE-INCOMING-CONNECTION</clix:ref> is applied to the\r
558 taskmaster which will call <clix:ref>PROCESS-CONNECTION</clix:ref>.\r
559 <clix:ref>PROCESS-CONNECTION</clix:ref>\r
560 calls <clix:ref>INITIALIZE-CONNECTION-STREAM</clix:ref> before it does\r
561 anything else, then it selects and calls a function which handles\r
562 the <a href="#requests">request</a>, and finally it sends\r
563 the <a href="#replies">reply</a> to the client before it\r
564 calls <clix:ref>RESET-CONNECTION-STREAM</clix:ref>.  If the connection\r
565 is persistent, this procedure is repeated (except for the\r
566 intialization step) in a loop until the connection is closed.  The\r
567 acceptor is stopped with <clix:ref>STOP</clix:ref>.\r
569 <p>\r
570 If you just want to use the standard acceptors that come with\r
571 Hunchentoot, you don't need to know anything about the functions\r
572 listed in this section.\r
573 </p>\r
575   <clix:function generic='true' name='start-listening'>\r
576   <clix:lambda-list>acceptor\r
577   </clix:lambda-list>\r
578   <clix:returns>|\r
579   </clix:returns>\r
580     <clix:description>Sets up a listen socket for the given acceptor and\r
581 enables it to listen to incoming connections.  This function is called\r
582 from the thread that starts the acceptor initially and may return\r
583 errors resulting from the listening operation (like &#039;address in use&#039;\r
584 or similar).\r
585     </clix:description>\r
586   </clix:function>\r
588   <clix:function generic='true' name='accept-connections'>\r
589   <clix:lambda-list>acceptor\r
590   </clix:lambda-list>\r
591   <clix:returns>nil\r
592   </clix:returns>\r
593     <clix:description>In a loop, accepts a connection and hands it over\r
594 to the acceptor's taskmaster for processing using\r
595 <clix:ref>HANDLE-INCOMING-CONNECTION</clix:ref>. On LispWorks, this\r
596 function returns immediately, on other Lisps it returns only once the\r
597 acceptor has been stopped.\r
598     </clix:description>\r
599   </clix:function>\r
601   <clix:function generic='true' name='process-connection'>\r
602   <clix:lambda-list>acceptor socket\r
603   </clix:lambda-list>\r
604   <clix:returns>nil\r
605   </clix:returns>\r
606     <clix:description>This function is called by the taskmaster when a\r
607 new client connection has been established.  Its arguments are the\r
608 <clix:ref>ACCEPTOR</clix:ref> object and a LispWorks socket handle or a usocket socket\r
609 stream object in <clix:arg>socket</clix:arg>.  It reads the request headers, sets up the\r
610 <a href="#requests">request</a> and <a href="#replies">reply</a>\r
611 objects, and hands over to <clix:ref>PROCESS-REQUEST</clix:ref> which\r
612 selects and calls a handler for the request and sends its reply to the\r
613 client.  This is done in a loop until the stream has to be closed or\r
614 until a connection timeout occurs.\r
616 <p>\r
617 It is probably not a good idea to re-implement this method until you\r
618 really, really know what you're doing, but you can for example write\r
619 an around method specialized for your subclass\r
620 of <clix:ref>ACCEPTOR</clix:ref> which binds or rebinds special\r
621 variables which can then be accessed by\r
622 your <a href="#handlers">handlers</a>.\r
623 </p>\r
624     </clix:description>\r
625   </clix:function>\r
627   <clix:function generic='true' name='initialize-connection-stream'>\r
628   <clix:lambda-list>acceptor stream\r
629   </clix:lambda-list>\r
630   <clix:returns>stream\r
631   </clix:returns>\r
632     <clix:description>Can be used to modify the stream which is used\r
633 to communicate between client and server before the request is read.\r
634 The default method of <clix:ref>ACCEPTOR</clix:ref> does nothing, but\r
635 see for example the method defined\r
636 for <clix:ref>SSL-ACCEPTOR</clix:ref>.  All methods of this generic\r
637 function <em>must</em> return the stream to use.\r
638     </clix:description>\r
639   </clix:function>\r
641   <clix:function generic='true' name='reset-connection-stream'>\r
642   <clix:lambda-list>acceptor stream\r
643   </clix:lambda-list>\r
644   <clix:returns>stream\r
645   </clix:returns>\r
646     <clix:description>Resets the stream which is used to communicate\r
647 between client and server after one request has been served so that it\r
648 can be used to process the next request.  This generic function is\r
649 called after a request has been processed and <em>must</em> return the\r
650 stream.\r
651     </clix:description>\r
652   </clix:function>\r
654     </clix:subchapter>\r
656     <clix:subchapter name="taskmasters" title="Taskmasters">\r
658 As a "normal" Hunchentoot user, you can completely ignore taskmasters\r
659 and skip this section.  But if you're still reading, here are the\r
660 dirty details: Each <a href="#acceptors">acceptor</a> has a taskmaster\r
661 associated with it at creation time.  It is the taskmaster's job to\r
662 distribute the work of accepting and handling incoming connections.\r
663 The acceptor calls the taskmaster if appropriate and the taskmaster\r
664 calls back into the acceptor.  This is done using the generic\r
665 functions described in this and\r
666 the <a href="#acceptor-behaviour">previous</a> section.  Hunchentoot\r
667 comes with two standard taskmaster implementations - one (which is the\r
668 default used on multi-threaded Lisps) which starts a new thread for\r
669 each incoming connection and one which handles all requests\r
670 sequentially.  It should for example be relatively straightforward to\r
671 create a taskmaster which allocates threads from a fixed pool instead\r
672 of creating a new one for each connection.\r
673 <p>\r
674 If you want to implement your own taskmasters, you should subclass\r
675 <clix:ref>TASKMASTER</clix:ref> and specialize the generic functions in this section.\r
676 </p>\r
678   <clix:class name='taskmaster'>\r
679     <clix:description>An instance of this class is responsible for\r
680 distributing the work of handling requests for its acceptor.\r
681 This is\r
682 an "abstract" class in the sense that usually only instances of\r
683 subclasses of <clix:ref>TASKMASTER</clix:ref> will be used.\r
684     </clix:description>\r
685   </clix:class>\r
687   <clix:class name='one-thread-per-connection-taskmaster'>\r
688     <clix:description>A taskmaster that starts one thread for listening\r
689 to incoming requests and one thread for each incoming connection.\r
690 <p>\r
691 This is the default taskmaster implementation for multi-threaded Lisp\r
692 implementations.\r
693 </p>\r
694     </clix:description>\r
695   </clix:class>\r
697   <clix:class name='single-threaded-taskmaster'>\r
698     <clix:description>A taskmaster that runs synchronously in the\r
699 thread where the <clix:ref>START</clix:ref> function was invoked (or\r
700 in the case of LispWorks in the thread started\r
701 by <a href="http://www.lispworks.com/documentation/lw51/LWRM/html/lwref-61.htm#marker-910861"><code>COMM:START-UP-SERVER</code></a>).\r
702 This is the simplest possible taskmaster implementation in that its\r
703 methods do nothing but calling their acceptor &quot;sister&quot;\r
704 methods - <clix:ref>EXECUTE-ACCEPTOR</clix:ref> calls <clix:ref>ACCEPT-CONNECTIONS</clix:ref>,\r
705 <clix:ref>HANDLE-INCOMING-CONNECTION</clix:ref> calls <clix:ref>PROCESS-CONNECTION</clix:ref>.\r
706     </clix:description>\r
707   </clix:class>\r
709   <clix:function generic='true' name='execute-acceptor'>\r
710   <clix:lambda-list>taskmaster\r
711   </clix:lambda-list>\r
712   <clix:returns>result\r
713   </clix:returns>\r
714     <clix:description>This is a callback called by the acceptor once it\r
715 has performed all initial processing to start listening for incoming\r
716 connections (see <clix:ref>START-LISTENING</clix:ref>).  It usually calls the\r
717 <clix:ref>ACCEPT-CONNECTIONS</clix:ref> method of the acceptor, but depending on the\r
718 taskmaster instance the method might be called from a new thread.\r
719     </clix:description>\r
720   </clix:function>\r
722   <clix:function generic='true' name='handle-incoming-connection'>\r
723   <clix:lambda-list>taskmaster socket\r
724   </clix:lambda-list>\r
725   <clix:returns>result\r
726   </clix:returns>\r
727     <clix:description>This function is called by the acceptor to start\r
728 processing of requests on a new incoming connection.  <clix:arg>socket</clix:arg> is the\r
729 usocket instance that represents the new connection (or a socket\r
730 handle on LispWorks).  The taskmaster starts processing requests on\r
731 the incoming connection by calling the <clix:ref>PROCESS-CONNECTION</clix:ref>\r
732 method of the acceptor instance.  The <clix:arg>socket</clix:arg> argument is passed to\r
733 <clix:ref>PROCESS-CONNECTION</clix:ref> as an argument.\r
734     </clix:description>\r
735   </clix:function>\r
737   <clix:function generic='true' name='shutdown'>\r
738   <clix:lambda-list>taskmaster\r
739   </clix:lambda-list>\r
740   <clix:returns>taskmaster\r
741   </clix:returns>\r
742     <clix:description>Shuts down the taskmaster, i.e. frees all resources\r
743 that were set up by it.  For example, a multi-threaded taskmaster\r
744 might terminate all threads that are currently associated with it.\r
745 This function is called by the acceptor's <clix:ref>STOP</clix:ref> method.\r
746     </clix:description>\r
747   </clix:function>\r
749   <clix:accessor generic='true' name='taskmaster-acceptor'>\r
750   <clix:lambda-list>taskmaster\r
751   </clix:lambda-list>\r
752   <clix:returns>acceptor\r
753   </clix:returns>\r
754     <clix:description>\r
755 This is an accessor for the slot of a <clix:ref>TASKMASTER</clix:ref>\r
756 object that links back to the <a href="#acceptors">acceptor</a> it is\r
757 associated with.\r
758     </clix:description>\r
759   </clix:accessor>\r
761     </clix:subchapter>\r
763     <clix:subchapter name="request-dispatch" title="Request dispatch and handling">\r
765 The main job of <clix:ref>PROCESS-REQUEST</clix:ref> is to select and\r
766 call a function which handles the request, i.e. which looks at the\r
767 data the client has sent and prepares an appropriate reply to send\r
768 back.  This is implemented as follows:\r
769 <p>\r
770 Each acceptor has a <a href="#acceptor-request-dispatcher"><em>request\r
771 dispatcher</em></a> which is a unary function that accepts\r
772 a <clix:ref>REQUEST</clix:ref> object.  This function is called by\r
773 <clix:ref>PROCESS-REQUEST</clix:ref>.  The idea is that this function\r
774 looks at the request object and depending on its contents decides to\r
775 call another function which "does the work".  This "other" function is\r
776 by convention called a <a class="none" name="handlers"><em>request\r
777 handler</em></a>.  (Obviously, this is really only a convention as\r
778 process-request doesn't "know" what the request dispatcher does.  You\r
779 could as well say that the request dispatcher and the request handler\r
780 have the same job.)\r
781 </p>\r
782 <p>\r
783 The default behaviour, unless you implement your own request\r
784 dispatcher, is that Hunchentoot walks through the list\r
785 *dispatch-table* which consists of <em>dispatch functions</em>.  Each\r
786 of these functions accepts the request object as its only argument and\r
787 either returns a request handler to handle the request\r
788 or <code>NIL</code> which means that the next dispatcher in the list\r
789 will be tried.  If all dispatch functions return <code>NIL</code>, the\r
790 return code\r
791 <clix:ref>+HTTP-NOT-FOUND+</clix:ref> will be sent to the client.\r
792 </p>\r
793 <p>\r
794 All functions and variables in this section are related to the\r
795 standard request dispatch mechanism described above and are\r
796 meaningless if you're using your own request dispatcher.\r
797 </p>\r
798 <p>\r
799 Request handlers do their work by modifying\r
800 the <a href="#replies">reply object</a> if necessary and by eventually\r
801 returning the response body in the form of a string or a binary\r
802 sequence.  As an alternative, they can also\r
803 call <clix:ref>SEND-HEADERS</clix:ref> and write directly to a stream.\r
804 </p>\r
806   <clix:special-variable name='*dispatch-table*'>\r
807     <clix:description>A global list of dispatch functions.  The\r
808     initial value is a list consisting of the two\r
809     symbols <clix:ref>DISPATCH-EASY-HANDLERS</clix:ref>\r
810     and <clix:ref>DEFAULT-DISPATCHER</clix:ref>.\r
811     </clix:description>\r
812   </clix:special-variable>\r
814   <clix:function name='default-dispatcher'>\r
815   <clix:lambda-list>request\r
816   </clix:lambda-list>\r
817   <clix:returns>result\r
818   </clix:returns>\r
819     <clix:description>Default dispatch function which handles every request with the\r
820 function stored in <clix:ref>*DEFAULT-HANDLER*</clix:ref>.\r
821     </clix:description>\r
822   </clix:function>\r
824   <clix:special-variable name='*default-handler*'>\r
825     <clix:description>The name of the function which is always returned by\r
826 <clix:ref>DEFAULT-DISPATCHER</clix:ref>.\r
827     </clix:description>\r
828   </clix:special-variable>\r
830       <clix:function name="create-prefix-dispatcher">\r
831         <clix:lambda-list>prefix handler</clix:lambda-list>\r
832         <clix:returns>dispatch-fn</clix:returns>\r
833         <clix:description>\r
834           A convenience function which will return a dispatcher that\r
835           returns <clix:arg>handler</clix:arg> whenever the path part of\r
836           the request URI starts with the\r
837           string <clix:arg>prefix</clix:arg>.\r
838         </clix:description>\r
839       </clix:function>\r
841       <clix:function name="create-regex-dispatcher">\r
842         <clix:lambda-list>regex handler</clix:lambda-list>\r
843         <clix:returns>dispatch-fn</clix:returns>\r
844         <clix:description>\r
845           A convenience function which will return a dispatcher that\r
846           returns <clix:arg>handler</clix:arg> whenever the path part of\r
847           the request URI matches\r
848           the <a href="http://weitz.de/cl-ppcre/">CL-PPCRE</a> regular\r
849           expression <clix:arg>regex</clix:arg> (which can be a string, an\r
850           s-expression, or a scanner).\r
851         </clix:description>\r
852       </clix:function>\r
854       <clix:function name="create-folder-dispatcher-and-handler">\r
855         <clix:lambda-list>uri-prefix base-path <clix:lkw>optional</clix:lkw> content-type</clix:lambda-list>\r
856         <clix:returns>dispatch-fn</clix:returns>\r
857         <clix:description>\r
858           Creates and returns a dispatch function which will dispatch to\r
859           a handler function which emits the file relative\r
860           to <clix:arg>base-path</clix:arg> that is denoted by the URI of\r
861           the request relative\r
862           to <clix:arg>uri-prefix</clix:arg>.  <clix:arg>uri-prefix</clix:arg>\r
863           must be a string ending with a\r
864           slash, <clix:arg>base-path</clix:arg> must be a pathname\r
865           designator for an existing directory.\r
866           Uses <clix:ref>HANDLE-STATIC-FILE</clix:ref> internally.\r
867           <p>\r
868             If <clix:arg>content-type</clix:arg> is <em>not</em>\r
869             <code>NIL</code>, it will be used as a the content type for\r
870             all files in the folder.  Otherwise (which is the default)\r
871             the content type of each file will be\r
872             determined <a href="#handle-static-file">as usual</a>.\r
873           </p>\r
874         </clix:description>\r
875       </clix:function>\r
877   <clix:function name='create-static-file-dispatcher-and-handler'>\r
878   <clix:lambda-list>uri path \r
879   <clix:lkw>optional\r
880   </clix:lkw> content-type\r
881   </clix:lambda-list>\r
882   <clix:returns>result\r
883   </clix:returns>\r
884     <clix:description>Creates and returns a request dispatch function which will dispatch\r
885 to a handler function which emits the file denoted by the pathname\r
886 designator PATH with content type CONTENT-TYPE if the SCRIPT-NAME of\r
887 the request matches the string URI.  If CONTENT-TYPE is NIL, tries to\r
888 determine the content type via the file&#039;s suffix.\r
889     </clix:description>\r
890   </clix:function>\r
893       <clix:function macro="true" name="define-easy-handler">\r
894         <clix:lambda-list>description lambda-list [[declaration* | documentation]] form*</clix:lambda-list>\r
895         <clix:description>\r
896           Defines a handler as if\r
897           by <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_defun.htm">\r
898             <code>DEFUN</code></a> and optionally registers it with a\r
899           URI so that it will be found\r
900           by <clix:ref>DISPATCH-EASY-HANDLERS</clix:ref>.\r
901           <p>\r
902             <clix:arg>description</clix:arg> is either a\r
903             symbol <clix:arg>name</clix:arg> or a list matching the\r
904             <a href="http://www.lispworks.com/documentation/HyperSpec/Body/03_de.htm">destructuring\r
905               lambda list</a>\r
906           </p>\r
907           <pre>(name &amp;key uri server-names default-parameter-type default-request-type).</pre>\r
908           <clix:arg>lambda-list</clix:arg> is a list the elements of which\r
909           are either a symbol <clix:arg>var</clix:arg> or a list matching\r
910           the destructuring lambda list\r
911           <pre>(var &amp;key real-name parameter-type init-form request-type).</pre>\r
912           The resulting handler will be a Lisp function with the\r
913           name <clix:arg>name</clix:arg> and keyword parameters named by\r
914           the <clix:arg>var</clix:arg> symbols.\r
915           Each <clix:arg>var</clix:arg> will be bound to the value of the\r
916           GET or POST parameter called <clix:arg>real-name</clix:arg> (a\r
917           string) before the body of the function is executed.\r
918           If <clix:arg>real-name</clix:arg> is not provided, it will be\r
919           computed\r
920           by <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_stg_up.htm#string-downcase">downcasing</a>\r
921           the symbol name of <clix:arg>var</clix:arg>.\r
922           <p>\r
923             If <clix:arg>uri</clix:arg> (which is evaluated) is provided,\r
924             then it must be a string or\r
925             a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function_designator">function\r
926               designator</a> for a unary function.  In this case, the\r
927             handler will be returned\r
928             by <clix:ref>DISPATCH-EASY-HANDLERS</clix:ref> ,\r
929             if <clix:arg>uri</clix:arg> is a string and\r
930             the <a href="#script-name">script name</a> of the current\r
931             request is <clix:arg>uri</clix:arg>, or\r
932             if <clix:arg>uri</clix:arg> designates a function and applying\r
933             this function to\r
934             the <a href="#*request*">current <code>REQUEST</code>\r
935               object</a> returns a true value.\r
936           </p>\r
937           <p>\r
938             <clix:arg>server-names</clix:arg> (which is evaluated) can be a\r
939             list of symbols which means that the handler will only be\r
940             returned by <clix:ref>DISPATCH-EASY-HANDLERS</clix:ref> in\r
941             servers which have one of these names\r
942             (see <clix:ref>SERVER-NAME</clix:ref>).  <clix:arg>server-names</clix:arg> can also be the\r
943             symbol <code>T</code> which means that the handler will be\r
944             returned by <clix:ref>DISPATCH-EASY-HANDLERS</clix:ref>\r
945             in <em>every</em> server.\r
946           </p>\r
947           <p>\r
948             Whether the GET or POST parameter (or both) will be taken into\r
949             consideration, depends on <clix:arg>request-type</clix:arg>\r
950             which can\r
951             be <code>:GET</code>, <code>:POST</code>, <code>:BOTH</code>,\r
952             or <code>NIL</code>.  In the last case, the value of\r
953             <clix:arg>default-request-type</clix:arg> (the default of which\r
954             is <code>:BOTH</code>) will be used.\r
955           </p>\r
956           <p>\r
957             The value of <clix:arg>var</clix:arg> will usually be a string\r
958             (unless it resulted from a <a href="#upload">file upload</a>\r
959             in which case it won't be converted at all), but\r
960             if <clix:arg>parameter-type</clix:arg> (which is evaluated) is\r
961             provided, the string will be converted to another Lisp type by\r
962             the following rules:\r
963           </p>\r
964           <p>\r
965             If the corresponding GET or POST parameter wasn't provided by\r
966             the client, <clix:arg>var</clix:arg>'s value will\r
967             be <code>NIL</code>.  If <clix:arg>parameter-type</clix:arg>\r
968             is <code>'STRING</code>,\r
969             <clix:arg>var</clix:arg>'s value remains as is.\r
970             If <clix:arg>parameter-type</clix:arg> is <code>'INTEGER</code>\r
971             and the parameter string consists solely of decimal\r
972             digits, <clix:arg>var</clix:arg>'s value will be the\r
973             corresponding integer, otherwise <code>NIL</code>.\r
974             If <clix:arg>parameter-type</clix:arg> is\r
975             <code>'KEYWORD</code>, <clix:arg>var</clix:arg>'s value will be\r
976             the keyword obtained\r
977             by <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_intern.htm">interning</a>\r
978             the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_stg_up.htm#string-upcase">upcased</a>\r
979             parameter string into\r
980             the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/11_abc.htm">keyword\r
981               package</a>.  If <clix:arg>parameter-type</clix:arg>\r
982             is <code>'CHARACTER</code> and the parameter string is of\r
983             length one, <clix:arg>var</clix:arg>'s value will be the single\r
984             character of this string, otherwise <code>NIL</code>.\r
985             If <clix:arg>parameter-type</clix:arg>\r
986             is <code>'BOOLEAN</code>, <clix:arg>var</clix:arg>'s value will\r
987             always be <code>T</code> (unless it is <code>NIL</code> by the\r
988             first rule above, of course).\r
989             If <clix:arg>parameter-type</clix:arg> is any other atom, it is\r
990             supposed to be\r
991             a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function_designator">function\r
992               designator</a> for a unary function which will be called to\r
993             convert the string to something else.\r
994           </p>\r
995           <p>\r
996             Those were the rules for <em>simple</em> parameter types, but\r
997             <clix:arg>parameter-type</clix:arg> can also be a list starting\r
998             with one of the symbols\r
999             <code>LIST</code>, <code>ARRAY</code>,\r
1000             or <code>HASH-TABLE</code>.  The second value of the list must\r
1001             always be a simple parameter type as in the last paragraph -\r
1002             we'll call it the <em>inner type</em> below.\r
1003           </p>\r
1004           <p>\r
1005             In the case of <code>'LIST</code>, all GET/POST parameters\r
1006             called <clix:arg>real-name</clix:arg> will be collected,\r
1007             converted to the inner type as by the rules above, and\r
1008             assembled into a list which will be the value of\r
1009             <clix:arg>var</clix:arg>.\r
1010           </p>\r
1011           <p>\r
1012             In the case of <code>'ARRAY</code>, all GET/POST parameters\r
1013             which have a name like the result of\r
1014           </p>\r
1015           <pre>(format nil "~A[~A]" real-name n)</pre>\r
1016           where <clix:arg>n</clix:arg> is a non-negative integer, will be\r
1017           assembled into an array where the <clix:arg>n</clix:arg>th element\r
1018           will be set accordingly, after conversion to the inner type.\r
1019           The array, which will become the value\r
1020           of <clix:arg>var</clix:arg>, will be big enough to hold all\r
1021           matching parameters, but not bigger.  Array elements not set as\r
1022           described above will be <code>NIL</code>.  Note\r
1023           that <code>VAR</code> will always be bound to an array, which\r
1024           may be empty, so it will never be <code>NIL</code>, even if no\r
1025           appropriate GET/POST parameters are found.\r
1026           <p>\r
1027             The full form of a <code>'HASH-TABLE</code> parameter type is\r
1028           </p>\r
1029           <pre>(hash-table inner-type key-type test-function)</pre>\r
1030           but <clix:arg>key-type</clix:arg>\r
1031           and <clix:arg>test-function</clix:arg> can be left out in which\r
1032           case they default to <code>'STRING</code>\r
1033           and <code>'EQUAL</code>, respectively.  For this parameter type,\r
1034           all GET/POST parameters which have a name like the result of\r
1035           <pre>(format nil "~A{~A}" real-name key)</pre>\r
1036           (where <clix:arg>key</clix:arg> is a string that doesn't contain\r
1037           curly brackets) will become the values (after conversion\r
1038           to <clix:arg>inner-type</clix:arg>) of a hash table with test\r
1039           function <clix:arg>test-function</clix:arg>\r
1040           where <clix:arg>key</clix:arg> (after conversion\r
1041           to <clix:arg>key-type</clix:arg>) will be the corresponding key.\r
1042           Note that <clix:arg>var</clix:arg> will always be bound to a hash\r
1043           table, which may be empty, so it will never be <code>NIL</code>,\r
1044           even if no appropriate GET/POST parameters are found.\r
1045           <p>\r
1046             To make matters even more complicated, the three compound\r
1047             parameter types also have an abbreviated form - just one of\r
1048             the symbols <code>LIST</code>, <code>ARRAY</code>,\r
1049             or <code>HASH-TABLE</code>.  In this case, the inner type will\r
1050             default to <code>'STRING</code>.\r
1051           </p>\r
1052           <p>\r
1053             If <clix:arg>parameter-type</clix:arg> is not provided\r
1054             or <code>NIL</code>, <clix:arg>default-parameter-type</clix:arg>\r
1055             (the default of which is <code>'STRING</code>) will be used\r
1056             instead.\r
1057           </p>\r
1058           <p>\r
1059             If the result of the computations above would be\r
1060             that <clix:arg>var</clix:arg> would be bound\r
1061             to <code>NIL</code>, then <clix:arg>init-form</clix:arg> (if\r
1062             provided) will be evaluated instead,\r
1063             and <clix:arg>var</clix:arg> will be bound to the result of this\r
1064             evaluation.\r
1065           </p>\r
1066           <p>\r
1067             Handlers built with this macro are constructed in such a way\r
1068             that the resulting Lisp function is useful even outside of\r
1069             Hunchentoot.  Specifically, all the parameter computations\r
1070             above will only happen if <clix:ref>*REQUEST*</clix:ref> is\r
1071             bound, i.e. if we're within a Hunchentoot request.\r
1072             Otherwise, <clix:arg>var</clix:arg> will always be bound to the\r
1073             result of evaluating <clix:arg>init-form</clix:arg> unless a\r
1074             corresponding keyword argument is provided.\r
1075           </p>\r
1076           <p>\r
1077             The <a href="#example">example code</a> that comes with\r
1078             Hunchentoot contains an example which demonstrates some of the\r
1079             features of <clix:ref>DEFINE-EASY-HANDLER</clix:ref>.\r
1080           </p>\r
1081         </clix:description>\r
1082       </clix:function>\r
1084   <clix:function name='dispatch-easy-handlers'>\r
1085   <clix:lambda-list>request\r
1086   </clix:lambda-list>\r
1087   <clix:returns>result\r
1088   </clix:returns>\r
1089     <clix:description>This is a dispatcher which returns the appropriate handler\r
1090 defined with <clix:ref>DEFINE-EASY-HANDLER</clix:ref>, if there is one.\r
1091     </clix:description>\r
1092   </clix:function>\r
1096     </clix:subchapter>\r
1098     <clix:subchapter name="requests" title="Request objects">\r
1100 For each incoming request, the <a href="#acceptors">acceptor</a>\r
1101 (in <clix:ref>PROCESS-CONNECTION</clix:ref>) creates\r
1102 a <clix:ref>REQUEST</clix:ref> object and makes it available\r
1103 to <a href="#handlers">handlers</a> via the special variable\r
1104 <clix:ref>*REQUEST*</clix:ref>.  This object contains all relevant\r
1105 information about the request and this section collects the functions\r
1106 which can be used to query such an object.\r
1107 In all function where <clix:arg>request</clix:arg> is an\r
1108 optional or keyword parameter, the default\r
1109 is <clix:ref>*REQUEST*</clix:ref>.\r
1111 <p>\r
1112 If you need more fine-grained control over the behaviour of request\r
1113 objects, you can subclass <clix:ref>REQUEST</clix:ref> and initialize\r
1114 the <a href="#acceptor-request-class"><code>REQUEST-CLASS</code></a>\r
1115 slot of the <clix:ref>ACCEPTOR</clix:ref> class accordingly.  The\r
1116 acceptor will generate request objects of the class named by this\r
1117 slot.\r
1118 </p>\r
1120   <clix:class name='request'>\r
1121     <clix:description>Objects of this class hold all the information\r
1122 about an incoming request.  They are created automatically by\r
1123 acceptors and can be accessed by the\r
1124 corresponding <a href="#handlers">handler</a>.\r
1126 You should not mess with the slots of these objects directly, but you\r
1127 can subclass <clix:ref>REQUEST</clix:ref> in order to implement your\r
1128 own behaviour.  See\r
1129 the <a href="#acceptor-request-class"><code>REQUEST-CLASS</code></a>\r
1130 slot of the <clix:ref>ACCEPTOR</clix:ref> class.\r
1131     </clix:description>\r
1132   </clix:class>\r
1134   <clix:special-variable name='*request*'>\r
1135     <clix:description>The current REQUEST object while in the context of a request.\r
1136     </clix:description>\r
1137   </clix:special-variable>\r
1139   <clix:function name='real-remote-addr'>\r
1140   <clix:lambda-list>\r
1141   <clix:lkw>optional\r
1142   </clix:lkw> request\r
1143   </clix:lambda-list>\r
1144   <clix:returns>string{, list}\r
1145   </clix:returns>\r
1146     <clix:description>Returns the &#039;<code>X-Forwarded-For</code>&#039; incoming http header as the\r
1147 second value in the form of a list of IP addresses and the first\r
1148 element of this list as the first value if this header exists.\r
1149 Otherwise returns the value of <clix:ref>REMOTE-ADDR</clix:ref> as the only value.\r
1150     </clix:description>\r
1151   </clix:function>\r
1153   <clix:function name='parameter'>\r
1154   <clix:lambda-list>name \r
1155   <clix:lkw>optional\r
1156   </clix:lkw> request\r
1157   </clix:lambda-list>\r
1158   <clix:returns>string\r
1159   </clix:returns>\r
1160     <clix:description>Returns the GET or the POST parameter with\r
1161 name <clix:arg>name</clix:arg> (a string) - or <code>NIL</code> if\r
1162 there is none.  If both a GET and a POST parameter with the same name\r
1163 exist the GET parameter is returned.  Search is case-sensitive.  See also <clix:ref>GET-PARAMETER</clix:ref>  and <clix:ref>POST-PARAMETER</clix:ref>. \r
1164     </clix:description>\r
1165   </clix:function>\r
1167       <clix:function name="get-parameter">\r
1168         <clix:lambda-list>name <clix:lkw>optional</clix:lkw> request</clix:lambda-list>\r
1169         <clix:returns>string</clix:returns>\r
1170         <clix:description>\r
1171           Returns the value of the GET parameter (as provided via the\r
1172           request URI) named by the string <clix:arg>name</clix:arg> as a\r
1173           string (or <code>NIL</code> if there ain't no GET parameter\r
1174           with this name). Note that only the first value will be\r
1175           returned if the client provided more than one GET parameter\r
1176           with the name <clix:arg>name</clix:arg>. See\r
1177           also <clix:ref>GET-PARAMETERS*</clix:ref>.\r
1178         </clix:description>\r
1179       </clix:function>\r
1181       <clix:function name="post-parameter">\r
1182         <clix:lambda-list>name <clix:lkw>optional</clix:lkw> request</clix:lambda-list>\r
1183         <clix:returns>string</clix:returns>\r
1184         <clix:description>\r
1185           Returns the value of the POST parameter (as provided in the\r
1186           request's body) named by the\r
1187           string <clix:arg>name</clix:arg>. Note that only the first value\r
1188           will be returned if the client provided more than one POST\r
1189           parameter with the name <clix:arg>name</clix:arg>.  This value\r
1190           will usually be a string (or <code>NIL</code> if there ain't\r
1191           no POST parameter with this name). If, however, the browser\r
1192           sent a <a class="none" name="upload">file</a> through\r
1193           a <a href="http://www.faqs.org/rfcs/rfc2388.html">\r
1194             <code>multipart/form-data</code>\r
1195           </a> form, the value of this function is a three-element list\r
1196           <pre>(path file-name content-type)</pre>\r
1197           where <clix:arg>path</clix:arg> is a pathname denoting the place\r
1198           were the uploaded file was\r
1199           stored, <clix:arg>file-name</clix:arg> (a string) is the file\r
1200           name sent by the browser, and <clix:arg>content-type</clix:arg>\r
1201           (also a string) is the content type sent by the browser. The\r
1202           file denoted by <clix:arg>path</clix:arg> will be deleted after\r
1203           the request has been handled - you have to move or copy it\r
1204           somewhere else if you want to keep it.\r
1205           <p>\r
1206             POST parameters will only be computed if the content type of\r
1207             the request body was <code>multipart/form-data</code>\r
1208             or <code>application/x-www-form-urlencoded</code>.  Although\r
1209             this function is called <code>POST-PARAMETER</code>, you can\r
1210             instruct Hunchentoot to compute these parameters for other\r
1211             request methods by\r
1212             setting <clix:ref>*METHODS-FOR-POST-PARAMETERS*</clix:ref>.\r
1213           </p>\r
1214           <p>\r
1215             See also <clix:ref>POST-PARAMETERS</clix:ref>\r
1216             and <clix:ref>*TMP-DIRECTORY*</clix:ref>.\r
1217           </p>\r
1218         </clix:description>\r
1219       </clix:function>\r
1221       <clix:function name="get-parameters*">\r
1222         <clix:lambda-list><clix:lkw>optional</clix:lkw> request</clix:lambda-list>\r
1223         <clix:returns>alist</clix:returns>\r
1224         <clix:description>\r
1225           Returns\r
1226           an <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#alist">alist</a>\r
1227           of all GET parameters (as provided via the request\r
1228           URI). The <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#car">car</a>\r
1229           of each element of this list is the parameter's name while\r
1230           the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#cdr">cdr</a>\r
1231           is its value (as a string). The elements of this list are in\r
1232           the same order as they were within the request URI. See\r
1233           also <clix:ref>GET-PARAMETER</clix:ref>.\r
1234         </clix:description>\r
1235       </clix:function>\r
1237       <clix:function name="post-parameters*">\r
1238         <clix:lambda-list><clix:lkw>optional</clix:lkw> request</clix:lambda-list>\r
1239         <clix:returns>alist</clix:returns>\r
1240         <clix:description>\r
1241           Returns\r
1242           an <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#alist">alist</a>\r
1243           of all POST parameters (as provided via the request's\r
1244           body). The <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#car">car</a>\r
1245           of each element of this list is the parameter's name while\r
1246           the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#cdr">cdr</a>\r
1247           is its value. The elements of this list are in the same order\r
1248           as they were within the request's body.\r
1249           <p>\r
1250             See also <clix:ref>POST-PARAMETER</clix:ref>.\r
1251           </p>\r
1252         </clix:description>\r
1253       </clix:function>\r
1255   <clix:special-variable name='*methods-for-post-parameters*'>\r
1256     <clix:description>A list of the request method types (as keywords) for which\r
1257 Hunchentoot will try to compute <clix:arg>post-parameters</clix:arg>.\r
1258     </clix:description>\r
1259   </clix:special-variable>\r
1261   <clix:function name='cookie-in'>\r
1262   <clix:lambda-list>name \r
1263   <clix:lkw>optional\r
1264   </clix:lkw> request\r
1265   </clix:lambda-list>\r
1266   <clix:returns>cookie\r
1267   </clix:returns>\r
1268     <clix:description>Returns the cookie with the name <clix:arg>name</clix:arg> (a string) as sent by the\r
1269 browser - or <code>NIL</code> if there is none.\r
1270     </clix:description>\r
1271   </clix:function>\r
1273   <clix:function name='cookies-in*'>\r
1274   <clix:lambda-list>\r
1275   <clix:lkw>optional\r
1276   </clix:lkw> request\r
1277   </clix:lambda-list>\r
1278   <clix:returns>alist\r
1279   </clix:returns>\r
1280     <clix:description>Returns an alist of all cookies associated with the <clix:ref>REQUEST</clix:ref> object\r
1281 <clix:arg>request</clix:arg>.\r
1282     </clix:description>\r
1283   </clix:function>\r
1285   <clix:function name='host'>\r
1286   <clix:lambda-list>\r
1287   <clix:lkw>optional\r
1288   </clix:lkw> request\r
1289   </clix:lambda-list>\r
1290   <clix:returns>host\r
1291   </clix:returns>\r
1292     <clix:description>Returns the &#039;Host&#039; incoming http header value.\r
1293     </clix:description>\r
1294   </clix:function>\r
1296   <clix:function name='query-string*'>\r
1297   <clix:lambda-list>\r
1298   <clix:lkw>optional\r
1299   </clix:lkw> request\r
1300   </clix:lambda-list>\r
1301   <clix:returns>string\r
1302   </clix:returns>\r
1303     <clix:description>Returns the query string of the <clix:ref>REQUEST</clix:ref> object <clix:arg>request</clix:arg>. That&#039;s\r
1304 the part behind the question mark (i.e. the GET parameters).\r
1305     </clix:description>\r
1306   </clix:function>\r
1308   <clix:function name='referer'>\r
1309   <clix:lambda-list>\r
1310   <clix:lkw>optional\r
1311   </clix:lkw> request\r
1312   </clix:lambda-list>\r
1313   <clix:returns>result\r
1314   </clix:returns>\r
1315     <clix:description>Returns the &#039;Referer&#039; (sic!) http header.\r
1316     </clix:description>\r
1317   </clix:function>\r
1319   <clix:function name='request-method*'>\r
1320   <clix:lambda-list>\r
1321   <clix:lkw>optional\r
1322   </clix:lkw> request\r
1323   </clix:lambda-list>\r
1324   <clix:returns>keyword\r
1325   </clix:returns>\r
1326     <clix:description>Returns the request method as a Lisp keyword.\r
1327     </clix:description>\r
1328   </clix:function>\r
1330   <clix:function name='request-uri*'>\r
1331   <clix:lambda-list>\r
1332   <clix:lkw>optional\r
1333   </clix:lkw> request\r
1334   </clix:lambda-list>\r
1335   <clix:returns>uri\r
1336   </clix:returns>\r
1337     <clix:description>Returns the request URI.\r
1338     </clix:description>\r
1339   </clix:function>\r
1341   <clix:function name='server-protocol*'>\r
1342   <clix:lambda-list>\r
1343   <clix:lkw>optional\r
1344   </clix:lkw> request\r
1345   </clix:lambda-list>\r
1346   <clix:returns>keyword\r
1347   </clix:returns>\r
1348     <clix:description>Returns the request protocol as a Lisp keyword.\r
1349     </clix:description>\r
1350   </clix:function>\r
1352   <clix:function name='user-agent'>\r
1353   <clix:lambda-list>\r
1354   <clix:lkw>optional\r
1355   </clix:lkw> request\r
1356   </clix:lambda-list>\r
1357   <clix:returns>result\r
1358   </clix:returns>\r
1359     <clix:description>Returns the &#039;User-Agent&#039; http header.\r
1360     </clix:description>\r
1361   </clix:function>\r
1363   <clix:function name='header-in*'>\r
1364   <clix:lambda-list>name \r
1365   <clix:lkw>optional\r
1366   </clix:lkw> request\r
1367   </clix:lambda-list>\r
1368   <clix:returns>header\r
1369   </clix:returns>\r
1370     <clix:description>Returns the incoming header with\r
1371 name <clix:arg>name</clix:arg>.  <clix:arg>name</clix:arg> can be a\r
1372 keyword (recommended) or a string.\r
1373     </clix:description>\r
1374   </clix:function>\r
1376   <clix:function name='headers-in*'>\r
1377   <clix:lambda-list>\r
1378   <clix:lkw>optional\r
1379   </clix:lkw> request\r
1380   </clix:lambda-list>\r
1381   <clix:returns>alist\r
1382   </clix:returns>\r
1383     <clix:description>Returns an alist of the incoming headers associated with the\r
1384 <clix:ref>REQUEST</clix:ref> object <clix:arg>request</clix:arg>.\r
1385     </clix:description>\r
1386   </clix:function>\r
1388   <clix:function name='remote-addr*'>\r
1389   <clix:lambda-list>\r
1390   <clix:lkw>optional\r
1391   </clix:lkw> request\r
1392   </clix:lambda-list>\r
1393   <clix:returns>address\r
1394   </clix:returns>\r
1395     <clix:description>Returns the address the current request originated from.\r
1396     </clix:description>\r
1397   </clix:function>\r
1399   <clix:function name='remote-port*'>\r
1400   <clix:lambda-list>\r
1401   <clix:lkw>optional\r
1402   </clix:lkw> request\r
1403   </clix:lambda-list>\r
1404   <clix:returns>port\r
1405   </clix:returns>\r
1406     <clix:description>Returns the port the current request originated from.\r
1407     </clix:description>\r
1408   </clix:function>\r
1410   <clix:function name='script-name*'>\r
1411   <clix:lambda-list>\r
1412   <clix:lkw>optional\r
1413   </clix:lkw> request\r
1414   </clix:lambda-list>\r
1415   <clix:returns>script-name\r
1416   </clix:returns>\r
1417     <clix:description>Returns the file name of\r
1418 the <clix:ref>REQUEST</clix:ref>\r
1419 object <clix:arg>request</clix:arg>. That&#039;s the requested URI\r
1420 without the query string (i.e the GET parameters).\r
1421     </clix:description>\r
1422   </clix:function>\r
1424   <clix:accessor name='aux-request-value'>\r
1425   <clix:lambda-list>symbol \r
1426   <clix:lkw>optional\r
1427   </clix:lkw> request\r
1428   </clix:lambda-list>\r
1429   <clix:returns>value, present-p\r
1430   </clix:returns>\r
1431     <clix:description>This accessor can be used to associate arbitrary\r
1432     data with the the symbol <clix:arg>symbol</clix:arg> in the <clix:ref>REQUEST</clix:ref> object\r
1433     <clix:arg>request</clix:arg>. <clix:arg>present-p</clix:arg> is true if such data was found, otherwise <code>NIL</code>.\r
1434     </clix:description>\r
1435   </clix:accessor>\r
1437   <clix:function name='delete-aux-request-value'>\r
1438   <clix:lambda-list>symbol \r
1439   <clix:lkw>optional\r
1440   </clix:lkw> request\r
1441   </clix:lambda-list>\r
1442   <clix:returns>|\r
1443   </clix:returns>\r
1444     <clix:description>Removes the value associated with <clix:arg>symbol</clix:arg> from the <clix:ref>REQUEST</clix:ref> object\r
1445 <clix:arg>request</clix:arg>.\r
1446     </clix:description>\r
1447   </clix:function>\r
1449   <clix:function name='authorization'>\r
1450   <clix:lambda-list>\r
1451   <clix:lkw>optional\r
1452   </clix:lkw> request\r
1453   </clix:lambda-list>\r
1454   <clix:returns>result\r
1455   </clix:returns>\r
1456     <clix:description>Returns as two values the user and password (if any) as encoded in\r
1457 the &#039;AUTHORIZATION&#039; header.  Returns <code>NIL</code> if there is no such header.\r
1458     </clix:description>\r
1459   </clix:function>\r
1461   <clix:special-variable name='*hunchentoot-default-external-format*'>\r
1462     <clix:description>The external format used to compute the <clix:ref>REQUEST</clix:ref> object.\r
1463     </clix:description>\r
1464   </clix:special-variable>\r
1466   <clix:special-variable name='*file-upload-hook*'>\r
1467     <clix:description>If this is not <code>NIL</code>, it should be a\r
1468 unary function which will be called with a pathname for each file\r
1469 which is <a href="#upload">uploaded</a> to Hunchentoot.  The pathname\r
1470 denotes the temporary file to which the uploaded file is written.  The\r
1471 hook is called directly before the file is created. At this\r
1472 point, <clix:ref>*REQUEST*</clix:ref> is already bound to the\r
1473 current <clix:ref>REQUEST</clix:ref> object, but obviously you can't\r
1474 access the post parameters yet.\r
1475     </clix:description>\r
1476   </clix:special-variable>\r
1478       <clix:function name="raw-post-data">\r
1479         <clix:lambda-list>\r
1480           <clix:lkw>key</clix:lkw>\r
1481           request external-format force-text force-binary want-stream\r
1482         </clix:lambda-list>\r
1483         <clix:returns>raw-body-or-stream</clix:returns>\r
1484         <clix:description>\r
1485           Returns the content sent by the client in the request body if\r
1486           there was any (unless the content type\r
1487           was <code>multipart/form-data</code> in which\r
1488           case <code>NIL</code> is returned).  By default, the result is\r
1489           a string if the type of the <code>Content-Type</code>\r
1490           <a href="http://www.faqs.org/rfcs/rfc1590.html">media type</a>\r
1491           is <code>"text"</code>, and a vector of octets otherwise.  In\r
1492           the case of a string, the external format to be used to decode\r
1493           the content will be determined from the <code>charset</code>\r
1494           parameter sent by the client (or\r
1495           otherwise <clix:ref>*HUNCHENTOOT-DEFAULT-EXTERNAL-FORMAT*</clix:ref>\r
1496           will be used).\r
1497           <p>\r
1498             You can also provide an external format explicitly (through\r
1499             <clix:arg>external-format</clix:arg>) in which case the result\r
1500             will unconditionally be a string.  Likewise, you can provide\r
1501             a true value for <clix:arg>force-text</clix:arg> which will\r
1502             force Hunchentoot to act as if the type of the media type\r
1503             had been <code>"text"</code>\r
1504             (with <clix:arg>external-format</clix:arg> taking precedence\r
1505             if provided).  Or you can provide a true value\r
1506             for <clix:arg>force-binary</clix:arg> which means that you\r
1507             want a vector of octets at any rate.  (If both\r
1508             <clix:arg>force-text</clix:arg>\r
1509             and <clix:arg>force-binary</clix:arg> are true, an error will\r
1510             be signaled.)\r
1511           </p>\r
1512           <p>\r
1513             If, however, you provide a true value\r
1514             for <clix:arg>want-stream</clix:arg>, the other parameters are\r
1515             ignored and you'll get the content (flexi) stream to read\r
1516             from it yourself.  It is then your responsibility to read\r
1517             the correct amount of data, because otherwise you won't be\r
1518             able to return a response to the client.  The stream will\r
1519             have\r
1520             its <a href="http://weitz.de/flexi-streams/#flexi-streams">octet\r
1521               position</a> set to <code>0</code>.  If the client provided\r
1522             a <code>Content-Length</code> header, the stream will also\r
1523             have a\r
1524             corresponding <a href="http://weitz.de/flexi-streams/#flexi-streams">bound</a>,\r
1525             so no matter whether the client used chunked encoding or\r
1526             not, you can always read until EOF.\r
1527           </p>\r
1528           <p>\r
1529             If the content type of the request\r
1530             was <code>multipart/form-data</code>\r
1531             or <code>application/x-www-form-urlencoded</code>, the\r
1532             content has been read by Hunchentoot already and you can't\r
1533             read from the stream anymore.\r
1534           </p>\r
1535           <p>\r
1536             You can call <clix:ref>RAW-POST-DATA</clix:ref> more than once\r
1537             per request, but you can't mix calls which have different\r
1538             values for <clix:arg>want-stream</clix:arg>.\r
1539           </p>\r
1540           <p>\r
1541             Note that this function is slightly misnamed because a\r
1542             client can send content even if the request method is not\r
1543             POST.\r
1544           </p>\r
1545         </clix:description>\r
1546       </clix:function>\r
1549   <clix:function name='recompute-request-parameters'>\r
1550   <clix:lambda-list>\r
1551   <clix:lkw>key\r
1552   </clix:lkw> request external-format\r
1553   </clix:lambda-list>\r
1554   <clix:returns>|\r
1555   </clix:returns>\r
1556     <clix:description>Recomputes the GET and POST parameters for the <clix:ref>REQUEST</clix:ref> object\r
1557       <clix:arg>request</clix:arg>.  This only makes sense if you&#039;re switching external formats\r
1558 during the request.\r
1559     </clix:description>\r
1560   </clix:function>\r
1562   <clix:function generic='true' name='process-request'>\r
1563   <clix:lambda-list>request\r
1564   </clix:lambda-list>\r
1565   <clix:returns>nil\r
1566   </clix:returns>\r
1567     <clix:description>\r
1568 This function is called by <clix:ref>PROCESS-CONNECTION</clix:ref>\r
1569 after the incoming headers have been read.  It selects and calls a\r
1570 <a href="#handlers">handler</a> and sends the output of this handler\r
1571 to the client.  It also sets up simple error handling for the request\r
1572 handler.  Note that <clix:ref>PROCESS-CONNECTION</clix:ref> is called\r
1573 once per connection and loops in case of a persistent connection\r
1574 while <clix:ref>PROCESS-REQUEST</clix:ref> is called anew for each\r
1575 request.\r
1576 <p>\r
1577 Like <clix:ref>PROCESS-CONNECTION</clix:ref>, this might be a good\r
1578 place to introduce around methods which bind special variables or do\r
1579 other interesting things.\r
1580 </p>\r
1581 <p>\r
1582 The return value of this function is ignored.\r
1583 </p>\r
1584     </clix:description>\r
1585   </clix:function>\r
1589   <clix:readers generic='true'>\r
1590     <clix:listed-reader generic='true' name='cookies-in'>\r
1591     <clix:lambda-list>request\r
1592     </clix:lambda-list>\r
1593     <clix:returns>cookies\r
1594     </clix:returns>\r
1595     </clix:listed-reader>\r
1597     <clix:listed-reader generic='true' name='get-parameters'>\r
1598     <clix:lambda-list>request\r
1599     </clix:lambda-list>\r
1600     <clix:returns>get-parameters\r
1601     </clix:returns>\r
1602     </clix:listed-reader>\r
1604     <clix:listed-reader generic='true' name='header-in'>\r
1605     <clix:lambda-list>name request\r
1606     </clix:lambda-list>\r
1607     <clix:returns>result\r
1608     </clix:returns>\r
1609       <clix:description>\r
1610       </clix:description>\r
1611     </clix:listed-reader>\r
1613     <clix:listed-reader generic='true' name='headers-in'>\r
1614     <clix:lambda-list>request\r
1615     </clix:lambda-list>\r
1616     <clix:returns>headers\r
1617     </clix:returns>\r
1618     </clix:listed-reader>\r
1620     <clix:listed-reader generic='true' name='post-parameters'>\r
1621     <clix:lambda-list>request\r
1622     </clix:lambda-list>\r
1623     <clix:returns>post-parameters\r
1624     </clix:returns>\r
1625     </clix:listed-reader>\r
1627     <clix:listed-reader generic='true' name='query-string'>\r
1628     <clix:lambda-list>request\r
1629     </clix:lambda-list>\r
1630     <clix:returns>query-string\r
1631     </clix:returns>\r
1632     </clix:listed-reader>\r
1634     <clix:listed-reader generic='true' name='remote-addr'>\r
1635     <clix:lambda-list>request\r
1636     </clix:lambda-list>\r
1637     <clix:returns>address\r
1638     </clix:returns>\r
1639     </clix:listed-reader>\r
1641     <clix:listed-reader generic='true' name='remote-port'>\r
1642     <clix:lambda-list>request\r
1643     </clix:lambda-list>\r
1644     <clix:returns>port\r
1645     </clix:returns>\r
1646     </clix:listed-reader>\r
1648     <clix:listed-reader generic='true' name='request-acceptor'>\r
1649     <clix:lambda-list>request\r
1650     </clix:lambda-list>\r
1651     <clix:returns>acceptor\r
1652     </clix:returns>\r
1653     </clix:listed-reader>\r
1655     <clix:listed-reader generic='true' name='request-method'>\r
1656     <clix:lambda-list>request\r
1657     </clix:lambda-list>\r
1658     <clix:returns>method\r
1659     </clix:returns>\r
1660     </clix:listed-reader>\r
1662     <clix:listed-reader generic='true' name='request-uri'>\r
1663     <clix:lambda-list>request\r
1664     </clix:lambda-list>\r
1665     <clix:returns>uri\r
1666     </clix:returns>\r
1667     </clix:listed-reader>\r
1669     <clix:listed-reader generic='true' name='server-protocol'>\r
1670     <clix:lambda-list>request\r
1671     </clix:lambda-list>\r
1672     <clix:returns>protocol\r
1673     </clix:returns>\r
1674     </clix:listed-reader>\r
1676     <clix:listed-reader generic='true' name='script-name'>\r
1677     <clix:lambda-list>request\r
1678     </clix:lambda-list>\r
1679     <clix:returns>result\r
1680     </clix:returns>\r
1681     </clix:listed-reader>\r
1683     <clix:description>These are various generic readers which are used\r
1684     to read information about a <clix:ref>REQUEST</clix:ref> object.  If you are writing a\r
1685     <a href="#handlers">handler</a>, you should <em>not</em> use these readers but instead utilize the\r
1686     corresponding functions with an asterisk at the end of their name,\r
1687     also listed in this section.  These generic readers are only\r
1688     exported for users who want to create their own subclasses of\r
1689     <clix:ref>REQUEST</clix:ref>.\r
1690     </clix:description>\r
1692   </clix:readers>\r
1694     </clix:subchapter>\r
1696     <clix:subchapter name="replies" title="Reply objects">\r
1698 For each incoming request, the <a href="#acceptors">acceptor</a>\r
1699 (in <clix:ref>PROCESS-CONNECTION</clix:ref>) creates\r
1700 a <clix:ref>REPLY</clix:ref> object and makes it available\r
1701 to <a href="#handlers">handlers</a> via the special variable\r
1702 <clix:ref>*REPLY*</clix:ref>.  This object contains all relevant\r
1703 information (except for the content body) about the reply that will be\r
1704 sent to the client and this section collects the functions which can\r
1705 be used to query and modify such an object.  In all function\r
1706 where <clix:arg>reply</clix:arg> is an optional or keyword parameter,\r
1707 the default is <clix:ref>*REPLY*</clix:ref>.\r
1709 <p>\r
1710 If you need more fine-grained control over the behaviour of reply\r
1711 objects, you can subclass <clix:ref>REPLY</clix:ref> and initialize\r
1712 the <a href="#acceptor-reply-class"><code>REPLY-CLASS</code></a>\r
1713 slot of the <clix:ref>ACCEPTOR</clix:ref> class accordingly.  The\r
1714 acceptor will generate reply objects of the class named by this\r
1715 slot.\r
1716 </p>\r
1718   <clix:class name='reply'>\r
1719     <clix:description>Objects of this class hold all the information\r
1720 about an outgoing reply.  They are created automatically by\r
1721 Hunchentoot and can be accessed and modified by the corresponding\r
1722 <a href="#handlers">handler</a>.\r
1723 <p>\r
1724 You should not mess with the slots of these objects directly, but you\r
1725 can subclass <clix:ref>REPLY</clix:ref> in order to implement your own behaviour.  See the\r
1726 <a href="#acceptor-reply-class"><code>:reply-class</code></a> initarg\r
1727 of the <clix:ref>ACCEPTOR</clix:ref> class.\r
1728 </p>\r
1729     </clix:description>\r
1730   </clix:class>\r
1732   <clix:special-variable name='*reply*'>\r
1733     <clix:description>The current <clix:ref>REPLY</clix:ref> object in the context of a request.\r
1734     </clix:description>\r
1735   </clix:special-variable>\r
1738   <clix:accessor name='header-out'>\r
1739   <clix:lambda-list>name \r
1740   <clix:lkw>optional\r
1741   </clix:lkw> reply\r
1742   </clix:lambda-list>\r
1743   <clix:returns>string\r
1744   </clix:returns>\r
1745     <clix:description>\r
1746      <clix:ref>HEADER-OUT</clix:ref> returns the outgoing http header named by the keyword <clix:arg>name</clix:arg> if there is one, otherwise <code>NIL</code>. <code>SETF</code> of <clix:ref>HEADER-OUT</clix:ref> changes the current value of the header named <clix:arg>name</clix:arg>. If no header named <clix:arg>name</clix:arg> exists, it is created. For backwards compatibility, <clix:arg>name</clix:arg> can also be a string in which case the association between a header and its name is case-insensitive.\r
1747 <p>\r
1748     Note that the header 'Set-Cookie' cannot be queried by <clix:ref>HEADER-OUT</clix:ref> and must not be set by <code>SETF</code> of <clix:ref>HEADER-OUT</clix:ref>.\r
1749     See also <clix:ref>HEADERS-OUT*</clix:ref>, <clix:ref>CONTENT-TYPE*</clix:ref>, <clix:ref>CONTENT-LENGTH*</clix:ref>, <clix:ref>COOKIES-OUT*</clix:ref>, and <clix:ref>COOKIE-OUT</clix:ref>.\r
1750 </p>\r
1751     </clix:description>\r
1752   </clix:accessor>\r
1754   <clix:function name='headers-out*'>\r
1755   <clix:lambda-list>\r
1756   <clix:lkw>optional\r
1757   </clix:lkw> reply\r
1758   </clix:lambda-list>\r
1759   <clix:returns>alist\r
1760   </clix:returns>\r
1761     <clix:description>Returns an alist of the outgoing headers associated with the\r
1762 <clix:ref>REPLY</clix:ref> object <clix:arg>reply</clix:arg>.  See also <clix:ref>HEADER-OUT</clix:ref>.\r
1763     </clix:description>\r
1764   </clix:function>\r
1766   <clix:accessor name='content-length*'>\r
1767   <clix:lambda-list>\r
1768   <clix:lkw>optional\r
1769   </clix:lkw> reply\r
1770   </clix:lambda-list>\r
1771   <clix:returns>content-length\r
1772   </clix:returns>\r
1773     <clix:description>The outgoing &#039;Content-Length&#039; http header of <clix:arg>reply</clix:arg>.\r
1774     </clix:description>\r
1775   </clix:accessor>\r
1778   <clix:accessor name='content-type*'>\r
1779   <clix:lambda-list>\r
1780   <clix:lkw>optional\r
1781   </clix:lkw> reply\r
1782   </clix:lambda-list>\r
1783   <clix:returns>content-type\r
1784   </clix:returns>\r
1785     <clix:description>The outgoing &#039;Content-Type&#039; http header of <clix:arg>reply</clix:arg>.\r
1786     </clix:description>\r
1787   </clix:accessor>\r
1789   <clix:function name='cookie-out'>\r
1790   <clix:lambda-list>name \r
1791   <clix:lkw>optional\r
1792   </clix:lkw> reply\r
1793   </clix:lambda-list>\r
1794   <clix:returns>result\r
1795   </clix:returns>\r
1796     <clix:description>Returns the current value of the outgoing <a href="#cookies">cookie</a> named\r
1797 <clix:arg>name</clix:arg>. Search is case-sensitive.\r
1798     </clix:description>\r
1799   </clix:function>\r
1801   <clix:accessor name='cookies-out*'>\r
1802   <clix:lambda-list>\r
1803   <clix:lkw>optional\r
1804   </clix:lkw> reply\r
1805   </clix:lambda-list>\r
1806   <clix:returns>alist\r
1807   </clix:returns>\r
1808     <clix:description>Returns or sets an alist of the outgoing <a href="#cookies">cookies</a> associated with the\r
1809 <clix:ref>REPLY</clix:ref> object <clix:arg>reply</clix:arg>.\r
1810     </clix:description>\r
1811   </clix:accessor>\r
1813   <clix:accessor name='return-code*'>\r
1814   <clix:lambda-list>\r
1815   <clix:lkw>optional\r
1816   </clix:lkw> reply\r
1817   </clix:lambda-list>\r
1818   <clix:returns>return-code\r
1819   </clix:returns>\r
1820     <clix:description>Gets or sets the http return code\r
1821     of <clix:arg>reply</clix:arg>.  The return code of\r
1822     each <clix:ref>REPLY</clix:ref> object is initially set\r
1823     to <clix:ref>+HTTP-OK+</clix:ref>.\r
1824     </clix:description>\r
1825   </clix:accessor>\r
1827       <clix:function name="send-headers">\r
1828         <clix:returns>stream</clix:returns>\r
1829         <clix:description>\r
1830           Sends the initial status line and all headers as determined\r
1831           by the <clix:ref>REPLY</clix:ref>\r
1832           object <clix:ref>*REPLY*</clix:ref>.  Returns\r
1833           a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_b.htm#binary">binary</a>\r
1834           stream to which the body of the reply can be written.  Once\r
1835           this function has been called, further changes\r
1836           to <clix:ref>*REPLY*</clix:ref> don't have any effect.\r
1837           Also, automatic handling of errors (i.e. sending the\r
1838           corresponding status code to the browser, etc.) is turned\r
1839           off for this request and functions\r
1840           like <clix:ref>REDIRECT</clix:ref> or\r
1841           to <clix:ref>ABORT-REQUEST-HANDLER</clix:ref> won't have the\r
1842           desired effect once the headers are sent.\r
1843           <p>\r
1844             If your handlers return the full body as a string or as an\r
1845             array of octets, you should <em>not</em> call this function.\r
1846             If a handler calls <clix:ref>SEND-HEADERS</clix:ref> , its\r
1847             return value is ignored.\r
1848           </p>\r
1849         </clix:description>\r
1850       </clix:function>\r
1852   <clix:accessor name='reply-external-format*'>\r
1853   <clix:lambda-list>\r
1854   <clix:lkw>optional\r
1855   </clix:lkw> reply\r
1856   </clix:lambda-list>\r
1857   <clix:returns>external-format\r
1858   </clix:returns>\r
1859     <clix:description>Gets or sets the external format of <clix:arg>reply</clix:arg> which is used for character output.\r
1860     </clix:description>\r
1861   </clix:accessor>\r
1863   <clix:special-variable name='*default-content-type*'>\r
1864     <clix:description>The default content-type header which is returned to the client.\r
1865     </clix:description>\r
1866   </clix:special-variable>\r
1868       <clix:constants>\r
1869         <clix:listed-constant name="+http-continue+"/>\r
1870         <clix:listed-constant name="+http-switching-protocols+"/>\r
1871         <clix:listed-constant name="+http-ok+"/>\r
1872         <clix:listed-constant name="+http-created+"/>\r
1873         <clix:listed-constant name="+http-accepted+"/>\r
1874         <clix:listed-constant name="+http-non-authoritative-information+"/>\r
1875         <clix:listed-constant name="+http-no-content+"/>\r
1876         <clix:listed-constant name="+http-reset-content+"/>\r
1877         <clix:listed-constant name="+http-partial-content+"/>\r
1878         <clix:listed-constant name="+http-multi-status+"/>\r
1879         <clix:listed-constant name="+http-multiple-choices+"/>\r
1880         <clix:listed-constant name="+http-moved-permanently+"/>\r
1881         <clix:listed-constant name="+http-moved-temporarily+"/>\r
1882         <clix:listed-constant name="+http-see-other+"/>\r
1883         <clix:listed-constant name="+http-not-modified+"/>\r
1884         <clix:listed-constant name="+http-use-proxy+"/>\r
1885         <clix:listed-constant name="+http-temporary-redirect+"/>\r
1886         <clix:listed-constant name="+http-bad-request+"/>\r
1887         <clix:listed-constant name="+http-authorization-required+"/>\r
1888         <clix:listed-constant name="+http-payment-required+"/>\r
1889         <clix:listed-constant name="+http-forbidden+"/>\r
1890         <clix:listed-constant name="+http-not-found+"/>\r
1891         <clix:listed-constant name="+http-method-not-allowed+"/>\r
1892         <clix:listed-constant name="+http-not-acceptable+"/>\r
1893         <clix:listed-constant name="+http-proxy-authentication-required+"/>\r
1894         <clix:listed-constant name="+http-request-time-out+"/>\r
1895         <clix:listed-constant name="+http-conflict+"/>\r
1896         <clix:listed-constant name="+http-gone+"/>\r
1897         <clix:listed-constant name="+http-length-required+"/>\r
1898         <clix:listed-constant name="+http-precondition-failed+"/>\r
1899         <clix:listed-constant name="+http-request-entity-too-large+"/>\r
1900         <clix:listed-constant name="+http-request-uri-too-large+"/>\r
1901         <clix:listed-constant name="+http-unsupported-media-type+"/>\r
1902         <clix:listed-constant name="+http-requested-range-not-satisfiable+"/>\r
1903         <clix:listed-constant name="+http-expectation-failed+"/>\r
1904         <clix:listed-constant name="+http-failed-dependency+"/>\r
1905         <clix:listed-constant name="+http-internal-server-error+"/>\r
1906         <clix:listed-constant name="+http-not-implemented+"/>\r
1907         <clix:listed-constant name="+http-bad-gateway+"/>\r
1908         <clix:listed-constant name="+http-service-unavailable+"/>\r
1909         <clix:listed-constant name="+http-gateway-time-out+"/>\r
1910         <clix:listed-constant name="+http-version-not-supported+"/>\r
1911         <clix:description>\r
1912           The values of these constants are 100, 101, 200, 201, 202,\r
1913           203, 204, 205, 206, 207, 300, 301, 302, 303, 304, 305, 307,\r
1914           400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411,\r
1915           412, 413, 414, 415, 416, 417, 424, 500, 501, 502, 503, 504,\r
1916           and 505. See <clix:ref>RETURN-CODE</clix:ref>.\r
1917         </clix:description>\r
1918       </clix:constants>\r
1920   <clix:readers generic='true'>\r
1921     <clix:listed-reader generic='true' name='content-length'>\r
1922     <clix:lambda-list>reply\r
1923     </clix:lambda-list>\r
1924     <clix:returns>content-length\r
1925     </clix:returns>\r
1926     </clix:listed-reader>\r
1928     <clix:listed-reader generic='true' name='content-type'>\r
1929     <clix:lambda-list>reply\r
1930     </clix:lambda-list>\r
1931     <clix:returns>content-type\r
1932     </clix:returns>\r
1933     </clix:listed-reader>\r
1935     <clix:listed-reader generic='true' name='headers-out'>\r
1936     <clix:lambda-list>reply\r
1937     </clix:lambda-list>\r
1938     <clix:returns>headers-out\r
1939     </clix:returns>\r
1940     </clix:listed-reader>\r
1942     <clix:description>These are various generic readers which are used\r
1943     to read information about a <clix:ref>REPLY</clix:ref> object.  If you are writing a\r
1944     <a href="#handlers">handler</a>, you should <em>not</em> use these readers but instead utilize the\r
1945     corresponding functions with an asterisk at the end of their name,\r
1946     also listed in this section.  These generic readers are only\r
1947     exported for users who want to create their own subclasses of\r
1948     <clix:ref>REPLY</clix:ref>.\r
1949     </clix:description>\r
1950   </clix:readers>\r
1952   <clix:accessors generic='true'>\r
1953     <clix:listed-accessor generic='true' name='cookies-out'>\r
1954     <clix:lambda-list>reply\r
1955     </clix:lambda-list>\r
1956     <clix:returns>result\r
1957     </clix:returns>\r
1958     </clix:listed-accessor>\r
1960     <clix:listed-accessor generic='true' name='return-code'>\r
1961     <clix:lambda-list>reply\r
1962     </clix:lambda-list>\r
1963     <clix:returns>result\r
1964     </clix:returns>\r
1965     </clix:listed-accessor>\r
1967     <clix:listed-accessor generic='true' name='reply-external-format'>\r
1968     <clix:lambda-list>reply\r
1969     </clix:lambda-list>\r
1970     <clix:returns>result\r
1971     </clix:returns>\r
1972     </clix:listed-accessor>\r
1974     <clix:description>These are various generic accessors which are\r
1975     used to query and modify a <clix:ref>REPLY</clix:ref> objects.  If\r
1976     you are writing a\r
1977     <a href="#handlers">handler</a>, you should <em>not</em> use these\r
1978     accessors but instead utilize the corresponding functions with an\r
1979     asterisk at the end of their name, also listed in this section.\r
1980     These generic accessors are only exported for users who want to\r
1981     create their own subclasses of\r
1982     <clix:ref>REPLY</clix:ref>.\r
1983     </clix:description>\r
1984   </clix:accessors>\r
1987     </clix:subchapter>\r
1989     <clix:subchapter name="sessions" title="Sessions">\r
1990 Hunchentoot supports <em>sessions</em>: Once a <a href="#handlers">request\r
1991 handler</a> has called <clix:ref>START-SESSION</clix:ref>, Hunchentoot\r
1992 uses either cookies or (if the client doesn't send the cookies\r
1993 back) <a href="#*rewrite-for-session-urls*">rewrites URLs</a> to keep\r
1994 track of this client, i.e. to provide a kind of 'state' for the\r
1995 stateless http protocol. The session associated with the client is a\r
1996 <a href="#session">CLOS object</a> which can be used\r
1997 to <a href="#session-value">store arbitrary data</a> between requests.\r
1998 <p>\r
1999 Hunchentoot makes some reasonable effort to prevent eavesdroppers from\r
2000 hijacking sessions (see below), but this should not be considered\r
2001 really secure. Don't store sensitive data in sessions and rely solely\r
2002 on the session mechanism as a safeguard against malicious users who\r
2003 want to get at this data!\r
2004 </p>\r
2005 <p>\r
2006 For each request there's one <clix:ref>SESSION</clix:ref> object which is accessible to the\r
2007 <a href="#handler">handler</a> via the special\r
2008 variable <clix:ref>*SESSION*</clix:ref>. This object holds all the\r
2009 information available about the session and can be accessed with the\r
2010 functions described in this chapter. Note that the internal structure\r
2011 of <clix:ref>SESSION</clix:ref> objects should be considered opaque\r
2012 and may change in future releases of Hunchentoot.\r
2013 </p>\r
2014 <p>\r
2015 Sessions are automatically <a href="#session-verify">verified</a> for\r
2016 validity and age when the <clix:ref>REQUEST</clix:ref> object is\r
2017 instantiated, i.e. if <clix:ref>*SESSION*</clix:ref> is not NIL then\r
2018 this session is valid (as far as Hunchentoot is concerned) and\r
2019 not <a href="#session-too-old-p">too old</a>.  Old sessions\r
2020 are <a href="#session-gc">automatically removed</a>.\r
2021 </p>\r
2023   <clix:class name='session'>\r
2024     <clix:description><clix:ref>SESSION</clix:ref> objects are\r
2025 automatically maintained by Hunchentoot.  They should not be created\r
2026 explicitly with <code>MAKE-INSTANCE</code> but implicitly\r
2027 with <clix:ref>START-SESSION</clix:ref> and they should be treated as\r
2028 opaque objects.\r
2029 <p>\r
2030 You can ignore Hunchentoot's <clix:ref>SESSION</clix:ref> objects and\r
2031 <a href="#session-behaviour">implement your own sessions</a> if you provide corresponding methods for\r
2032 <clix:ref>SESSION-COOKIE-VALUE</clix:ref>\r
2033 and <clix:ref>SESSION-VERIFY</clix:ref>.\r
2034 </p>\r
2035     </clix:description>\r
2036   </clix:class>\r
2038   <clix:function name='start-session'>\r
2039   <clix:lambda-list>\r
2040   </clix:lambda-list>\r
2041   <clix:returns>session\r
2042   </clix:returns>\r
2043     <clix:description>Returns the current <clix:ref>SESSION</clix:ref>\r
2044 object. If there is no current session, creates one and updates the\r
2045 corresponding data structures. In this case the function will also\r
2046 send a session cookie to the browser.\r
2047     </clix:description>\r
2048   </clix:function>\r
2050   <clix:accessor name='session-value'>\r
2051   <clix:lambda-list>symbol \r
2052   <clix:lkw>optional\r
2053   </clix:lkw> session\r
2054   </clix:lambda-list>\r
2055   <clix:returns>value, present-p\r
2056   </clix:returns>\r
2057     <clix:description>\r
2058 This accessor can be used to associate arbitrary data with the the\r
2059 symbol <clix:arg>symbol</clix:arg> in the <clix:ref>SESSION</clix:ref>\r
2060 object <clix:arg>session</clix:arg>. <clix:arg>present-p</clix:arg> is\r
2061 true if such data was found, otherwise <code>NIL</code>. The default\r
2062 value for <clix:arg>session</clix:arg> is\r
2063 <clix:ref>*SESSION*</clix:ref>.\r
2064 <p>\r
2065 If <code>SETF</code> of <clix:ref>SESSION-VALUE</clix:ref> is called\r
2066 with <clix:arg>session</clix:arg> being <code>NIL</code> then a\r
2067 session is automatically instantiated\r
2068 with <clix:ref>START-SESSION</clix:ref>.\r
2069 </p>\r
2070     </clix:description>\r
2071   </clix:accessor>\r
2073   <clix:function name='delete-session-value'>\r
2074   <clix:lambda-list>symbol \r
2075   <clix:lkw>optional\r
2076   </clix:lkw> session\r
2077   </clix:lambda-list>\r
2078   <clix:returns>|\r
2079   </clix:returns>\r
2080     <clix:description>Removes the value associated\r
2081 with <clix:arg>symbol</clix:arg> from <clix:arg>session</clix:arg> if\r
2082 there is one.\r
2083     </clix:description>\r
2084   </clix:function>\r
2088   <clix:special-variable name='*session*'>\r
2089     <clix:description>The current session while in the context of a\r
2090     request, or <code>NIL</code>.\r
2091     </clix:description>\r
2092   </clix:special-variable>\r
2094   <clix:function name='remove-session'>\r
2095   <clix:lambda-list>session\r
2096   </clix:lambda-list>\r
2097   <clix:returns>|\r
2098   </clix:returns>\r
2099     <clix:description>Completely removes\r
2100 the <clix:ref>SESSION</clix:ref> object <clix:arg>session</clix:arg>\r
2101 from Hunchentoot&#039;s internal <a href="#session-db">session\r
2102 database</a>.\r
2103     </clix:description>\r
2104   </clix:function>\r
2107   <clix:function name='reset-sessions'>\r
2108   <clix:lambda-list>\r
2109   </clix:lambda-list>\r
2110   <clix:returns>|\r
2111   </clix:returns>\r
2112     <clix:description>Removes <em>all</em> stored sessions.\r
2113     </clix:description>\r
2114   </clix:function>\r
2117   <clix:special-variable name='*rewrite-for-session-urls*'>\r
2118     <clix:description>Whether HTML pages should possibly be rewritten for cookie-less\r
2119 session-management.\r
2120     </clix:description>\r
2121   </clix:special-variable>\r
2123   <clix:special-variable name='*content-types-for-url-rewrite*'>\r
2124     <clix:description>The content types for which url-rewriting is\r
2125     OK. See\r
2126 <clix:ref>*REWRITE-FOR-SESSION-URLS*</clix:ref>.\r
2127     </clix:description>\r
2128   </clix:special-variable>\r
2131   <clix:special-variable name='*use-remote-addr-for-sessions*'>\r
2132     <clix:description>Whether the client&#039;s remote IP (as returned by <clix:ref>REAL-REMOTE-ADDR</clix:ref>)\r
2133 should be encoded into the session string.  If this value is true, a\r
2134 session will cease to be accessible if the client&#039;s remote IP changes.\r
2135 <p>\r
2136 This might for example be an issue if the client uses a proxy server\r
2137 which doesn&#039;t send correct &#039;X_FORWARDED_FOR&#039; headers.\r
2138 </p>\r
2139     </clix:description>\r
2140   </clix:special-variable>\r
2142   <clix:function generic='true' name='session-remote-addr'>\r
2143   <clix:lambda-list>session\r
2144   </clix:lambda-list>\r
2145   <clix:returns>remote-addr\r
2146   </clix:returns>\r
2147     <clix:description>\r
2148 The remote IP address of the client when this session was started (as\r
2149 returned by <clix:ref>REAL-REMOTE-ADDR</clix:ref>).\r
2150     </clix:description>\r
2151   </clix:function>\r
2154   <clix:special-variable name='*use-user-agent-for-sessions*'>\r
2155     <clix:description>Whether the &#039;User-Agent&#039; header should\r
2156 be encoded into the session string.  If this value is true, a session\r
2157 will cease to be accessible if the client sends a different\r
2158 &#039;User-Agent&#039; header.\r
2159     </clix:description>\r
2160   </clix:special-variable>\r
2162   <clix:function generic='true' name='session-user-agent'>\r
2163   <clix:lambda-list>session\r
2164   </clix:lambda-list>\r
2165   <clix:returns>user-agent\r
2166   </clix:returns>\r
2167     <clix:description>\r
2168 The incoming &#039;User-Agent&#039; header that\r
2169 was sent when this session was created.\r
2170     </clix:description>\r
2171   </clix:function>\r
2174   <clix:accessor generic='true' name='session-max-time'>\r
2175   <clix:lambda-list>session\r
2176   </clix:lambda-list>\r
2177   <clix:returns>max-time\r
2178   </clix:returns>\r
2179     <clix:description>\r
2180 Gets or sets the time (in seconds) after\r
2181 which <clix:arg>session</clix:arg> expires if it's not used.\r
2182     </clix:description>\r
2183   </clix:accessor>\r
2186   <clix:special-variable name='*session-max-time*'>\r
2187     <clix:description>The default time (in seconds) after which a session times out.\r
2188     </clix:description>\r
2189   </clix:special-variable>\r
2191   <clix:special-variable name='*session-gc-frequency*'>\r
2192     <clix:description>A session GC (see function <clix:ref>SESSION-GC</clix:ref>) will happen every\r
2193 <clix:ref>*SESSION-GC-FREQUENCY*</clix:ref> requests (counting only\r
2194 requests which create a new session) if this variable is\r
2195 not <code>NIL</code>.  See <clix:ref>SESSION-CREATED</clix:ref>.\r
2196     </clix:description>\r
2197   </clix:special-variable>\r
2199   <clix:function name='session-gc'>\r
2200   <clix:lambda-list>\r
2201   </clix:lambda-list>\r
2202   <clix:returns>|\r
2203   </clix:returns>\r
2204     <clix:description>Removes sessions from the current session database which are too\r
2205 old - see <clix:ref>SESSION-TOO-OLD-P</clix:ref>.\r
2206     </clix:description>\r
2207   </clix:function>\r
2209   <clix:function name='session-too-old-p'>\r
2210   <clix:lambda-list>session\r
2211   </clix:lambda-list>\r
2212   <clix:returns>generalized-boolean\r
2213   </clix:returns>\r
2214     <clix:description>Returns true if the <clix:ref>SESSION</clix:ref> object <clix:arg>session</clix:arg> has not been active in\r
2215 the last <code>(session-max-time session)</code> seconds.\r
2216     </clix:description>\r
2217   </clix:function>\r
2220   <clix:special-variable name='*session-removal-hook*'>\r
2221     <clix:description>A function of one argument\r
2222 (a <clix:ref>SESSION</clix:ref> object) which is called whenever a\r
2223 session is <a href="#session-gc">garbage-collected</a>.\r
2224     </clix:description>\r
2225   </clix:special-variable>\r
2228     </clix:subchapter>\r
2231     <clix:subchapter name="session-behaviour" title="Customizing session behaviour">\r
2233 For everyday session usage, you will probably just\r
2234 use <clix:ref>START-SESSION</clix:ref>,\r
2235 <clix:ref>SESSION-VALUE</clix:ref>,\r
2236 and maybe <clix:ref>DELETE-SESSION-VALUE</clix:ref>\r
2237 and <clix:ref>*SESSION*</clix:ref>.  However, there are two ways to\r
2238 customize the way Hunchentoot maintains sessions.\r
2239 <p>\r
2240 One way is to mostly leave the session mechanism intact but to tweak\r
2241 it a bit:\r
2242 <ul>\r
2243 <li>The publicly visible part of a session is encoded using a\r
2244 <a href="#*session-secret*">secret</a> which you can set yourself.</li>\r
2245 <li>And it is stored using a cookie (or GET\r
2246 parameter) <a href="#session-cookie-name">name</a> that you can\r
2247 override.</li>\r
2248 <li>Each session receives a <a href="#next-session-id">new ID</a> when\r
2249 it is created and you can implement a more robust way to do that.</li>\r
2250 <li>You can arrange to be called whenever a session\r
2251 is <a href="#session-created">created</a> to trigger some action.  You\r
2252 might also do this to invent your own\r
2253 session <a href="#session-gc">garbage collection</a>.</li>\r
2254 <li>By default, all sessions are stored in a global alist in memory.\r
2255 You can't change the alist part, but you can distribute your sessions\r
2256 over different <a href="#session-db">"databases"</a>.</li>\r
2257 <li>By default, every operation which modifies sessions or one of the\r
2258 session databases is guarded by a global lock, but you can arrange to\r
2259 <a href="#session-db-lock">provide</a> different locks for this.</li>\r
2260 </ul>\r
2261 </p>\r
2262 <p>\r
2263 The other way to customize Hunchentoot's sessions is to completely\r
2264 replace them.  This is actually pretty easy: Create your own class to\r
2265 store state (which doesn't have to and probably shouldn't inherit\r
2266 from <clix:ref>SESSION</clix:ref>) and implement methods for\r
2267 <clix:ref>SESSION-VERIFY</clix:ref>\r
2268 and <clix:ref>SESSION-COOKIE-VALUE</clix:ref> - that's it.\r
2269 Hunchentoot will continue to use cookies and/or to rewrite URLs to\r
2270 keep track of session state and it will store "the current session"\r
2271 (whatever that is in your implementation)\r
2272 in <clix:ref>*SESSION*</clix:ref>.  Everything else (like persisting\r
2273 sessions, GC, getting and setting values) you'll have to take care of\r
2274 yourself and the other session functions\r
2275 (like <clix:ref>START-SESSION</clix:ref> or\r
2276 <clix:ref>SESSION-VALUE</clix:ref>) won't work anymore.  (Almost)\r
2277 total freedom, but a lot of responsibility as well... :)\r
2278 </p>\r
2280   <clix:special-variable name='*session-secret*'>\r
2281     <clix:description>A random ASCII string that&#039;s used to encode\r
2282 the public session data.  This variable is initially unbound and will\r
2283 be set (using <clix:ref>RESET-SESSION-SECRET</clix:ref>) the first\r
2284 time a session is created, if necessary.  You can prevent this from\r
2285 happening if you set the value yourself before\r
2286 starting <a href="#acceptors">acceptors</a>.\r
2287     </clix:description>\r
2288   </clix:special-variable>\r
2290   <clix:function name='reset-session-secret'>\r
2291   <clix:lambda-list>\r
2292   </clix:lambda-list>\r
2293   <clix:returns>secret\r
2294   </clix:returns>\r
2295     <clix:description>Sets <clix:ref>*SESSION-SECRET*</clix:ref> to a\r
2296 new random value. All old sessions will cease to be valid.\r
2297     </clix:description>\r
2298   </clix:function>\r
2302   <clix:function generic='true' name='session-cookie-name'>\r
2303   <clix:lambda-list>acceptor\r
2304   </clix:lambda-list>\r
2305   <clix:returns>name\r
2306   </clix:returns>\r
2307     <clix:description>Returns the name (a string) of the cookie (or\r
2308 the GET parameter) which is used to store a session on the client\r
2309 side.  The default is to use the\r
2310 string <code>&quot;hunchentoot-session&quot;</code>, but you can\r
2311 specialize this function if you want another name.\r
2312     </clix:description>\r
2313   </clix:function>\r
2315   <clix:function generic='true' name='session-created'>\r
2316   <clix:lambda-list>acceptor new-session\r
2317   </clix:lambda-list>\r
2318   <clix:returns>result\r
2319   </clix:returns>\r
2320     <clix:description>This function is called whenever a new session\r
2321 has been created.  There&#039;s a default method which might trigger\r
2322 a <a href="#session-gc">session GC</a> based on the value of\r
2323 <clix:ref>*SESSION-GC-FREQUENCY*</clix:ref>.\r
2324 <p>\r
2325 The return value is ignored.\r
2326 </p>\r
2327     </clix:description>\r
2328   </clix:function>\r
2331   <clix:function generic='true' name='next-session-id'>\r
2332   <clix:lambda-list>acceptor\r
2333   </clix:lambda-list>\r
2334   <clix:returns>id\r
2335   </clix:returns>\r
2336     <clix:description>Returns the next sequential session ID, an\r
2337 integer, which should be unique per session.  The default method uses\r
2338 a simple global counter and isn&#039;t guarded by a lock.  For a\r
2339 high-performance production environment you might consider using a\r
2340 more robust implementation.\r
2341     </clix:description>\r
2342   </clix:function>\r
2344   <clix:accessor generic='true' name='session-db'>\r
2345   <clix:lambda-list>acceptor\r
2346   </clix:lambda-list>\r
2347   <clix:returns>database\r
2348   </clix:returns>\r
2349     <clix:description>Returns the current session database which is an\r
2350 alist where each car is a session&#039;s ID and the cdr is the\r
2351 corresponding <clix:ref>SESSION</clix:ref> object itself.  The default\r
2352 is to use a global list for all acceptors.\r
2353     </clix:description>\r
2354   </clix:accessor>\r
2356   <clix:function generic='true' name='session-db-lock'>\r
2357   <clix:lambda-list>acceptor \r
2358   <clix:lkw>key\r
2359   </clix:lkw> whole-db-p\r
2360   </clix:lambda-list>\r
2361   <clix:returns>lock\r
2362   </clix:returns>\r
2363     <clix:description>A function which returns a lock that will be\r
2364 used to prevent concurrent access to sessions.  The first argument\r
2365 will be the <a href="#acceptors">acceptor</a> that handles the\r
2366 current <a href="#requests">request</a>, the second argument is true\r
2367 if the whole (current) session database is modified.  If it\r
2368 is <code>NIL</code>, only one existing session in the database is\r
2369 modified.\r
2370 <p>\r
2371 This function can return <code>NIL</code> which means that sessions or\r
2372 session databases will be modified without a lock held (for example\r
2373 for single-threaded environments).  The default is to always return a\r
2374 global lock (ignoring the <clix:arg>acceptor</clix:arg> argument) for\r
2375 Lisps that support threads and <code>NIL</code> otherwise.\r
2376 </p>\r
2377     </clix:description>\r
2378   </clix:function>\r
2380   <clix:function generic='true' name='session-verify'>\r
2381   <clix:lambda-list>request\r
2382   </clix:lambda-list>\r
2383   <clix:returns>session-or-nil\r
2384   </clix:returns>\r
2385     <clix:description>Tries to get a session identifier from the cookies\r
2386 (or alternatively from the GET parameters) sent by the client (see\r
2387 <clix:ref>SESSION-COOKIE-NAME</clix:ref>\r
2388 and <clix:ref>SESSION-COOKIE-VALUE</clix:ref>).  This identifier is\r
2389 then checked for validity against the <clix:ref>REQUEST</clix:ref>\r
2390 object\r
2391 <clix:arg>request</clix:arg>.  On success the corresponding session object (if not too\r
2392 old) is returned (and updated).  Otherwise <code>NIL</code> is returned.\r
2393 <p>\r
2394 A default method is provided and you only need to write your own one\r
2395 if you want to maintain your own sessions.\r
2396 </p>\r
2397     </clix:description>\r
2398   </clix:function>\r
2400   <clix:function generic='true' name='session-cookie-value'>\r
2401   <clix:lambda-list>session\r
2402   </clix:lambda-list>\r
2403   <clix:returns>string\r
2404   </clix:returns>\r
2405     <clix:description>Returns a string which can be used to safely\r
2406 restore the session <clix:arg>session</clix:arg> if as session has\r
2407 already been established.  This is used as the value stored in the\r
2408 session cookie or in the corresponding GET parameter and verified\r
2409 by <clix:ref>SESSION-VERIFY</clix:ref>.\r
2410 <p>\r
2411 A default\r
2412 method is provided and there&#039;s no reason to change it unless you\r
2413 want to use your own session objects.\r
2414 </p>\r
2415     </clix:description>\r
2416   </clix:function>\r
2419     </clix:subchapter>\r
2421     <clix:subchapter name="cookies" title="Cookies">\r
2423       Outgoing cookies are stored in the request's <clix:ref>REPLY</clix:ref>\r
2424       object (see <clix:ref>COOKIE-OUT</clix:ref>\r
2425       and <clix:ref>COOKIES-OUT*</clix:ref>). They are CLOS objects\r
2426       defined like this:\r
2428       <pre>(defclass cookie ()\r
2429   ((name :initarg :name\r
2430          :reader <a class="noborder" name="cookie-name">cookie-name</a>\r
2431          :type string\r
2432          :documentation "The name of the cookie - a string.")\r
2433    (value :initarg :value\r
2434           :accessor <a class="noborder" name="cookie-value">cookie-value</a>\r
2435           :initform ""\r
2436           :documentation "The value of the cookie. Will be URL-encoded when sent to the browser.")\r
2437    (expires :initarg :expires\r
2438             :initform nil\r
2439             :accessor <a class="noborder" name="cookie-expires">cookie-expires</a>\r
2440             :documentation "The time (a universal time) when the cookie expires (or NIL).")\r
2441    (path :initarg :path\r
2442          :initform nil\r
2443          :accessor <a class="noborder" name="cookie-path">cookie-path</a>\r
2444          :documentation "The path this cookie is valid for (or NIL).")\r
2445    (domain :initarg :domain\r
2446            :initform nil\r
2447            :accessor <a class="noborder" name="cookie-domain">cookie-domain</a>\r
2448            :documentation "The domain this cookie is valid for (or NIL).")\r
2449    (secure :initarg :secure\r
2450            :initform nil\r
2451            :accessor <a class="noborder" name="cookie-secure">cookie-secure</a>\r
2452            :documentation "A generalized boolean denoting whether this is a secure cookie.")\r
2453    (http-only :initarg :http-only\r
2454               :initform nil\r
2455               :accessor <a class="noborder" name="cookie-http-only">cookie-http-only</a>\r
2456               :documentation "A generalized boolean denoting whether this is a <a href="http://msdn2.microsoft.com/en-us/library/ms533046.aspx">HttpOnly</a> cookie.")))</pre>\r
2458       The <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_r.htm#reader">reader</a>\r
2459       <clix:ref>COOKIE-NAME</clix:ref> and\r
2460       the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#accessor">accessors</a>\r
2461       <clix:ref>COOKIE-VALUE</clix:ref>, <clix:ref>COOKIE-EXPIRES</clix:ref>,\r
2462       <clix:ref>COOKIE-PATH</clix:ref>, <clix:ref>COOKIE-DOMAIN</clix:ref>, <clix:ref>COOKIE-SECURE</clix:ref>,\r
2463       and <clix:ref>COOKIE-HTTP-ONLY</clix:ref> are all exported from\r
2464       the <code>HUNCHENTOOT</code> package.  For now, the class name itself is <em>not</em> exported.\r
2466       <clix:function name="set-cookie">\r
2467         <clix:lambda-list>\r
2468           name <clix:lkw>key</clix:lkw> value expires path\r
2469           domain secure http-only reply\r
2470         </clix:lambda-list>\r
2471         <clix:returns>cookie</clix:returns>\r
2472         <clix:description>\r
2473           Creates a <code>COOKIE</code> object from the parameters\r
2474           provided to this function and adds it to the outgoing cookies\r
2475           of the <a href="#replies"><code>REPLY</code> object</a>\r
2476           <clix:arg>reply</clix:arg>. If a cookie with the same name\r
2477           (case-sensitive) already exists, it is replaced. The default\r
2478           for <clix:arg>reply</clix:arg>\r
2479           is <clix:ref>*REPLY*</clix:ref>. The default\r
2480           for <clix:arg>value</clix:arg> is the empty string.\r
2481         </clix:description>\r
2482       </clix:function>\r
2484       <clix:function name="set-cookie*">\r
2485         <clix:lambda-list>cookie <clix:lkw>optional</clix:lkw> reply</clix:lambda-list>\r
2486         <clix:returns>cookie</clix:returns>\r
2487         <clix:description>\r
2488           Adds the <code>COOKIE</code> object <clix:arg>cookie</clix:arg>\r
2489           to the outgoing cookies of\r
2490           the <a href="#replies"><code>REPLY</code> object</a>\r
2491           <clix:arg>reply</clix:arg>. If a cookie with the same name\r
2492           (case-sensitive) already exists, it is replaced. The default\r
2493           for <clix:arg>reply</clix:arg> is <clix:ref>*REPLY*</clix:ref>.\r
2494         </clix:description>\r
2495       </clix:function>\r
2496     </clix:subchapter>\r
2499     <clix:subchapter name="logging" title="Logging">\r
2501 By default, Hunchentoot logs accesses and errors to two separate files\r
2502 in the file system, but <em>only</em> if the special variables\r
2503 <clix:ref>*MESSAGE-LOG-PATHNAME*</clix:ref> and <clix:ref>*ACCESS-LOG-PATHNAME*</clix:ref> are set accordingly.\r
2504 Access logging is done in a format similar to what\r
2505 the Apache web server can write so that logfile analysis using\r
2506 standard tools is possible.  Errors during request processing are\r
2507 logged to a separate file.\r
2508 <p>\r
2509 The standard logging mechanism is deliberately simple and slow.  The\r
2510 log files are opened for each log entry and closed again after\r
2511 writing, and access to them is protected by a global lock.  If you\r
2512 want more sophisticated logging, use\r
2513 the <a href="#acceptor-access-logger"><code>:access-logger</code></a>\r
2514 and <a href="#acceptor-message-logger"><code>:message-logger</code></a>\r
2515 initargs of the acceptor class to establish your own logging\r
2516 functions.  See the docstrings of the corresponding slots for more\r
2517 information.\r
2518 </p>\r
2519 <p>\r
2520 Errors happening within a <a href="#handlers">handler</a> which are\r
2521 not caught by the handler itself are handled by Hunchentoot by logging\r
2522 them to the log file.\r
2523 </p>\r
2525   <clix:function name='log-message'>\r
2526   <clix:lambda-list>log-level format-string \r
2527   <clix:lkw>rest\r
2528   </clix:lkw> format-arguments\r
2529   </clix:lambda-list>\r
2530   <clix:returns>result\r
2531   </clix:returns>\r
2532     <clix:description>Convenience function which calls the message\r
2533 logger of the current acceptor (if there is one) with the same\r
2534 arguments it accepts.  Returns <code>NIL</code> if there is no message\r
2535 logger or whatever the message logger returns.\r
2536 <p>\r
2537 This is the function which Hunchentoot itself uses to log errors it\r
2538 catches during request processing.\r
2539 </p>\r
2540     </clix:description>\r
2541   </clix:function>\r
2543   <clix:special-variable name='*message-log-pathname*'>\r
2544     <clix:description>\r
2545 A designator for the pathname of the message log file used by the\r
2546 <a href="#logging">default message logger</a>.  The initial value is <code>NIL</code> which\r
2547 means that <em>nothing</em> will be logged!\r
2548     </clix:description>\r
2549   </clix:special-variable>\r
2551   <clix:special-variable name='*access-log-pathname*'>\r
2552     <clix:description>\r
2553 A designator for the pathname of the access log file used by the\r
2554 <a href="#logging">default access logger</a>.  The initial value is <code>NIL</code> which\r
2555 means that <em>nothing</em> will be logged!\r
2556     </clix:description>\r
2557   </clix:special-variable>\r
2559   <clix:special-variable name='*log-lisp-errors-p*'>\r
2560     <clix:description>Whether Lisp errors in request handlers should be logged.\r
2561     </clix:description>\r
2562   </clix:special-variable>\r
2564   <clix:special-variable name='*log-lisp-warnings-p*'>\r
2565     <clix:description>Whether Lisp warnings in request handlers should be logged.\r
2566     </clix:description>\r
2567   </clix:special-variable>\r
2569   <clix:special-variable name='*lisp-errors-log-level*'>\r
2570     <clix:description>Log level for Lisp errors.  Should be one\r
2571 of <code>:ERROR</code> (the default), <code>:WARNING</code>,\r
2572 or <code>:INFO</code>.\r
2573     </clix:description>\r
2574   </clix:special-variable>\r
2576   <clix:special-variable name='*lisp-warnings-log-level*'>\r
2577     <clix:description>Log level for Lisp warnings.\r
2578 Should be one of <code>:ERROR</code>, <code>:WARNING</code>\r
2579 (the default), or <code>:INFO</code>.\r
2580     </clix:description>\r
2581   </clix:special-variable>\r
2584     </clix:subchapter>\r
2586     <clix:subchapter name="conditions" title="Conditions and error handling">\r
2588 This section describes how Hunchentoot deals with exceptional\r
2589 situations.  See also the secion about <a href="#logging">logging</a>.\r
2591   <clix:special-variable name='*show-lisp-errors-p*'>\r
2592     <clix:description>Whether Lisp errors should be shown in HTML output.\r
2593     </clix:description>\r
2594   </clix:special-variable>\r
2596   <clix:special-variable name='*approved-return-codes*'>\r
2597     <clix:description>A list of return codes the server should <em>not</em> treat as an error -\r
2598 see <clix:ref>*HANDLE-HTTP-ERRORS-P*</clix:ref>.\r
2599     </clix:description>\r
2600   </clix:special-variable>\r
2602   <clix:special-variable name='*handle-http-errors-p*'>\r
2603     <clix:description>A generalized boolean that determines whether return codes which\r
2604 are not in <clix:ref>*APPROVED-RETURN-CODES*</clix:ref> are treated specially.  When its value\r
2605 is true (the default), either a default body for the return code or\r
2606 the result of calling <clix:ref>*HTTP-ERROR-HANDLER*</clix:ref> is used.  When the value is\r
2607 <code>NIL</code>, no special action is taken and you are expected to supply your\r
2608 own response body to describe the error.\r
2609     </clix:description>\r
2610   </clix:special-variable>\r
2612   <clix:special-variable name='*http-error-handler*'>\r
2613     <clix:description>Contains <code>NIL</code> (the default) or a function of one argument which is\r
2614 called if the content handler has set a return code which is not in\r
2615 <clix:ref>*APPROVED-RETURN-CODES*</clix:ref>\r
2616 and <clix:ref>*HANDLE-HTTP-ERRORS*</clix:ref> is true.\r
2617     </clix:description>\r
2618   </clix:special-variable>\r
2620   <clix:condition name='hunchentoot-condition'>\r
2621     <clix:description>Superclass for all conditions related to Hunchentoot.\r
2622     </clix:description>\r
2623   </clix:condition>\r
2625   <clix:condition name='hunchentoot-error'>\r
2626     <clix:description>Superclass for all errors related to Hunchentoot and a subclass of <clix:ref>HUNCHENTOOT-CONDITION</clix:ref>.\r
2627     </clix:description>\r
2628   </clix:condition>\r
2630   <clix:condition name='parameter-error'>\r
2631     <clix:description>Signalled if a function was called with incosistent or illegal parameters.  A subclass of <clix:ref>HUNCHENTOOT-ERROR</clix:ref>.\r
2632     </clix:description>\r
2633   </clix:condition>\r
2635   <clix:condition name='hunchentoot-warning'>\r
2636     <clix:description>Superclass for all warnings related to Hunchentoot and a subclass of <clix:ref>HUNCHENTOOT-CONDITION</clix:ref>.\r
2637     </clix:description>\r
2638   </clix:condition>\r
2640     </clix:subchapter>\r
2642     <clix:subchapter name="misc" title="Miscellaneous">\r
2644       Various functions and variables which didn't fit into one of the\r
2645       other categories.\r
2647   <clix:function name='abort-request-handler'>\r
2648   <clix:lambda-list>\r
2649   <clix:lkw>optional\r
2650   </clix:lkw> result\r
2651   </clix:lambda-list>\r
2652   <clix:returns>result\r
2653   </clix:returns>\r
2654     <clix:description>This function can be called by a request handler\r
2655 at any time to immediately abort handling the request.  This works as\r
2656 if the handler had returned <clix:arg>result</clix:arg>.  See the\r
2657 source code of <clix:ref>REDIRECT</clix:ref> for an example.\r
2658     </clix:description>\r
2659   </clix:function>\r
2661       <clix:function name="handle-if-modified-since">\r
2662         <clix:lambda-list>time <clix:lkw>optional</clix:lkw> request</clix:lambda-list>\r
2663         <clix:returns>|</clix:returns>\r
2664         <clix:description>\r
2665           This function is designed to be used inside\r
2666           a <a href="#handlers">handler</a>. If the client has sent an\r
2667           'If-Modified-Since' header\r
2668           (see <a href="http://www.faqs.org/rfcs/rfc2616.html">RFC 2616</a>,\r
2669           section 14.25) and the time specified matches the universal\r
2670           time\r
2671           <clix:arg>time</clix:arg> then the\r
2672           header <clix:ref>+HTTP-NOT-MODIFIED+</clix:ref> with no content\r
2673           is immediately returned to the client.\r
2674           <p>\r
2675             Note that for this function to be useful you should usually\r
2676             send 'Last-Modified' headers back to the client. See the\r
2677             code\r
2678             of <clix:ref>CREATE-STATIC-FILE-DISPATCHER-AND-HANDLER</clix:ref>\r
2679             for an example.\r
2680           </p>\r
2681         </clix:description>\r
2682       </clix:function>\r
2684       <clix:function name="handle-static-file">\r
2685         <clix:lambda-list>path <clix:lkw>optional</clix:lkw> content-type</clix:lambda-list>\r
2686         <clix:returns>nil</clix:returns>\r
2687         <clix:description>\r
2688           Sends the file denoted by the pathname designator\r
2689           <clix:arg>path</clix:arg> with content type\r
2690           <clix:arg>content-type</clix:arg> to the client.  Sets the\r
2691           necessary handlers.  In particular the function employs\r
2692           <clix:ref>HANDLE-IF-MODIFIED-SINCE</clix:ref>.\r
2693           <p>\r
2694             If <clix:arg>content-type</clix:arg> is <code>NIL</code> the\r
2695             function tries to determine the correct content type from\r
2696             the file's suffix or falls back\r
2697             to <code>"application/octet-stream"</code> as a last resort.\r
2698           </p>\r
2699           <p>\r
2700             Note that this function\r
2701             calls <clix:ref>SEND-HEADERS</clix:ref> internally, so after\r
2702             you've called it, the headers are sent and the return value\r
2703             of your handler is ignored.\r
2704           </p>\r
2705         </clix:description>\r
2706       </clix:function>\r
2708       <clix:function name="redirect">\r
2709         <clix:lambda-list>target <clix:lkw>key</clix:lkw> host port protocol add-session-id code</clix:lambda-list>\r
2710         <clix:returns>|</clix:returns>\r
2711         <clix:description>\r
2712           Sends back appropriate headers to redirect the client\r
2713           to <clix:arg>target</clix:arg> (a string).\r
2714           <p>\r
2715             If <clix:arg>target</clix:arg> is a full URL starting with a\r
2716             scheme, <clix:arg>host</clix:arg>, <clix:arg>port</clix:arg>,\r
2717             and <clix:arg>protocol</clix:arg> are ignored.\r
2718             Otherwise, <clix:arg>target</clix:arg> should denote the path\r
2719             part of a URL, <clix:arg>protocol</clix:arg> must be one of\r
2720             the keywords <code>:HTTP</code> or <code>:HTTPS</code>, and\r
2721             the URL to redirect to will be constructed\r
2722             from <clix:arg>host</clix:arg>, <clix:arg>port</clix:arg>, <clix:arg>protocol</clix:arg>,\r
2723             and <clix:arg>target</clix:arg>.\r
2724           </p>\r
2725           <p>\r
2726             If <clix:arg>code</clix:arg> is a 3xx redirection code, it\r
2727             will be sent as status code.  In case of <code>NIL</code>, a\r
2728             302 status code will be sent to the client.\r
2729             If <clix:arg>host</clix:arg> is not provided, the current host\r
2730             (see <clix:ref>HOST</clix:ref>) will be\r
2731             used. If <clix:arg>protocol</clix:arg> is the\r
2732             keyword <code>:HTTPS</code>, the client will be redirected\r
2733             to a https URL, if it's <code>:HTTP</code> it'll be sent to\r
2734             a http URL.  If both <clix:arg>host</clix:arg>\r
2735             and <clix:arg>protocol</clix:arg> aren't provided, then the\r
2736             value of <clix:arg>protocol</clix:arg> will match the current\r
2737             request.\r
2738           </p>\r
2739         </clix:description>\r
2740       </clix:function>\r
2742       <clix:function name="require-authorization">\r
2743         <clix:lambda-list><clix:lkw>optional</clix:lkw> realm</clix:lambda-list>\r
2744         <clix:returns>|</clix:returns>\r
2745         <clix:description>\r
2746           Sends back appropriate headers to require basic HTTP\r
2747           authentication\r
2748           (see <a href="http://www.faqs.org/rfcs/rfc2617.html">RFC 2617</a>)\r
2749           for the realm <clix:arg>realm</clix:arg>. The default value\r
2750           for <clix:arg>realm</clix:arg> is <code>"Hunchentoot"</code>.\r
2751         </clix:description>\r
2752       </clix:function>\r
2754   <clix:function name='no-cache'>\r
2755   <clix:lambda-list>\r
2756   </clix:lambda-list>\r
2757   <clix:returns>|\r
2758   </clix:returns>\r
2759     <clix:description>Adds appropriate headers to completely prevent caching on most browsers.\r
2760     </clix:description>\r
2761   </clix:function>\r
2763    <clix:function name='ssl-p'>\r
2764   <clix:lambda-list>\r
2765   <clix:lkw>optional\r
2766   </clix:lkw> acceptor\r
2767   </clix:lambda-list>\r
2768   <clix:returns>generalized-boolean\r
2769   </clix:returns>\r
2770     <clix:description>Whether the current connection to the client is secure.  See <clix:ref>ACCEPTOR-SSL-P</clix:ref>.\r
2771     </clix:description>\r
2772   </clix:function>\r
2774    <clix:function name='reason-phrase'>\r
2775   <clix:lambda-list>return-code\r
2776   </clix:lambda-list>\r
2777   <clix:returns>string\r
2778   </clix:returns>\r
2779     <clix:description>Returns a reason phrase for the HTTP return code <clix:arg>return-code</clix:arg>\r
2780 (which should be an integer) or <code>NIL</code> for return codes Hunchentoot\r
2781 doesn&#039;t know.\r
2782     </clix:description>\r
2783   </clix:function>\r
2785  <clix:function name='rfc-1123-date'>\r
2786   <clix:lambda-list>\r
2787   <clix:lkw>optional\r
2788   </clix:lkw> time\r
2789   </clix:lambda-list>\r
2790   <clix:returns>string\r
2791   </clix:returns>\r
2792     <clix:description>Generates a time string according to <a href="http://www.faqs.org/rfcs/rfc1123.html">RFC 1123</a>.  Default is current time.\r
2793 This can be used to send a 'Last-Modified' header - see <clix:ref>HANDLE-IF-MODIFIED-SINCE</clix:ref>. \r
2794     </clix:description>\r
2795   </clix:function>\r
2797   <clix:function name='url-encode'>\r
2798   <clix:lambda-list>string \r
2799   <clix:lkw>optional\r
2800   </clix:lkw> external-format\r
2801   </clix:lambda-list>\r
2802   <clix:returns>string\r
2803   </clix:returns>\r
2804     <clix:description>URL-encodes a string using the external format <clix:arg>external-format</clix:arg>.  The default for <clix:arg>external-format</clix:arg> is the value of <clix:ref>*HUNCHENTOOT-DEFAULT-EXTERNAL-FORMAT*</clix:ref>. \r
2805     </clix:description>\r
2806   </clix:function>\r
2808   <clix:function name='url-decode'>\r
2809   <clix:lambda-list>string \r
2810   <clix:lkw>optional\r
2811   </clix:lkw> external-format\r
2812   </clix:lambda-list>\r
2813   <clix:returns>string\r
2814   </clix:returns>\r
2815     <clix:description>Decodes a URL-encoded string which is assumed to\r
2816 be encoded using the external\r
2817 format <clix:arg>external-format</clix:arg>, i.e. this is the inverse\r
2818 of <clix:ref>URL-ENCODE</clix:ref>. It is assumed that you'll rarely\r
2819 need this function, if ever. But just in case - here it is.  The\r
2820 default for <clix:arg>external-format</clix:arg> is the value\r
2821 of <clix:ref>*HUNCHENTOOT-DEFAULT-EXTERNAL-FORMAT*</clix:ref>.\r
2822     </clix:description>\r
2823   </clix:function>\r
2825   <clix:function name='escape-for-html'>\r
2826   <clix:lambda-list>string\r
2827   </clix:lambda-list>\r
2828   <clix:returns>result\r
2829   </clix:returns>\r
2830     <clix:description>Escapes the characters #\&lt;, #\&gt;, #\&#039;, #\&quot;, and #\&amp; for HTML output.\r
2831     </clix:description>\r
2832   </clix:function>\r
2834       <clix:function name="http-token-p">\r
2835         <clix:lambda-list>object</clix:lambda-list>\r
2836         <clix:returns>generalized-boolean</clix:returns>\r
2837         <clix:description>\r
2838           This function tests whether <clix:arg>object</clix:arg> is a\r
2839           non-empty string which is a <em>token</em> according\r
2840           to <a href="http://www.faqs.org/rfcs/rfc2068.html">RFC\r
2841             2068</a> (i.e. whether it may be used for, say, cookie names).\r
2842         </clix:description>\r
2843       </clix:function>\r
2845   <clix:function name='mime-type'>\r
2846   <clix:lambda-list>pathspec\r
2847   </clix:lambda-list>\r
2848   <clix:returns>result\r
2849   </clix:returns>\r
2850     <clix:description>Given a pathname designator <clix:arg>pathspec</clix:arg> returns the <a href="http://en.wikipedia.org/wiki/Internet_media_type">MIME type</a>\r
2851 (as a string) corresponding to the suffix of the file denoted by\r
2852 <clix:arg>pathspec</clix:arg> (or <code>NIL</code>).\r
2853     </clix:description>\r
2854   </clix:function>\r
2856       <clix:special-variable name="*tmp-directory*">\r
2857   <clix:function name='within-request-p'>
2858   <clix:lambda-list>
2859   </clix:lambda-list>
2860   <clix:returns>generalized-boolean
2861   </clix:returns>
2862     <clix:description>Returns true if in the context of a request. Otherwise, <code>NIL</code>.
2863     </clix:description>
2864   </clix:function>
2866         <clix:description>\r
2867           This should be a pathname denoting a directory where temporary\r
2868           files can be stored. It is used for <a href="#upload">file\r
2869             uploads</a>.\r
2870         </clix:description>\r
2871       </clix:special-variable>\r
2873   <clix:special-variable name='*header-stream*'>\r
2874     <clix:description>If this variable is not <code>NIL</code>, it should be bound to a stream to\r
2875 which incoming and outgoing headers will be written for debugging\r
2876 purposes.\r
2877     </clix:description>\r
2878   </clix:special-variable>\r
2881   <clix:special-variable name='*cleanup-function*'>\r
2882     <clix:description>A designator for a function without arguments which is called on a\r
2883 regular basis if <clix:ref>*CLEANUP-INTERVAL*</clix:ref> is not <code>NIL</code>.  The initial value is\r
2884 the name of a function which invokes a garbage collection on 32-bit\r
2885 versions of LispWorks.\r
2886 <p>\r
2887 This variable is only available on LispWorks.\r
2888 </p>\r
2889     </clix:description>\r
2890   </clix:special-variable>\r
2892   <clix:special-variable name='*cleanup-interval*'>\r
2893     <clix:description>Should be <code>NIL</code> or a positive integer.  The system calls\r
2894 <clix:ref>*CLEANUP-FUNCTION*</clix:ref>\r
2895 whenever <clix:ref>*CLEANUP-INTERVAL*</clix:ref> new worker threads\r
2896 (counted globally across all acceptors) have been created unless the\r
2897 value is <code>NIL</code>.  The initial value is 100.\r
2898 <p>\r
2899 This variable is only available on LispWorks.\r
2900 </p>\r
2901     </clix:description>\r
2902   </clix:special-variable>\r
2904     </clix:subchapter>\r
2906   </clix:chapter>\r
2909   <clix:chapter name="testing" title="Testing">\r
2910     Hunchentoot comes with a test script which verifies that the\r
2911     example web server responds as expected.  This test script uses the\r
2912     <a href="http://weitz.de/drakma/">Drakma</a> HTTP client library\r
2913     and thus shares a significant amount of its base code with\r
2914     Hunchentoot itself.  Still, running the test script is a useful\r
2915     confidence test, and it is also possible to run the script across\r
2916     machines in order to verify a new Hunchentoot (or, for that matter\r
2917     Drakma) port.\r
2918     <p>\r
2919       To run the confidence test, <a href="#start">start\r
2920       the example web server</a>.  Then, in your Lisp\r
2921       listener, type\r
2922 <pre>(<a class="noborder" href="hunchentoot-test:test-hunchentoot">hunchentoot-test:test-hunchentoot</a> "http://localhost:4242")</pre>\r
2923       You will see some diagnostic output and a summary line that\r
2924       reports whether any tests have failed.  (You can also use the\r
2925       example certificate and key files in the test directory and\r
2926       start and test an https server instead.)\r
2927     </p>\r
2929     <clix:function name="hunchentoot-test:test-hunchentoot">\r
2930       <clix:lambda-list>base-url <clix:lkw>key</clix:lkw></clix:lambda-list>\r
2931       <clix:returns>|</clix:returns>\r
2932       <clix:description>\r
2933         Runs the built-in confidence\r
2934         test.  <clix:arg>base-url</clix:arg> is the base URL to use\r
2935         for testing, it should not have a trailing slash.  The keyword\r
2936         arguments accepted are for future extension and should not\r
2937         currently be used.\r
2938         <p>\r
2939           The script expects the Hunchentoot example test server to be\r
2940           running at the given <clix:arg>base-url</clix:arg> and\r
2941           retrieves various pages from that server, expecting certain\r
2942           responses.\r
2943         </p>\r
2944       </clix:description>\r
2945     </clix:function>\r
2947   </clix:chapter>\r
2949   <clix:chapter name="history" title="History">\r
2951     Hunchentoot's predecessor <a href="http://weitz.de/tbnl/">TBNL</a>\r
2952     (which is short for "To Be Named Later") grew over the years as a\r
2953     toolkit that I used for various commercial and private\r
2954     projects. In August 2003, Daniel Barlow started\r
2955     a <a href="http://article.gmane.org/gmane.lisp.web/148">review of\r
2956       web APIs</a> on\r
2957     the <a href="http://www.red-bean.com/lispweb/">lispweb</a> mailing\r
2958     list and\r
2959     I <a href="http://article.gmane.org/gmane.lisp.web/153">described</a>\r
2960     the API of my hitherto-unreleased bunch of code (and christened it\r
2961     "TBNL").\r
2962     <p>\r
2963       It turned out that\r
2964       <a href="http://www.jeffcaldwell.com/">Jeff Caldwell</a> had\r
2965       worked on something similar so he emailed me and proposed to\r
2966       join our efforts. As I had no immediate plans to release my code\r
2967       (which was poorly organized, undocumented, and mostly\r
2968       CMUCL-specific), I gave it to Jeff and he worked towards a\r
2969       release. He added docstrings, refactored, added some stuff, and\r
2970       based it on KMRCL to make it portable across several Lisp\r
2971       implementations.\r
2972     </p>\r
2973     <p>\r
2974       Unfortunately, Jeff is at least as busy as I am so he didn't\r
2975       find the time to finish a full release.  But in spring 2004 I\r
2976       needed a documented version of the code for a client of mine who\r
2977       thought it would be good if the toolkit were publicly available\r
2978       under an open source license. So I took Jeff's code, refactored\r
2979       again (to sync with the changes I had done in the meantime), and\r
2980       added documentation.  This resulted in TBNL 0.1.0 (which\r
2981       initially required mod_lisp as its front-end).\r
2982     </p>\r
2983     <p>\r
2984       In March 2005, Bob Hutchinson sent patches which enabled TBNL to\r
2985       use other front-ends than mod_lisp.  This made me aware that\r
2986       TBNL was already <em>almost</em> a full web server, so\r
2987       eventually I wrote Hunchentoot which <em>was</em> a full web\r
2988       server, implemented as a wrapper around TBNL.  Hunchentoot 0.1.0\r
2989       was released at the end of 2005 and was originally\r
2990       LispWorks-only.\r
2991     </p>\r
2992     <p>\r
2993       Hunchentoot 0.4.0, released in October 2006, was the first\r
2994       release which also worked with other Common Lisp\r
2995       implementations.  It is a major rewrite and also incorporates\r
2996       most of TBNL and replaces it completely.\r
2997     </p>\r
2998     <p>\r
2999       Hunchentoot 1.0.0, released in February 2009, is again a major\r
3000       rewrite and should be considered work in progress.  It moved to\r
3001       using\r
3002       the <a href="http://common-lisp.net/project/usocket/">usocket</a>\r
3003       and <a href="http://common-lisp.net/project/bordeaux-threads/">Bordeaux\r
3004       Threads</a> libraries for non-LispWorks Lisps, thereby removing most of\r
3005       the platform dependent code.  Threading behaviour was made\r
3006       controllable through the introduction of\r
3007       taskmasters.  <a href="http://www.cliki.net/mod_lisp">mod_lisp</a>\r
3008       support and several other things were removed in this release to\r
3009       simplify the code base (and partly due to the lack of interest).\r
3010       Several architectural changes (lots of them not\r
3011       backwards-compatible) were made to ease customization of\r
3012       Hunchentoot's behaviour.  A significant part of the 1.0.0\r
3013       redesign was done\r
3014       by <a href="http://netzhansa.blogspot.com/">Hans Hübner</a>.\r
3015     </p>\r
3016   </clix:chapter>\r
3018   <clix:chapter name="index" title="Symbol index">\r
3020     Here are all exported symbols of the <code>HUNCHENTOOT</code>\r
3021     package in alphabetical order linked to their corresponding\r
3022     documentation entries:\r
3024     <clix:index/>\r
3026   </clix:chapter>\r
3028   <clix:chapter name="ack" title="Acknowledgements">\r
3030     Thanks to Jeff Caldwell - TBNL would not have been released\r
3031     without his efforts.  Thanks\r
3032     to <a href="http://www.cliki.net/Stefan%20Scholl">Stefan\r
3033     Scholl</a> and Travis Cross for various additions and fixes to\r
3034     TBNL, to <a href="http://www.foldr.org/~michaelw/">Michael\r
3035     Weber</a> for initial file upload code, and\r
3036     to <a href="http://www.ltn.lv/~jonis/">Janis Dzerins</a> for\r
3037     his <a href="http://common-lisp.net/project/rfc2388/">RFC 2388\r
3038     code</a>. Thanks to Bob Hutchison for his code for multiple\r
3039     front-ends (which made me realize that TBNL was already pretty\r
3040     close to a "real" web server) and the initial UTF-8 example.\r
3041     Thanks to <a href="http://netzhansa.blogspot.com/">Hans Hübner</a>\r
3042     for a lot of architectural and implementation enhancements for the\r
3043     1.0.0 release and also for transferring the documentation to sane\r
3044     XHTML.  Thanks to John\r
3045     Foderaro's <a href="http://opensource.franz.com/aserve/index.html">AllegroServe</a>\r
3046     for inspiration.  Thanks to <a href="http://www.htg1.de/">Uwe von\r
3047     Loh</a> for\r
3048     the <a href="http://www.htg1.de/hunchentoot/hunchentoot.html">Hunchentoot\r
3049     logo</a>.\r
3050     \r
3051     <p>\r
3052       Hunchentoot originally used code\r
3053       from <a href="http://www.cliki.net/ACL-COMPAT">ACL-COMPAT</a>,\r
3054       specifically the chunking code from Jochen Schmidt.  (This has been\r
3055       replaced by <a href="http://weitz.de/chunga/">Chunga</a>.)  When I ported\r
3056       Hunchentoot to other Lisps than LispWorks, I stole code from\r
3057       ACL-COMPAT, <a href="http://www.cliki.net/kmrcl">KMRCL</a>,\r
3058       and <a href="http://www.cliki.net/trivial-sockets">trivial-sockets</a> for\r
3059       implementation-dependent stuff like sockets and MP.  (This has been replaced by \r
3060       <a href="http://common-lisp.net/project/bordeaux-threads/">Bordeaux\r
3061       Threads</a>\r
3062       and <a href="http://common-lisp.net/project/usocket/">usocket</a>.)\r
3063     </p>\r
3064     <p>\r
3065       Parts of this documentation were prepared\r
3066       with <a href="http://weitz.de/documentation-template/">DOCUMENTATION-TEMPLATE</a>,\r
3067       no animals were harmed.\r
3068     </p>\r
3069   </clix:chapter>\r
3070     <p>$Header: /usr/local/cvsrep/documentation-template/output.lisp,v 1.16 2008/06/01 21:26:20 edi Exp $\r
3071     </p>\r
3072     <p>\r
3073       <a href='http://weitz.de/index.html'>BACK TO MY HOMEPAGE\r
3074       </a>\r
3075     </p>\r
3076   </clix:documentation>\r