/
index.xml
3647 lines (3347 loc) · 159 KB
/
index.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="clixdoc.xsl" ?>
<clix:documentation xmlns='http://www.w3.org/1999/xhtml' xmlns:clix='http://bknr.net/clixdoc'>
<clix:title>Hunchentoot - The Common Lisp web server formerly known as TBNL</clix:title>
<clix:short-description>
A full-featured web server written in Common Lisp offering things
like HTTP/1.1 chunking, persistent connections, and SSL. Includes
a framework for building dynamic websites interactively.
</clix:short-description>
<h2>
<a href="http://www.htg1.de/hunchentoot/hunchentoot.html"
title="Click here for the Hunchentoot logo"
class="noborder">
<img align="top" width="93" height="45" border="0" src="hunchentoot.gif" />
</a>
Hunchentoot - The Common Lisp web server formerly known as TBNL
</h2>
<blockquote>
<clix:chapter name='abstract' title='Abstract'>
<p>
Hunchentoot is a web server written in Common Lisp and at the
same time a toolkit for building dynamic websites. As a
stand-alone web server, Hunchentoot is capable of HTTP/1.1
chunking (both directions), persistent connections
(keep-alive), and SSL.
</p>
<p>
Hunchentoot provides facilities like automatic session
handling (with and without cookies), logging, customizable
error handling, and easy access to GET and POST parameters
sent by the client. It does <em>not</em> include functionality
to programmatically generate HTML output. For this task you
can use any library you like, e.g. (shameless self-plug)
<a href="http://weitz.de/cl-who/">CL-WHO</a> or
<a href="http://weitz.de/html-template/">HTML-TEMPLATE</a>.
</p>
<p>
Hunchentoot talks with its front-end or with the client over
TCP/IP sockets and optionally uses multiprocessing to handle
several requests at the same time. Therefore, it cannot be
implemented completely in <a
href="http://www.lispworks.com/documentation/HyperSpec/Front/index.htm">portable
Common Lisp</a>. It currently works with <a
href="http://www.lispworks.com/">LispWorks</a> and all Lisps
which are supported by the compatibility layers <a
href="http://common-lisp.net/project/usocket/">usocket</a> and
<a
href="http://common-lisp.net/project/bordeaux-threads/">Bordeaux
Threads</a>.
</p>
<p>
Hunchentoot comes with a
<a href="http://www.opensource.org/licenses/bsd-license.php">BSD-style
license</a> so you can basically do with it whatever you want.
</p>
<p>
Hunchentoot is (or was) for example used by
<a href="http://quickhoney.com/">QuickHoney</a>,
<a href="http://www.city-farming.de/">City Farming</a>,
<a href="http://heikestephan.de/">Heike Stephan</a>.
</p>
<p>
<font color="red">Download shortcut:</font>
<a href="http://weitz.de/files/hunchentoot.tar.gz">http://weitz.de/files/hunchentoot.tar.gz</a>.
</p>
</clix:chapter>
</blockquote>
<clix:chapter name='contents' title='Contents'></clix:chapter>
<clix:contents></clix:contents>
<clix:chapter name="install" title="Download and installation">
Hunchentoot depends on a couple of other Lisp libraries which you'll need
to install first:
<ul>
<li>Pierre R. Mai's <a href="http://www.cliki.net/md5">MD5</a>,</li>
<li>Kevin Rosenberg's <a href="http://www.cliki.net/cl-base64">CL-BASE64</a>,</li>
<li>Janis Dzerins' <a href="http://common-lisp.net/project/rfc2388/">RFC2388</a>,</li>
<li>Peter Seibel's <a href="http://weitz.de/cl-fad/">CL-FAD</a>,</li>
<li>Gary King's <a href="http://common-lisp.net/project/trivial-backtrace/">trivial-backtrace</a>,</li>
<li>Erik Huelsmann's <a href="http://common-lisp.net/project/usocket">usocket</a> (unless you're using LispWorks),</li>
<li>Greg Pfeil's <a href="http://common-lisp.net/project/bordeaux-threads/">Bordeaux Threads</a> (unless you're using LispWorks),
</li>
<li>
David Lichteblau's <a href="http://common-lisp.net/project/cl-plus-ssl/">CL+SSL</a>
(unless you're using LispWorks),
</li>
<li>
and my own <a href="http://weitz.de/flexi-streams/">FLEXI-STREAMS</a> (0.12.0 or higher),
<a href="http://weitz.de/chunga/">Chunga</a> (1.0.0 or
higher), and <a href="http://weitz.de/cl-ppcre/">
CL-PPCRE</a> (plus
<a href="http://weitz.de/cl-who/">CL-WHO</a> for the <a href="#teen-age">example code</a>
and <a href="http://weitz.de/drakma/">Drakma</a> for the <a href="#testing">tests</a>).
</li>
</ul>
Make sure to use the <em>newest</em> versions of all of these
libraries (which might themselves depend on other libraries) - try
the repository versions if you're in doubt. Note: You can compile
Hunchentoot without SSL support - and thus without the need to
have CL+SSL - if you add <code>:HUNCHENTOOT-NO-SSL</code> to
<a href="http://www.lispworks.com/documentation/HyperSpec/Body/v_featur.htm">
<code>*FEATURES*</code></a> <em>before</em> you compile it.
<p>
Hunchentoot will only work with Lisps where
the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#character_code">character
codes</a> of
all <a href="http://en.wikipedia.org/wiki/ISO/IEC_8859-1">Latin-1</a>
characters coincide with their
Unicode <a href="http://en.wikipedia.org/wiki/Code_point">code
points</a> (which is the case for all current implementations I
know).
</p>
<p>
Hunchentoot itself together with this documentation can be
downloaded from
<a href="http://weitz.de/files/hunchentoot.tar.gz">http://weitz.de/files/hunchentoot.tar.gz</a>.
The current version is <clix:library-version/>.
</p>
<p>
The preferred method to compile and load Hunchentoot is via <a
href="http://www.cliki.net/asdf">ASDF</a>. If you want to avoid
downloading and installing all the dependencies manually, give
Zach Beane's excellent <a
href="http://www.quicklisp.org/">Quicklisp</a> system a try.
</p>
<p>
Hunchentoot and its dependencies can also be installed with <a
href="http://common-lisp.net/project/clbuild/">clbuild</a>.
There's also a port for <a
href="http://www.gentoo.org/proj/en/lisp/common-lisp/index.xml">Gentoo
Linux</a> thanks to Matthew Kennedy.
</p>
<p>
The current development version of Hunchentoot can be found
at <a href="https://github.com/edicl/hunchentoot">https://github.com/edicl/hunchentoot</a>.
If you want to send patches, please fork the github repository and send pull requests.
</p>
<clix:subchapter name="port80" title="Running Hunchentoot on port 80">
Hunchentoot does not come with code to help with running it on a
privileged port (i.e. port 80 or 443) on Unix-like operating
systems. Modern Unix-like systems have specific, non-portable
ways to allow non-root users to listen to privileged ports, so
including such functionality in Hunchentoot was considered
unnecessary. Please refer to online resources for help. At the
time of this writing, the YAWS documentation has a <a
href="http://yaws.hyber.org/privbind.yaws">comprehensive
writeup</a> on the topic.
</clix:subchapter>
<clix:subchapter name="proxy" title="Hunchentoot behind a proxy">
If you're feeling unsecure about exposing Hunchentoot to the wild,
wild Internet or if your Lisp web application is part of a larger
website, you can hide it behind a
<a href="http://en.wikipedia.org/wiki/Proxy_server">proxy server</a>.
One approach that I have used several times is to employ Apache's
<a href="http://httpd.apache.org/docs/current/mod/mod_proxy.html">mod_proxy</a>
module with a configuration that looks like this:
<pre><a href="http://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypass" class="noborder">ProxyPass</a> /hunchentoot http://127.0.0.1:3000/hunchentoot
<a href="http://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypassreverse" class="noborder">ProxyPassReverse</a> /hunchentoot http://127.0.0.1:3000/hunchentoot</pre>
This will tunnel all requests where the URI path begins with
<code>"/hunchentoot"</code> to a (Hunchentoot) server listening on
port 3000 on the same machine.
<p>
Of course, there are
<a href="http://www.red-bean.com/pipermail/lispweb/2006-October/001342.html">several
other</a> (more lightweight) web proxies that you could use
instead of Apache.
</p>
</clix:subchapter>
</clix:chapter>
<clix:chapter name="support" title="Support">
<p>
The development version of Hunchentoot can be found <a
href="https://github.com/edicl/hunchentoot" target="_new">on
github</a>. Please use the github issue tracking system to
submit bug reports. Patches are welcome, please use <a
href="https://github.com/edicl/hunchentoot/pulls">GitHub pull
requests</a>. If you want to make a change, please <a
href="http://weitz.de/patches.html" target="_new">read this
first</a>.
</p>
</clix:chapter>
<clix:chapter name="teen-age" title="Your own webserver (the easy teen-age New York version)">
Starting your own web server is pretty easy. Do something like this:
<pre>(hunchentoot:<a class="noborder" href="#teen-age">start</a> (make-instance 'hunchentoot:<a class="noborder" href="#acceptor">easy-acceptor</a> :port 4242))</pre>
That's it. Now you should be able to enter the address
"<a href='http://127.0.0.1:4242/'><code>http://127.0.0.1:4242/</code></a>" in
your browser and see something, albeit nothing very interesting
for now.
<p>
By default, Hunchentoot serves the files from the
<code><i>www/</i></code> directory in its source tree. In the
distribution, that directory contains a HTML version of the
documentation as well as the error templates. The location of
the document root directory can be specified when creating a new
<clix:ref>ACCEPTOR</clix:ref> instance by the way of the
<clix:ref>ACCEPTOR-DOCUMENT-ROOT</clix:ref>. Likewise, the
location of the error template directory can be specified by the
<clix:ref>ACCEPTOR-ERROR-TEMPLATE-DIRECTORY</clix:ref>. Both
<clix:ref>ACCEPTOR-DOCUMENT-ROOT</clix:ref> and
<clix:ref>ACCEPTOR-ERROR-TEMPLATE-DIRECTORY</clix:ref> can be
specified using a logical pathname, which will be translated
once when the <clix:ref>ACCEPTOR</clix:ref> is instantiated.
</p>
<p>
The <clix:ref>EASY-ACCEPTOR</clix:ref> class implements a
framework for developing web applications. Handlers are defined
using the <clix:ref>DEFINE-EASY-HANDLER</clix:ref> macro.
Request dispatching is performed according to the list of
dispatch functions in <clix:ref>*DISPATCH-TABLE*</clix:ref>.
Each of the functions on that list is called to determine
whether it wants to handle the request, provided as single
argument. If a dispatcher function wants to handle the request,
it returns another function to actually create the desired page.
</p>
<p>
<clix:ref>DEFINE-EASY-HANDLER</clix:ref> is accompanied by a set
of dispatcher creation functions that can be used to create
dispatchers for standard tasks. These are documented in the <a
class="noborder" href="#easy-handlers">subchapter on easy
handlers</a>
</p>
<p>
Now be a bit more adventurous, try this
<pre>(hunchentoot:<a class="noborder" href="#define-easy-handler">define-easy-handler</a> (say-yo :uri "/yo") (name)
(setf (hunchentoot:<a class="noborder" href="#content-type*">content-type*</a>) "text/plain")
(format nil "Hey~@[ ~A~]!" name))</pre>
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
"<a href='http://127.0.0.1:4242/yo?name=Dude'><code>http://127.0.0.1:4242/yo?name=Dude</code></a>" .
</p>
<p>
Hunchentoot comes with a little example website which you can use
to see if it works and which should also demonstrate a couple of
the things you can do with Hunchentoot. To start the example
website, enter the following code into your listener:
<pre>(<a class="noborder" href="http://common-lisp.net/~mmommer/asdf-howto.shtml#sec11">asdf:oos</a> 'asdf:load-op :hunchentoot-test)</pre>
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.
</p>
</clix:chapter>
<clix:chapter name="extras" title="Third party documentation and add-ons">
<p>
Adam Petersen has written a book called <a
href="http://www.adampetersen.se/articles/lispweb.htm">"Lisp for
the Web"</a> which explains how Hunchentoot and some other
libraries can be used to build web sites.
</p>
<p>
Here is some software which extends Hunchentoot or is based on it:
</p>
<ul>
<li>
<a href="http://weblocks-framework.info/">Weblocks</a> by
Slava Akhmechet is a "continuations-based web framework" which
is based on Hunchentoot.
</li>
<li>
<a href="https://github.com/slyrus/hunchentoot-cgi">hunchentoot-cgi</a>
(by Cyrus Harmon) provides
<a href="http://en.wikipedia.org/wiki/Common_Gateway_Interface">CGI</a>
handlers for Hunchentoot.
</li>
<li>
<a href="http://weitz.de/cl-webdav/">CL-WEBDAV</a> is a <a href="http://webdav.org/">WebDAV</a>
server based on Hunchentoot.
</li>
<li>
<a href="http://restas.lisper.ru/">RESTAS</a> is a web
framework based on Hunchentoot.
</li>
</ul>
</clix:chapter>
<clix:chapter name="reference" title="Function and variable reference">
<clix:subchapter name="acceptors" title="Acceptors">
If you want Hunchentoot to actually do something, you have to create and
<a href="#teen-age">start</a> an <a href="#acceptor">acceptor</a>.
You can also run several acceptors in one image, each one
listening on a different different port.
<clix:class name='acceptor'>
<clix:description>
To create a Hunchentoot webserver, you make an instance of
this class or one of its subclasses and use the generic
function <clix:ref>START</clix:ref> to start it (and
<clix:ref>STOP</clix:ref> to stop it). Use the
<code>:port</code> initarg if you don't want to listen
on the default http port 80. There are other initargs most
of which you probably won't need very often. They are
explained in detail in the docstrings of the slot
definitions for this class.
<p>
Unless you are in a Lisp without MP capabilities, you can
have several active instances of
<clix:ref>ACCEPTOR</clix:ref> (listening on different
ports) at the same time.
</p>
</clix:description>
</clix:class>
<clix:class name='ssl-acceptor'>
<clix:description>Create and <clix:ref>START</clix:ref> an instance of this class
(instead of <clix:ref>ACCEPTOR</clix:ref>) if you want an https server. There are two
required initargs, <code>:SSL-CERTIFICATE-FILE</code> and <code>:SSL-PRIVATEKEY-FILE</code>, for
pathname designators denoting the certificate file and the key file in
PEM format. On LispWorks, you can have both in one file in which case
the second initarg is optional. You can also use the
<code>:SSL-PRIVATEKEY-PASSWORD</code> initarg to provide a password
(as a string) for the key file (or <code>NIL</code>, the default, for
no password).
<p>
The default port for <clix:ref>SSL-ACCEPTOR</clix:ref> instances is 443 instead of 80
</p>
</clix:description>
</clix:class>
<clix:function generic='true' name='start'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>acceptor
</clix:returns>
<clix:description>Starts <clix:arg>acceptor</clix:arg> so that it begins accepting
connections. Returns the acceptor.
</clix:description>
</clix:function>
<clix:function generic='true' name='stop'>
<clix:lambda-list>acceptor &key soft</clix:lambda-list>
<clix:returns>acceptor
</clix:returns>
<clix:description>Stops the <clix:arg>acceptor</clix:arg> so
that it no longer accepts requests. If
<clix:arg>soft</clix:arg> is true, and there are any requests
in progress, wait until all requests are fully processed, but
meanwhile do not accept new requests. Note that
<clix:arg>soft</clix:arg> must not be set when calling
<clix:ref>stop</clix:ref> from within a request handler, as
that will deadlock.
</clix:description>
</clix:function>
<clix:special-variable name='*acceptor*'>
<clix:description>The current ACCEPTOR object in the context of a request.
</clix:description>
</clix:special-variable>
<clix:function generic='true' name='acceptor-listen-backlog'>
<clix:lambda-list>listen-backlog
</clix:lambda-list>
<clix:returns>number-of-pending-connections
</clix:returns>
<clix:description>
Number of pending connections allowed in the listen socket
before the kernel rejects further incoming connections.
Non-LispWorks only.
</clix:description>
</clix:function>
<clix:readers generic='true'>
<clix:listed-reader generic='true' name='acceptor-address'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>address
</clix:returns>
</clix:listed-reader>
<clix:listed-reader generic='true' name='acceptor-port'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>port
</clix:returns>
</clix:listed-reader>
<clix:listed-reader generic='true' name='acceptor-read-timeout'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>read-timeout
</clix:returns>
</clix:listed-reader>
<clix:listed-reader generic='true' name='acceptor-ssl-certificate-file'>
<clix:lambda-list>ssl-acceptor
</clix:lambda-list>
<clix:returns>ssl-certificate-file
</clix:returns>
</clix:listed-reader>
<clix:listed-reader generic='true' name='acceptor-ssl-privatekey-file'>
<clix:lambda-list>ssl-acceptor
</clix:lambda-list>
<clix:returns>ssl-privatekey-file
</clix:returns>
</clix:listed-reader>
<clix:listed-reader generic='true' name='acceptor-ssl-privatekey-password'>
<clix:lambda-list>ssl-acceptor
</clix:lambda-list>
<clix:returns>ssl-privatekey-password
</clix:returns>
</clix:listed-reader>
<clix:listed-reader generic='true' name='acceptor-write-timeout'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>write-timeout
</clix:returns>
</clix:listed-reader>
<clix:description>
These are readers for various slots of <clix:ref>ACCEPTOR</clix:ref>
objects (and some of them obviously only make sense
for <clix:ref>SSL-ACCEPTOR</clix:ref> objects). See the docstrings of
these slots for more information and note that there are corresponding
initargs for all of them.
</clix:description>
</clix:readers>
<clix:accessors generic='true'>
<clix:listed-accessor generic='true' name='acceptor-access-log-destination'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>(or pathname null)
</clix:returns>
</clix:listed-accessor>
<clix:listed-accessor generic='true' name='acceptor-document-root'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>(or pathname null)
</clix:returns>
</clix:listed-accessor>
<clix:listed-accessor generic='true' name='acceptor-error-template-directory'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>(or pathname null)
</clix:returns>
</clix:listed-accessor>
<clix:listed-accessor generic='true' name='acceptor-input-chunking-p'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>input-chunking-p
</clix:returns>
</clix:listed-accessor>
<clix:listed-accessor generic='true' name='acceptor-message-log-destination'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>(or pathname null)
</clix:returns>
</clix:listed-accessor>
<clix:listed-accessor generic='true' name='acceptor-name'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>name
</clix:returns>
</clix:listed-accessor>
<clix:listed-accessor generic='true' name='acceptor-output-chunking-p'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>output-chunking-p
</clix:returns>
</clix:listed-accessor>
<clix:listed-accessor generic='true' name='acceptor-persistent-connections-p'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>persistent-connections-p
</clix:returns>
</clix:listed-accessor>
<clix:listed-accessor generic='true' name='acceptor-reply-class'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>reply-class
</clix:returns>
</clix:listed-accessor>
<clix:listed-accessor generic='true' name='acceptor-request-class'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>request-class
</clix:returns>
</clix:listed-accessor>
<clix:description>
These are accessors for various slots of <clix:ref>ACCEPTOR</clix:ref>
objects. See the docstrings of these slots for more information and
note that there are corresponding initargs for all of them.
</clix:description>
</clix:accessors>
<clix:function generic='true' name='acceptor-ssl-p'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>generalized-boolean
</clix:returns>
<clix:description>Returns a true value if <clix:arg>acceptor</clix:arg> uses SSL
connections. The default is to unconditionally return <code>NIL</code> and
subclasses of <clix:ref>ACCEPTOR</clix:ref> must specialize this method to signal that
they're using secure connections - see the <clix:ref>SSL-ACCEPTOR</clix:ref> class.
</clix:description>
</clix:function>
<clix:special-variable name='*default-connection-timeout*'>
<clix:description>The default connection timeout used when an
acceptor is reading from and writing to a socket stream. Note that
some Lisps allow you to set different timeouts for reading and writing
and you can specify both values via initargs when you create
an <a href="#acceptors">acceptor</a>.
</clix:description>
</clix:special-variable>
<clix:function generic='true' name='acceptor-remove-session'>
<clix:lambda-list>acceptor session
</clix:lambda-list>
<clix:returns>|
</clix:returns>
<clix:description>
This function is called whenever a session in
<clix:ref>ACCEPTOR</clix:ref> is being destroyed because of
a session timout or an explicit
<clix:ref>REMOVE-SESSION</clix:ref> call.
</clix:description>
</clix:function>
</clix:subchapter>
<clix:subchapter name="acceptor-behaviour" title="Customizing acceptor behaviour">
If you want to modify what acceptors do, you should subclass
<clix:ref>ACCEPTOR</clix:ref> (or <clix:ref>SSL-ACCEPTOR</clix:ref>) and
specialize the generic functions that constitute their behaviour (see
example below). The life of an acceptor looks like this: It is started
with the function <clix:ref>START</clix:ref> which immediately calls
<clix:ref>START-LISTENING</clix:ref> and then applies the function
<clix:ref>EXECUTE-ACCEPTOR</clix:ref> to its <a
href="#taskmasters">taskmaster</a>. This function will eventually call
<clix:ref>ACCEPT-CONNECTIONS</clix:ref> which is responsible for setting
things up to wait for clients to connect. For each incoming connection
which comes in, <clix:ref>HANDLE-INCOMING-CONNECTION</clix:ref> is applied
to the taskmaster which will either call
<clix:ref>PROCESS-CONNECTION</clix:ref> directly, or will create a thread
to call it. <clix:ref>PROCESS-CONNECTION</clix:ref> calls
<clix:ref>INITIALIZE-CONNECTION-STREAM</clix:ref> before it does anything
else, then it selects and calls a function which handles the <a
href="#requests">request</a>, and finally it sends the <a
href="#replies">reply</a> to the client before it calls
<clix:ref>RESET-CONNECTION-STREAM</clix:ref>. If the connection is
persistent, this procedure is repeated (except for the intialization step)
in a loop until the connection is closed. The acceptor is stopped with
<clix:ref>STOP</clix:ref>.
<p>
If you just want to use the standard acceptors that come with
Hunchentoot, you don't need to know anything about the functions
listed in this section.
</p>
<clix:function generic='true' name='start-listening'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>|
</clix:returns>
<clix:description>Sets up a listen socket for the given acceptor and
enables it to listen to incoming connections. This function is called
from the thread that starts the acceptor initially and may return
errors resulting from the listening operation (like 'address in use'
or similar).
</clix:description>
</clix:function>
<clix:function generic='true' name='accept-connections'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>nil
</clix:returns>
<clix:description>In a loop, accepts a connection and hands it over
to the acceptor's taskmaster for processing using
<clix:ref>HANDLE-INCOMING-CONNECTION</clix:ref>. On LispWorks, this
function returns immediately, on other Lisps it returns only once the
acceptor has been stopped.
</clix:description>
</clix:function>
<clix:function generic='true' name='process-connection'>
<clix:lambda-list>acceptor socket
</clix:lambda-list>
<clix:returns>nil
</clix:returns>
<clix:description>
This function is called by the taskmaster when a new client
connection has been established. Its arguments are the
<clix:ref>ACCEPTOR</clix:ref> object and a LispWorks socket
handle or a usocket socket stream object in
<clix:arg>socket</clix:arg>. It reads the request headers,
sets up the <a href="#requests">request</a> and <a
href="#replies">reply</a> objects, and hands over to
<clix:ref>PROCESS-REQUEST</clix:ref> which calls
<clix:ref>HANDLE-REQUEST</clix:ref> to select and call a
handler for the request and sends its reply to the client.
This is done in a loop until the stream has to be closed or
until a connection timeout occurs. It is probably not a
good idea to re-implement this method until you really,
really know what you're doing.
<p>
Handlers may call to the
<clix:ref>DETACH-SOCKET</clix:ref> generic function to
indicate that no further requests should be handled on
the connection by Hunchentoot, and that responsibility for
the socket is assumed by third-party software. This can
be used by specialized handlers that wish to hand over
connection polling or processing to functions outside of
Hunchentoot, i.e. for connection multiplexing or
implementing specialized client protocols. Hunchentoot
will finish processing the request and the
<clix:ref>PROCESS-CONNECTION</clix:ref> function will
return without closing the connection. At that point,
the acceptor may interact with the socket in whatever
fashion required.
</p>
</clix:description>
</clix:function>
<clix:function generic='true' name='detach-socket'>
<clix:lambda-list>acceptor
</clix:lambda-list>
<clix:returns>stream
</clix:returns>
<clix:description>
Indicate to Hunchentoot that it should stop serving requests
on the current request's socket. Hunchentoot will finish
processing the current request and then return from
<clix:ref>PROCESS-CONNECTION</clix:ref> without closing the
connection to the client.
<clix:ref>DETACH-SOCKET</clix:ref> can only be called from
within a request handler function.
</clix:description>
</clix:function>
<clix:function generic='true' name='initialize-connection-stream'>
<clix:lambda-list>acceptor stream
</clix:lambda-list>
<clix:returns>stream
</clix:returns>
<clix:description>
Can be used to modify the stream which is used to
communicate between client and server before the request is
read. The default method of <clix:ref>ACCEPTOR</clix:ref>
does nothing, but see for example the method defined for
<clix:ref>SSL-ACCEPTOR</clix:ref>. All methods of this
generic function <em>must</em> return the stream to use.
</clix:description>
</clix:function>
<clix:function generic='true' name='reset-connection-stream'>
<clix:lambda-list>acceptor stream
</clix:lambda-list>
<clix:returns>stream
</clix:returns>
<clix:description>
Resets the stream which is used to communicate
between client and server after one request has been served so that it
can be used to process the next request. This generic function is
called after a request has been processed and <em>must</em> return the
stream.
</clix:description>
</clix:function>
<clix:function name="acceptor-log-access" generic="true">
<clix:lambda-list>acceptor &key return-code</clix:lambda-list>
<clix:description>
Function to call to log access to the acceptor. The
<clix:arg>return-code</clix:arg> keyword argument contains additional
information about the request to log. In addition, it can use the
standard request and reply accessor functions that are available to
handler functions to find out more information about the request.
</clix:description>
</clix:function>
<clix:function name="acceptor-log-message" generic="true">
<clix:lambda-list>acceptor log-level format-string &rest format-arguments</clix:lambda-list>
<clix:description>
Function to call to log messages by the <clix:arg>acceptor</clix:arg>. It must accept
a severity level for the message, which will be one of :ERROR, :INFO,
or :WARNING, a format string and an arbitary number of formatting
arguments.
</clix:description>
</clix:function>
<clix:function name="acceptor-status-message" generic="true">
<clix:lambda-list>acceptor http-return-code &key &allow-other-keys</clix:lambda-list>
<clix:description>
This function is called when a request's handler has been
called but failed to provide content to send back to the
client. It converts the
<clix:arg>HTTP-STATUS-CODE</clix:arg> to some request
contents, typically a human readable description of the
status code to be displayed to the user.
If an ERROR-TEMPLATE-DIRECTORY is set in the current
acceptor and the directory contains a file corresponding to
HTTP-STATUS-CODE named <code>.html, that file is sent
to the client after variable substitution. Variables are
referenced by ${<variable-name>}.
Additional keyword arguments may be provided which are made
available to the templating logic as substitution variables.
These variables can be interpolated into error message
templates in, which contains the current URL relative to the
server and without GET parameters.
In addition to the variables corresponding to keyword
arguments, the script-name, lisp-implementation-type,
lisp-implementation-version and hunchentoot-version
variables are available.
</clix:description>
</clix:function>
</clix:subchapter>
<clix:subchapter name="subclassing-acceptors"
title="An example of how to subclass ACCEPTOR">
This example shows how to subclass <clix:ref>ACCEPTOR</clix:ref> in order to
provide Hunchentoot with basic virtual host support.  It assumes
Hunchentoot is sitting behind an Internet-facing reverse-proxy web server
that maps the host (or domain) part of incoming HTTP requests to unique
localhost ports.
<pre>(asdf:load-system "hunchentoot")
(asdf:load-system "drakma")
;;; Subclass ACCEPTOR
(defclass vhost (tbnl:acceptor)
;; slots
((dispatch-table
:initform '()
:accessor dispatch-table
:documentation "List of dispatch functions"))
;; options
(:default-initargs ; default-initargs must be used
:address "127.0.0.1")) ; because ACCEPTOR uses it
;;; Specialise ACCEPTOR-DISPATCH-REQUEST for VHOSTs
(defmethod tbnl:acceptor-dispatch-request ((vhost vhost) request)
;; try REQUEST on each dispatcher in turn
(mapc (lambda (dispatcher)
(let ((handler (funcall dispatcher request)))
(when handler ; Handler found. FUNCALL it and return result
(return-from tbnl:acceptor-dispatch-request (funcall handler)))))
(dispatch-table vhost))
(call-next-method))
;;; ======================================================================
;;; Now all we need to do is test it
;;; Instantiate VHOSTs
(defvar vhost1 (make-instance 'vhost :port 50001))
(defvar vhost2 (make-instance 'vhost :port 50002))
;;; Populate each dispatch table
(push
(tbnl:create-prefix-dispatcher "/foo" 'foo1)
(dispatch-table vhost1))
(push
(tbnl:create-prefix-dispatcher "/foo" 'foo2)
(dispatch-table vhost2))
;;; Define handlers
(defun foo1 () "Hello")
(defun foo2 () "Goodbye")
;;; Start VHOSTs
(tbnl:start vhost1)
(tbnl:start vhost2)
;;; Make some requests
(drakma:http-request "http://127.0.0.1:50001/foo")
;;; =|
;;; 127.0.0.1 - [2012-06-08 14:30:39] "GET /foo HTTP/1.1" 200 5 "-" "Drakma/1.2.6 (SBCL 1.0.56; Linux; 2.6.32-5-686; http://weitz.de/drakma/)"
;;; =>
;;; "Hello"
;;; 200
;;; ((:CONTENT-LENGTH . "5") (:DATE . "Fri, 08 Jun 2012 14:30:39 GMT")
;;; (:SERVER . "Hunchentoot 1.2.3") (:CONNECTION . "Close")
;;; (:CONTENT-TYPE . "text/html; charset=utf-8"))
;;; #<PURI:URI http://127.0.0.1:50001/foo>
;;; #<FLEXI-STREAMS:FLEXI-IO-STREAM {CA90059}>
;;; T
;;; "OK"
(drakma:http-request "http://127.0.0.1:50002/foo")
;;; =|
;;; 127.0.0.1 - [2012-06-08 14:30:47] "GET /foo HTTP/1.1" 200 7 "-" "Drakma/1.2.6 (SBCL 1.0.56; Linux; 2.6.32-5-686; http://weitz.de/drakma/)"
;;; =>
;;; "Goodbye"
;;; 200
;;; ((:CONTENT-LENGTH . "7") (:DATE . "Fri, 08 Jun 2012 14:30:47 GMT")
;;; (:SERVER . "Hunchentoot 1.2.3") (:CONNECTION . "Close")
;;; (:CONTENT-TYPE . "text/html; charset=utf-8"))
;;; #<PURI:URI http://127.0.0.1:50002/foo>
;;; #<FLEXI-STREAMS:FLEXI-IO-STREAM {CAE8059}>
;;; T
;;; "OK"</pre>
How to make each VHOST write to separate access log streams (or files) is
left as an exercise to the reader.
</clix:subchapter>
<clix:subchapter name="taskmasters" title="Taskmasters">
As a "normal" Hunchentoot user, you can completely ignore
taskmasters and skip this section. But if you're still reading,
here are the dirty details: Each <a
href="#acceptors">acceptor</a> has a taskmaster associated with
it at creation time. It is the taskmaster's job to distribute
the work of accepting and handling incoming connections. The
acceptor calls the taskmaster if appropriate and the taskmaster
calls back into the acceptor. This is done using the generic
functions described in this and the <a
href="#acceptor-behaviour">previous</a> section. Hunchentoot
comes with two standard taskmaster implementations - one (which
is the default used on multi-threaded Lisps) which starts a new
thread for each incoming connection and one which handles all
requests sequentially. It should for example be relatively
straightforward to create a taskmaster which allocates threads
from a fixed pool instead of creating a new one for each
connection.
<p>
You can control the resources consumed by a threaded taskmaster via
two initargs. <code>:max-thread-count</code> lets you set the maximum
number of request threads that can be processes simultaneously. If
this is <code>nil</code>, the is no thread limit imposed.
<code>:max-accept-count</code> lets you set the maximum number of requests
that can be outstanding (i.e. being processed or queued for processing).
If <code>:max-thread-count</code> is supplied and <code>:max-accept-count</code>
is <code>NIL</code>, then a <clix:ref>+HTTP-SERVICE-UNAVAILABLE+</clix:ref>
error will be generated if there are more than the max-thread-count
threads processing requests. If both <code>:max-thread-count</code>
and <code>:max-accept-count</code> are supplied, then max-thread-count
must be less than max-accept-count; if more than max-thread-count
requests are being processed, then requests up to max-accept-count
will be queued until a thread becomes available. If more than
max-accept-count requests are outstanding, then a <clix:ref>+HTTP-SERVICE-UNAVAILABLE+</clix:ref>
error will be generated.
In a load-balanced environment with multiple Hunchentoot servers, it's
reasonable to provide <code>:max-thread-count</code> but leave
<code>:max-accept-count</code> null. This will immediately result
in <clix:ref>+HTTP-SERVICE-UNAVAILABLE+</clix:ref> when one server is
out of resources, so the load balancer can try to find another server.
In an environment with a single Hunchentoot server, it's reasonable
to provide both <code>:max-thread-count</code> and a somewhat larger value
for <code>:max-accept-count</code>. This will cause a server that's almost
out of resources to wait a bit; if the server is completely out of resources,
then the reply will be <clix:ref>+HTTP-SERVICE-UNAVAILABLE+</clix:ref>.
The default for these values is 100 and 120, respectively.
</p>
<p>
If you want to implement your own taskmasters, you should subclass
<clix:ref>TASKMASTER</clix:ref> or one of its subclasses,
<clix:ref>SINGLE-THREADED-TASKMASTER</clix:ref> or
<clix:ref>ONE-THREAD-PER-CONNECTION-TASKMASTER</clix:ref>, and
specialize the generic functions in this section.
</p>
<clix:class name='taskmaster'>
<clix:description>
An instance of this class is responsible for distributing
the work of handling requests for its acceptor. This is an
"abstract" class in the sense that usually only instances of
subclasses of <clix:ref>TASKMASTER</clix:ref> will be used.
</clix:description>
</clix:class>
<clix:class name='one-thread-per-connection-taskmaster'>
<clix:description>
A taskmaster that starts one thread for listening to
incoming requests and one thread for each incoming
connection.
<p>
This is the default taskmaster implementation for multi-threaded Lisp
implementations.
</p>
</clix:description>
</clix:class>
<clix:class name='single-threaded-taskmaster'>
<clix:description>
A taskmaster that runs synchronously in the
thread where the <clix:ref>START</clix:ref> function was invoked (or
in the case of LispWorks in the thread started
by <a href="http://www.lispworks.com/documentation/lw51/LWRM/html/lwref-61.htm#marker-910861"><code>COMM:START-UP-SERVER</code></a>).
This is the simplest possible taskmaster implementation in that its
methods do nothing but calling their acceptor "sister"
methods - <clix:ref>EXECUTE-ACCEPTOR</clix:ref> calls <clix:ref>ACCEPT-CONNECTIONS</clix:ref>,
<clix:ref>HANDLE-INCOMING-CONNECTION</clix:ref> calls <clix:ref>PROCESS-CONNECTION</clix:ref>.
</clix:description>
</clix:class>
<clix:class name='multi-threaded-taskmaster'>
<clix:description>
This is an abstract class for taskmasters that use multiple threads;
it is not a concrete class and you should not instantiate it with
<code>MAKE-INSTANCE</code>.
Instead, you should instantiate its subclass
<clix:ref>ONE-THREAD-PER-CONNECTION-TASKMASTER</clix:ref> described above.
<clix:ref>MULTI-THREADED-TASKMASTER</clix:ref>
is intended to be inherited from by extensions to Hunchentoot,
such as <a href="http://common-lisp.net/project/qitab/">quux-hunchentoot</a>'s
<code>THREAD-POOLING-TASKMASTER</code>,
though at the moment, doing so only inherits one slot and one method,
on <clix:ref>EXECUTE-ACCEPTOR</clix:ref>,
to have it start a new thread for the acceptor,
then saved in said slot.
</clix:description>
</clix:class>
<clix:function generic='true' name='execute-acceptor'>
<clix:lambda-list>taskmaster
</clix:lambda-list>
<clix:returns>result
</clix:returns>
<clix:description>This is a callback called by the acceptor once it
has performed all initial processing to start listening for incoming
connections (see <clix:ref>START-LISTENING</clix:ref>). It usually calls the
<clix:ref>ACCEPT-CONNECTIONS</clix:ref> method of the acceptor, but depending on the
taskmaster instance the method might be called from a new thread.
</clix:description>
</clix:function>
<clix:function generic='true' name='handle-incoming-connection'>
<clix:lambda-list>taskmaster socket
</clix:lambda-list>
<clix:returns>result
</clix:returns>
<clix:description>
This function is called by the acceptor to start
processing of requests on a new incoming connection. <clix:arg>socket</clix:arg> is the
usocket instance that represents the new connection (or a socket
handle on LispWorks). The taskmaster starts processing requests on
the incoming connection by calling the <clix:ref>PROCESS-CONNECTION</clix:ref>
method of the acceptor instance. The <clix:arg>socket</clix:arg> argument is passed to
<clix:ref>PROCESS-CONNECTION</clix:ref> as an argument.
If the taskmaster is a multi-threaded taskmaster, <clix:ref>HANDLE-INCOMING-THREAD</clix:ref>
will call <clix:ref>CREATE-REQUEST-HANDLER-THREAD</clix:ref>, which will call
<clix:ref>PROCESS-CONNECTION</clix:ref> in a new thread.
<clix:ref>HANDLE-INCOMING-THREAD</clix:ref> might issue a
<clix:ref>+HTTP-SERVICE-UNAVAILABLE+</clix:ref> error
if there are too many request threads or it might block waiting for a
request thread to finish.
</clix:description>
</clix:function>
<clix:function generic='true' name='start-thread'>
<clix:lambda-list>taskmaster thunk &key
</clix:lambda-list>
<clix:returns>thread
</clix:returns>
<clix:description>This function is a callback that
starts a new thread that will call the given <clix:arg>thunk</clix:arg>
in the context of the proper <clix:arg>taskmaster</clix:arg>,
with appropriate context-dependent keyword arguments.
<clix:ref>ONE-THREAD-PER-CONNECTION-TASKMASTER</clix:ref> uses it in
<clix:ref>EXECUTE-ACCEPTOR</clix:ref>
and <clix:ref>CREATE-REQUEST-HANDLER-THREAD</clix:ref>,
but specialized taskmasters may define more functions that use it.
By default, it just creates a thread calling the thunk
with a specified <clix:arg>name</clix:arg> keyword argument.
Specialized taskmasters may wrap special bindings and condition handlers