1 <?xml version="1.0" encoding="ISO-8859-1"?>
\r
2 <?xml-stylesheet type="text/xsl" href="clixdoc.xsl" ?>
\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
13 <a href="http://www.htg1.de/hunchentoot/hunchentoot.html"
\r
14 title="Click here for the Hunchentoot logo"
\r
16 <img align="top" width="93" height="45" border="0" src="hunchentoot.gif" />
\r
18 HUNCHENTOOT - The Common Lisp web server formerly known as TBNL
\r
21 <clix:chapter name='abstract' title='Abstract'>
\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
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
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
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
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
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
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
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
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
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
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
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
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
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
123 Hunchentoot itself together with this documentation can be
\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
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
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
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
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
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
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
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
193 If you want to send patches, please
\r
194 <a href="http://weitz.de/patches.html">read this first</a>.
\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
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
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
228 <clix:chapter name="tutorials" title="Tutorials and add-ons">
\r
231 Here are some Hunchentoot tutorials done by others:
\r
235 <a href="http://www.adampetersen.se/articles/lispweb.htm">"Lisp for the Web"</a> by Adam Petersen.
\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
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
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
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
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
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
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
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
285 Here is some software which extends Hunchentoot or is based on it:
\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
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
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
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
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
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
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
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't want to
\r
340 listen on the default http port 80. There are other initargs most of
\r
341 which you probably won't need very often. They are explained in
\r
342 detail in the docstrings of the slot definitions for this class.
\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
347 </clix:description>
\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
361 The default port for <clix:ref>SSL-ACCEPTOR</clix:ref> instances is 443 instead of 80
\r
363 </clix:description>
\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
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
376 <clix:function generic='true' name='stop'>
\r
377 <clix:lambda-list>acceptor
\r
378 </clix:lambda-list>
\r
379 <clix:returns>acceptor
\r
381 <clix:description>Stops <clix:arg>acceptor</clix:arg> so that it
\r
382 no longer accepts requests.
\r
383 </clix:description>
\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
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
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
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
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
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
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
439 </clix:listed-reader>
\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
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
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
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
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
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
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
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
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
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
512 </clix:listed-accessor>
\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
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
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're using secure connections - see the <clix:ref>SSL-ACCEPTOR</clix:ref> class.
\r
530 </clix:description>
\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
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
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
575 <clix:function generic='true' name='start-listening'>
\r
576 <clix:lambda-list>acceptor
\r
577 </clix:lambda-list>
\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 'address in use'
\r
585 </clix:description>
\r
588 <clix:function generic='true' name='accept-connections'>
\r
589 <clix:lambda-list>acceptor
\r
590 </clix:lambda-list>
\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
601 <clix:function generic='true' name='process-connection'>
\r
602 <clix:lambda-list>acceptor socket
\r
603 </clix:lambda-list>
\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
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
624 </clix:description>
\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
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
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
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
651 </clix:description>
\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
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
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
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
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
691 This is the default taskmaster implementation for multi-threaded Lisp
\r
694 </clix:description>
\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 "sister"
\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
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
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
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
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
737 <clix:function generic='true' name='shutdown'>
\r
738 <clix:lambda-list>taskmaster
\r
739 </clix:lambda-list>
\r
740 <clix:returns>taskmaster
\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
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
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
758 </clix:description>
\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
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
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
791 <clix:ref>+HTTP-NOT-FOUND+</clix:ref> will be sent to the client.
\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
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
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
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
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
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
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
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
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
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
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
874 </clix:description>
\r
877 <clix:function name='create-static-file-dispatcher-and-handler'>
\r
878 <clix:lambda-list>uri path
\r
880 </clix:lkw> content-type
\r
881 </clix:lambda-list>
\r
882 <clix:returns>result
\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's suffix.
\r
889 </clix:description>
\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
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
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
907 <pre>(name &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 &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
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
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
934 the <a href="#*request*">current <code>REQUEST</code>
\r
935 object</a> returns a true value.
\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
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
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
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
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
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
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
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
1012 In the case of <code>'ARRAY</code>, all GET/POST parameters
\r
1013 which have a name like the result of
\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
1027 The full form of a <code>'HASH-TABLE</code> parameter type is
\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
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
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
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
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
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
1081 </clix:description>
\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
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
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
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
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
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
1146 <clix:description>Returns the '<code>X-Forwarded-For</code>' 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
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
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
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
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
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
1215 See also <clix:ref>POST-PARAMETERS</clix:ref>
\r
1216 and <clix:ref>*TMP-DIRECTORY*</clix:ref>.
\r
1218 </clix:description>
\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
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
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
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
1250 See also <clix:ref>POST-PARAMETER</clix:ref>.
\r
1252 </clix:description>
\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
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
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
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
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
1292 <clix:description>Returns the 'Host' incoming http header value.
\r
1293 </clix:description>
\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
1303 <clix:description>Returns the query string of the <clix:ref>REQUEST</clix:ref> object <clix:arg>request</clix:arg>. That's
\r
1304 the part behind the question mark (i.e. the GET parameters).
\r
1305 </clix:description>
\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
1315 <clix:description>Returns the 'Referer' (sic!) http header.
\r
1316 </clix:description>
\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
1326 <clix:description>Returns the request method as a Lisp keyword.
\r
1327 </clix:description>
\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
1337 <clix:description>Returns the request URI.
\r
1338 </clix:description>
\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
1348 <clix:description>Returns the request protocol as a Lisp keyword.
\r
1349 </clix:description>
\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
1359 <clix:description>Returns the 'User-Agent' http header.
\r
1360 </clix:description>
\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
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
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
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
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
1395 <clix:description>Returns the address the current request originated from.
\r
1396 </clix:description>
\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
1406 <clix:description>Returns the port the current request originated from.
\r
1407 </clix:description>
\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
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's the requested URI
\r
1420 without the query string (i.e the GET parameters).
\r
1421 </clix:description>
\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
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
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
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
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
1456 <clix:description>Returns as two values the user and password (if any) as encoded in
\r
1457 the 'AUTHORIZATION' header. Returns <code>NIL</code> if there is no such header.
\r
1458 </clix:description>
\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
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
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
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
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
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
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
1541 Note that this function is slightly misnamed because a
\r
1542 client can send content even if the request method is not
\r
1545 </clix:description>
\r
1549 <clix:function name='recompute-request-parameters'>
\r
1550 <clix:lambda-list>
\r
1552 </clix:lkw> request external-format
\r
1553 </clix:lambda-list>
\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're switching external formats
\r
1558 during the request.
\r
1559 </clix:description>
\r
1562 <clix:function generic='true' name='process-request'>
\r
1563 <clix:lambda-list>request
\r
1564 </clix:lambda-list>
\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
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
1582 The return value of this function is ignored.
\r
1584 </clix:description>
\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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
1729 </clix:description>
\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
1742 </clix:lambda-list>
\r
1743 <clix:returns>string
\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
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
1751 </clix:description>
\r
1754 <clix:function name='headers-out*'>
\r
1755 <clix:lambda-list>
\r
1756 <clix:lkw>optional
\r
1758 </clix:lambda-list>
\r
1759 <clix:returns>alist
\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
1766 <clix:accessor name='content-length*'>
\r
1767 <clix:lambda-list>
\r
1768 <clix:lkw>optional
\r
1770 </clix:lambda-list>
\r
1771 <clix:returns>content-length
\r
1773 <clix:description>The outgoing 'Content-Length' http header of <clix:arg>reply</clix:arg>.
\r
1774 </clix:description>
\r
1778 <clix:accessor name='content-type*'>
\r
1779 <clix:lambda-list>
\r
1780 <clix:lkw>optional
\r
1782 </clix:lambda-list>
\r
1783 <clix:returns>content-type
\r
1785 <clix:description>The outgoing 'Content-Type' http header of <clix:arg>reply</clix:arg>.
\r
1786 </clix:description>
\r
1789 <clix:function name='cookie-out'>
\r
1790 <clix:lambda-list>name
\r
1791 <clix:lkw>optional
\r
1793 </clix:lambda-list>
\r
1794 <clix:returns>result
\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
1801 <clix:accessor name='cookies-out*'>
\r
1802 <clix:lambda-list>
\r
1803 <clix:lkw>optional
\r
1805 </clix:lambda-list>
\r
1806 <clix:returns>alist
\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
1813 <clix:accessor name='return-code*'>
\r
1814 <clix:lambda-list>
\r
1815 <clix:lkw>optional
\r
1817 </clix:lambda-list>
\r
1818 <clix:returns>return-code
\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
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
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
1849 </clix:description>
\r
1852 <clix:accessor name='reply-external-format*'>
\r
1853 <clix:lambda-list>
\r
1854 <clix:lkw>optional
\r
1856 </clix:lambda-list>
\r
1857 <clix:returns>external-format
\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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
2035 </clix:description>
\r
2038 <clix:function name='start-session'>
\r
2039 <clix:lambda-list>
\r
2040 </clix:lambda-list>
\r
2041 <clix:returns>session
\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
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
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
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
2070 </clix:description>
\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
2080 <clix:description>Removes the value associated
\r
2081 with <clix:arg>symbol</clix:arg> from <clix:arg>session</clix:arg> if
\r
2083 </clix:description>
\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
2099 <clix:description>Completely removes
\r
2100 the <clix:ref>SESSION</clix:ref> object <clix:arg>session</clix:arg>
\r
2101 from Hunchentoot's internal <a href="#session-db">session
\r
2103 </clix:description>
\r
2107 <clix:function name='reset-sessions'>
\r
2108 <clix:lambda-list>
\r
2109 </clix:lambda-list>
\r
2112 <clix:description>Removes <em>all</em> stored sessions.
\r
2113 </clix:description>
\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
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'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's remote IP changes.
\r
2136 This might for example be an issue if the client uses a proxy server
\r
2137 which doesn't send correct 'X_FORWARDED_FOR' headers.
\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
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
2154 <clix:special-variable name='*use-user-agent-for-sessions*'>
\r
2155 <clix:description>Whether the 'User-Agent' 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 'User-Agent' 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
2167 <clix:description>
\r
2168 The incoming 'User-Agent' header that
\r
2169 was sent when this session was created.
\r
2170 </clix:description>
\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
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
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
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
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
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
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
2240 One way is to mostly leave the session mechanism intact but to tweak
\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
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
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
2280 <clix:special-variable name='*session-secret*'>
\r
2281 <clix:description>A random ASCII string that'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
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
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
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>"hunchentoot-session"</code>, but you can
\r
2311 specialize this function if you want another name.
\r
2312 </clix:description>
\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
2320 <clix:description>This function is called whenever a new session
\r
2321 has been created. There'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
2325 The return value is ignored.
\r
2327 </clix:description>
\r
2331 <clix:function generic='true' name='next-session-id'>
\r
2332 <clix:lambda-list>acceptor
\r
2333 </clix:lambda-list>
\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'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
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
2349 <clix:description>Returns the current session database which is an
\r
2350 alist where each car is a session'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
2356 <clix:function generic='true' name='session-db-lock'>
\r
2357 <clix:lambda-list>acceptor
\r
2359 </clix:lkw> whole-db-p
\r
2360 </clix:lambda-list>
\r
2361 <clix:returns>lock
\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
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
2377 </clix:description>
\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
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
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
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
2397 </clix:description>
\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
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
2412 method is provided and there's no reason to change it unless you
\r
2413 want to use your own session objects.
\r
2415 </clix:description>
\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
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
2436 :documentation "The value of the cookie. Will be URL-encoded when sent to the browser.")
\r
2437 (expires :initarg :expires
\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
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
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
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
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
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
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
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
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
2525 <clix:function name='log-message'>
\r
2526 <clix:lambda-list>log-level format-string
\r
2528 </clix:lkw> format-arguments
\r
2529 </clix:lambda-list>
\r
2530 <clix:returns>result
\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
2537 This is the function which Hunchentoot itself uses to log errors it
\r
2538 catches during request processing.
\r
2540 </clix:description>
\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
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
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
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
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
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
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
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
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
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
2678 of <clix:ref>CREATE-STATIC-FILE-DISPATCHER-AND-HANDLER</clix:ref>
\r
2681 </clix:description>
\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
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
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
2705 </clix:description>
\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
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
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
2739 </clix:description>
\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
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
2754 <clix:function name='no-cache'>
\r
2755 <clix:lambda-list>
\r
2756 </clix:lambda-list>
\r
2759 <clix:description>Adds appropriate headers to completely prevent caching on most browsers.
\r
2760 </clix:description>
\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
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
2774 <clix:function name='reason-phrase'>
\r
2775 <clix:lambda-list>return-code
\r
2776 </clix:lambda-list>
\r
2777 <clix:returns>string
\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't know.
\r
2782 </clix:description>
\r
2785 <clix:function name='rfc-1123-date'>
\r
2786 <clix:lambda-list>
\r
2787 <clix:lkw>optional
\r
2789 </clix:lambda-list>
\r
2790 <clix:returns>string
\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
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
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
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
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
2825 <clix:function name='escape-for-html'>
\r
2826 <clix:lambda-list>string
\r
2827 </clix:lambda-list>
\r
2828 <clix:returns>result
\r
2830 <clix:description>Escapes the characters #\<, #\>, #\', #\", and #\& for HTML output.
\r
2831 </clix:description>
\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
2845 <clix:function name='mime-type'>
\r
2846 <clix:lambda-list>pathspec
\r
2847 </clix:lambda-list>
\r
2848 <clix:returns>result
\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
2856 <clix:special-variable name="*tmp-directory*">
\r
2857 <clix:function name='within-request-p'>
2860 <clix:returns>generalized-boolean
2862 <clix:description>Returns true if in the context of a request. Otherwise, <code>NIL</code>.
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
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
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
2887 This variable is only available on LispWorks.
\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
2899 This variable is only available on LispWorks.
\r
2901 </clix:description>
\r
2902 </clix:special-variable>
\r
2904 </clix:subchapter>
\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
2919 To run the confidence test, <a href="#start">start
\r
2920 the example web server</a>. Then, in your Lisp
\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
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
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
2944 </clix:description>
\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
2957 the <a href="http://www.red-bean.com/lispweb/">lispweb</a> mailing
\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
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
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
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
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
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
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
3014 by <a href="http://netzhansa.blogspot.com/">Hans Hübner</a>.
\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
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
3048 the <a href="http://www.htg1.de/hunchentoot/hunchentoot.html">Hunchentoot
\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
3062 and <a href="http://common-lisp.net/project/usocket/">usocket</a>.)
\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
3070 <p>$Header: /usr/local/cvsrep/documentation-template/output.lisp,v 1.16 2008/06/01 21:26:20 edi Exp $
\r
3073 <a href='http://weitz.de/index.html'>BACK TO MY HOMEPAGE
\r
3076 </clix:documentation>
\r