--- /dev/null
+---
+postid: 000
+title: Hunchentoot: further architectural notes; and usage examples
+date: July 25, 2019
+author: Lucian Mogoșanu
+tags: tech, tmsr
+---
+
+This post is part of a series on [Common Lisp WWWism][cl-www], more
+specifically a continuation of [ongoing work][hunchentoot-i] to
+[understand][hunchentoot-ii] the web server known as Hunchentoot and,
+as a result, produce a signed genesis to be used by members of the
+TMSR [WoT][wot].
+
+In this episode we'll do another illustration of the Hunchentoot
+architecture; and we'll have fun documenting a running web server
+instance, thusly exploring for now a few of things that it can do[^1].
+
+First, the architectural diagram, with bells, whistles and clickable
+stuff:
+
+<!-- quite ugh! -->
+<div style="text-align:center">
+<svg width="690px" height="300px" viewBox="0 0 746 336">
+ <use xlink:href="/uploads/2019/07/hunchentootarch.svg#graph1" />
+</svg>
+</div>
+
+No, really, I'm not kidding: if you have a browser that implements
+SVG, clicking on the text should direct you to defgeneric pieces of
+code[^2]. Anyway, the big squares are Hunchentoot components and, more
+specifically, the name of their CL classes, while the small squares
+found inside the big ones represent methods specializing on a given
+class. The green boxes are user actionable or defineable methods, so
+this is where you should start looking; while the arrows denote the "X
+calls Y" relation, with the exception of the dashed green arrow, that
+denotes that header-out is in fact a setf-able object used from
+somewhere within the context of acceptor-dispatch-request, e.g. a
+dispatcher function.
+
+Now from this airplane view, Hunchentoot's organization looks quite
+digestible, which should give us a very good idea of how to start
+using it.
+
+[^1]: Contrary to popular belief and expectations, the things that
+ some particular X can do that are known to (some particular) me
+ are not to be confused with the total set of things that said X
+ can possibly do, nor with the set of things that it *can't*
+ do. Take for example X = your average pointeristic slash
+ buffer-overflowistic C barfola: you can identify some particular
+ uses for it, sure, but meanwhile the average douchebag will
+ exercise code paths that may make it usable for things you've
+ never imagined, such as stealing your keys, wiping your disk and
+ murdering your dog... and many other things, short of making you
+ some french fries, which is something that e.g. a web server can't
+ do.
+
+ In other words, nobody gives a fuck about popular beliefs and
+ expectations; and by the time I publish a [signed][io] genesis for
+ this Hunchentoot thing -- good, bad, with or without warts or
+ however we have it -- I will be entirely able to say what it does
+ and doesn't do, which is exactly what I'm doing here right now.
+
+ And now to be an asshole and leave this otherwise properly rounded
+ footnote hanging: what about, say, [usocket][usocket]? and then
+ what about SBCL or some other working CLtron? and what about
+ [Linux][btcbase-1923536] and [its userland][cuntoo]? This
+ unfortunately is the curse of our postmodern times: our ability to
+ run computing machines rests, for the time being, upon the promise
+ of some [shitheads][btcbase-1918973].
+
+[^2]: I don't write HTML and CSS for a living, so I might as well use
+ this footnote to document the pain required to generate this, for
+ later reference.
+
+ Specifying the diagram in GraphViz is fairly straightforward: one
+ simply has to list the clusters, the nodes and the edges within
+ them in a text file -- see for example the final [.dot
+ file][hunchentootarch-dot] used for generating the illustration
+ above. Adding links and colours and all that is also easy, as
+ previously shown. The problem, however, with this GraphViz thing
+ is that graph generation involves an automated step, i.e. node
+ layout generation and edge routing, that can easily prove to be a
+ pain in the ass for the user: not only do I want this diagram
+ generated, but I also want the diagram generated like *so*, and
+ not like *that*, because I want the viewer to be able to look at
+ the components of the graph in some particular order.
+
+ To add insult to injury, this automated step is almost entirely
+ opaque to the user: in order to have that square near that one, I
+ need to frantically shuffle nodes and edges about until I find the
+ magic ordering that generates something close to what I want --
+ that is, the relationship between said ordering and the output is
+ purely coincidental, and I'm stuck guessing based on the vague
+ hints found in the spec. Anyway, this is the best diagram layout
+ we've got here at The Tar Pit, sorry... do make sure to write in
+ if I'm in the wrong.
+
+ Now that I have a representation, I need to embed it in the blog
+ post. One would expect that's also straightforward, wouldn't they?
+ Well, no! You see, I got the idea that putting clickable links in
+ the generated SVG files is cool, only this doesn't work in the
+ slightest when inserting the .svg using img tags, because
+ completely counter-intuitively, the browser displays *an image*,
+ not a DOM sub-tree. So then I look at how Phf did it with his
+ [patch viewe][btcbase-patches], and it looks like he's inserting a
+ HTML image-map in the HTML document, which kinda beats the purpose
+ of having links in the SVG in the first place. I really, *really*
+ don't want to copy-paste the whole SVG file into the post, so what
+ the fuck am I gonna do, use <object> tags?!
+
+ So if by now you were curious enough to look at the page source,
+ you'll notice that what I did was to insert an inline svg that
+ then imports the content of my .svg file using the
+ [<use>][svg-use] tag, which works exactly the way I want
+ it. And no, you won't find this anywhere on Google either, because
+ Google [doesn't fucking work][btcbase-1922361].
+
+ To sum this up: IMHO the result looks pretty cool, with the
+ mention that I'm most likely going to draw the SVG "by hand" next
+ time I'm doing anything non-trivial. At least then no magic tool
+ will lie to me that it saves hours of my work, when it instead
+ adds to it.
+
+[cl-www]: /posts/y05/090-tmsr-work-ii.html#selection-108.0-108.17
+[hunchentoot-i]: /posts/y05/093-hunchentoot-i.html
+[hunchentoot-ii]: /posts/y05/096-hunchentoot-ii.html
+[wot]: http://wot.deedbot.org/
+[io]: /posts/y04/069-on-intellectual-ownership.html
+[usocket]: http://archive.is/3UKXf
+[btcbase-1923536]: http://btcbase.org/log/2019-07-19#1923536
+[cuntoo]: http://btcbase.org/log-search?q=cuntoo
+[btcbase-1918973]: http://btcbase.org/log/2019-06-20#1918973
+[hunchentootarch-dot]: /uploads/2019/07/hunchentootarch.dot
+[btcbase-patches]: http://btcbase.org/patches
+[svg-use]: http://archive.is/JfGyb
+[btcbase-1922361]: http://btcbase.org/log/2019-07-12#1922361
--- /dev/null
+// Hunchentoot architectural diagram
+//
+// A synthesis of
+// http://thetarpit.org/posts/y05/096-hunchentoot-ii.html
+
+digraph hunchentoot_arch {
+ rankdir=LR // really?
+ newrank=true
+ ranksep=0.4
+ nodesep=0.2
+ node [shape=box]
+
+ subgraph cluster_acceptor {
+ label="acceptor"
+ start [label="start",color=darkgreen,
+ href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L221"]
+ start_listening [label="start-listening",
+ href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L244"]
+ accept_connections [label="accept-connections",
+ href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L251"]
+ process_connection [label="process-connection",
+ href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L272"]
+ handle_request [label="handle-request",
+ href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L284"]
+ acceptor_dispatch_request [label="acceptor-dispatch-request",
+ color=darkgreen,
+ href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L293"]
+ stop [label="stop",color=darkgreen,
+ href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L225"]
+ }
+
+ subgraph cluster_taskmaster {
+ label="taskmaster"
+ execute_acceptor [label="execute-acceptor",
+ href="http://coad.thetarpit.org/hunchentoot/c-taskmaster.lisp.html#L40"]
+ handle_incoming_connection [label="handle-incoming-connection",
+ href="http://coad.thetarpit.org/hunchentoot/c-taskmaster.lisp.html#L47"]
+ shutdown [label="shutdown",
+ href="http://coad.thetarpit.org/hunchentoot/c-taskmaster.lisp.html#L56"]
+ }
+
+ subgraph cluster_request {
+ label="request"
+ process_request [label="process-request",
+ href="http://coad.thetarpit.org/hunchentoot/c-request.lisp.html#L105"]
+ }
+
+ subgraph cluster_reply {
+ label="reply"
+ header_out [label="header-out",
+ href="http://coad.thetarpit.org/hunchentoot/c-reply.lisp.html#L135"]
+ }
+
+ start -> start_listening
+ start_listening -> execute_acceptor [constraint=false]
+ execute_acceptor -> accept_connections
+ accept_connections -> handle_incoming_connection [constraint=false]
+ handle_incoming_connection -> process_connection
+ process_connection -> process_request -> handle_request [constraint=false]
+ handle_request -> acceptor_dispatch_request
+ acceptor_dispatch_request -> header_out [style=dashed,color=darkgreen]
+ stop -> shutdown
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.26.3 (20100126.1600)
+ -->
+<!-- Title: hunchentoot_arch Pages: 1 -->
+<svg width="771pt" height="336pt"
+ viewBox="0.00 0.00 771.00 336.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 332)">
+<title>hunchentoot_arch</title>
+<polygon fill="white" stroke="white" points="-4,5 -4,-332 768,-332 768,5 -4,5"/>
+<g id="graph2" class="cluster"><title>cluster_acceptor</title>
+<polygon fill="none" stroke="black" points="247,-43 247,-320 634,-320 634,-43 247,-43"/>
+<text text-anchor="middle" x="440.5" y="-303.4" font-family="Times Roman,serif" font-size="14.00">acceptor</text>
+</g>
+<g id="graph3" class="cluster"><title>cluster_taskmaster</title>
+<polygon fill="none" stroke="black" points="8,-93 8,-270 234,-270 234,-93 8,-93"/>
+<text text-anchor="middle" x="121" y="-253.4" font-family="Times Roman,serif" font-size="14.00">taskmaster</text>
+</g>
+<g id="graph4" class="cluster"><title>cluster_request</title>
+<polygon fill="none" stroke="black" points="50,-8 50,-85 192,-85 192,-8 50,-8"/>
+<text text-anchor="middle" x="121" y="-68.4" font-family="Times Roman,serif" font-size="14.00">request</text>
+</g>
+<g id="graph5" class="cluster"><title>cluster_reply</title>
+<polygon fill="none" stroke="black" points="647,-93 647,-170 755,-170 755,-93 647,-93"/>
+<text text-anchor="middle" x="701" y="-153.4" font-family="Times Roman,serif" font-size="14.00">reply</text>
+</g>
+<!-- start -->
+<g id="node2" class="node"><title>start</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L221" xlink:title="start">
+<polygon fill="none" stroke="darkgreen" points="356,-287 302,-287 302,-251 356,-251 356,-287"/>
+<text text-anchor="middle" x="329" y="-264.9" font-family="Times Roman,serif" font-size="14.00">start</text>
+</a>
+</g>
+<!-- start_listening -->
+<g id="node3" class="node"><title>start_listening</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L244" xlink:title="start-listening">
+<polygon fill="none" stroke="black" points="585,-287 473,-287 473,-251 585,-251 585,-287"/>
+<text text-anchor="middle" x="529" y="-264.9" font-family="Times Roman,serif" font-size="14.00">start-listening</text>
+</a>
+</g>
+<!-- start->start_listening -->
+<g id="edge6" class="edge"><title>start->start_listening</title>
+<path fill="none" stroke="black" d="M356.39,-269C383.459,-269 425.928,-269 461.966,-269"/>
+<polygon fill="black" stroke="black" points="462.43,-272.5 472.43,-269 462.429,-265.5 462.43,-272.5"/>
+</g>
+<!-- execute_acceptor -->
+<g id="node10" class="node"><title>execute_acceptor</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-taskmaster.lisp.html#L40" xlink:title="execute-acceptor">
+<polygon fill="none" stroke="black" points="188,-237 54,-237 54,-201 188,-201 188,-237"/>
+<text text-anchor="middle" x="121" y="-214.9" font-family="Times Roman,serif" font-size="14.00">execute-acceptor</text>
+</a>
+</g>
+<!-- start_listening->execute_acceptor -->
+<g id="edge8" class="edge"><title>start_listening->execute_acceptor</title>
+<path fill="none" stroke="black" d="M472.302,-285.577C414.594,-299.785 323.061,-314.924 247,-294 211.211,-284.155 175.315,-261.194 151.045,-243.252"/>
+<polygon fill="black" stroke="black" points="153.052,-240.382 142.964,-237.145 148.831,-245.967 153.052,-240.382"/>
+</g>
+<!-- accept_connections -->
+<g id="node4" class="node"><title>accept_connections</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L251" xlink:title="accept-connections">
+<polygon fill="none" stroke="black" points="403,-237 255,-237 255,-201 403,-201 403,-237"/>
+<text text-anchor="middle" x="329" y="-214.9" font-family="Times Roman,serif" font-size="14.00">accept-connections</text>
+</a>
+</g>
+<!-- handle_incoming_connection -->
+<g id="node11" class="node"><title>handle_incoming_connection</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-taskmaster.lisp.html#L47" xlink:title="handle-incoming-connection">
+<polygon fill="none" stroke="black" points="226,-187 16,-187 16,-151 226,-151 226,-187"/>
+<text text-anchor="middle" x="121" y="-164.9" font-family="Times Roman,serif" font-size="14.00">handle-incoming-connection</text>
+</a>
+</g>
+<!-- accept_connections->handle_incoming_connection -->
+<g id="edge12" class="edge"><title>accept_connections->handle_incoming_connection</title>
+<path fill="none" stroke="black" d="M261.874,-200.982C252.527,-198.576 243.034,-196.187 234,-194 227.571,-192.444 220.927,-190.874 214.229,-189.32"/>
+<polygon fill="black" stroke="black" points="214.926,-185.889 204.396,-187.059 213.357,-192.711 214.926,-185.889"/>
+</g>
+<!-- process_connection -->
+<g id="node5" class="node"><title>process_connection</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L272" xlink:title="process-connection">
+<polygon fill="none" stroke="black" points="403,-187 255,-187 255,-151 403,-151 403,-187"/>
+<text text-anchor="middle" x="329" y="-164.9" font-family="Times Roman,serif" font-size="14.00">process-connection</text>
+</a>
+</g>
+<!-- process_request -->
+<g id="node14" class="node"><title>process_request</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-request.lisp.html#L105" xlink:title="process-request">
+<polygon fill="none" stroke="black" points="183,-52 59,-52 59,-16 183,-16 183,-52"/>
+<text text-anchor="middle" x="121" y="-29.9" font-family="Times Roman,serif" font-size="14.00">process-request</text>
+</a>
+</g>
+<!-- process_connection->process_request -->
+<g id="edge16" class="edge"><title>process_connection->process_request</title>
+<path fill="none" stroke="black" d="M254.7,-150.761C251.935,-148.737 249.347,-146.492 247,-144 230.073,-126.032 249.397,-109.296 234,-90 222.535,-75.6319 206.438,-64.665 189.978,-56.4138"/>
+<polygon fill="black" stroke="black" points="191.363,-53.1971 180.824,-52.1048 188.381,-59.5305 191.363,-53.1971"/>
+</g>
+<!-- handle_request -->
+<g id="node6" class="node"><title>handle_request</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L284" xlink:title="handle-request">
+<polygon fill="none" stroke="black" points="389,-137 269,-137 269,-101 389,-101 389,-137"/>
+<text text-anchor="middle" x="329" y="-114.9" font-family="Times Roman,serif" font-size="14.00">handle-request</text>
+</a>
+</g>
+<!-- acceptor_dispatch_request -->
+<g id="node7" class="node"><title>acceptor_dispatch_request</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L293" xlink:title="acceptor-dispatch-request">
+<polygon fill="none" stroke="darkgreen" points="626,-137 432,-137 432,-101 626,-101 626,-137"/>
+<text text-anchor="middle" x="529" y="-114.9" font-family="Times Roman,serif" font-size="14.00">acceptor-dispatch-request</text>
+</a>
+</g>
+<!-- handle_request->acceptor_dispatch_request -->
+<g id="edge19" class="edge"><title>handle_request->acceptor_dispatch_request</title>
+<path fill="none" stroke="black" d="M389.549,-119C399.76,-119 410.625,-119 421.609,-119"/>
+<polygon fill="black" stroke="black" points="421.714,-122.5 431.714,-119 421.714,-115.5 421.714,-122.5"/>
+</g>
+<!-- header_out -->
+<g id="node16" class="node"><title>header_out</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-reply.lisp.html#L135" xlink:title="header-out">
+<polygon fill="none" stroke="black" points="747,-137 655,-137 655,-101 747,-101 747,-137"/>
+<text text-anchor="middle" x="701" y="-114.9" font-family="Times Roman,serif" font-size="14.00">header-out</text>
+</a>
+</g>
+<!-- acceptor_dispatch_request->header_out -->
+<g id="edge21" class="edge"><title>acceptor_dispatch_request->header_out</title>
+<path fill="none" stroke="darkgreen" stroke-dasharray="5,2" d="M626.059,-119C632.25,-119 638.363,-119 644.268,-119"/>
+<polygon fill="darkgreen" stroke="darkgreen" points="644.642,-122.5 654.642,-119 644.642,-115.5 644.642,-122.5"/>
+</g>
+<!-- stop -->
+<g id="node8" class="node"><title>stop</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-acceptor.lisp.html#L225" xlink:title="stop">
+<polygon fill="none" stroke="darkgreen" points="356,-87 302,-87 302,-51 356,-51 356,-87"/>
+<text text-anchor="middle" x="329" y="-64.9" font-family="Times Roman,serif" font-size="14.00">stop</text>
+</a>
+</g>
+<!-- shutdown -->
+<g id="node12" class="node"><title>shutdown</title>
+<a xlink:href="http://coad.thetarpit.org/hunchentoot/c-taskmaster.lisp.html#L56" xlink:title="shutdown">
+<polygon fill="none" stroke="black" points="164,-137 78,-137 78,-101 164,-101 164,-137"/>
+<text text-anchor="middle" x="121" y="-114.9" font-family="Times Roman,serif" font-size="14.00">shutdown</text>
+</a>
+</g>
+<!-- stop->shutdown -->
+<g id="edge23" class="edge"><title>stop->shutdown</title>
+<path fill="none" stroke="black" d="M301.828,-75.5318C269.474,-83.3091 214.693,-96.4775 173.886,-106.287"/>
+<polygon fill="black" stroke="black" points="173.003,-102.9 164.098,-108.64 174.639,-109.706 173.003,-102.9"/>
+</g>
+<!-- execute_acceptor->accept_connections -->
+<g id="edge10" class="edge"><title>execute_acceptor->accept_connections</title>
+<path fill="none" stroke="black" d="M188.244,-219C206.254,-219 225.95,-219 244.753,-219"/>
+<polygon fill="black" stroke="black" points="244.789,-222.5 254.789,-219 244.789,-215.5 244.789,-222.5"/>
+</g>
+<!-- handle_incoming_connection->process_connection -->
+<g id="edge14" class="edge"><title>handle_incoming_connection->process_connection</title>
+<path fill="none" stroke="black" d="M226.219,-169C232.416,-169 238.607,-169 244.704,-169"/>
+<polygon fill="black" stroke="black" points="244.861,-172.5 254.861,-169 244.861,-165.5 244.861,-172.5"/>
+</g>
+<!-- process_request->handle_request -->
+<g id="edge17" class="edge"><title>process_request->handle_request</title>
+<path fill="none" stroke="black" d="M155.421,-52.0989C180.411,-64.8147 215.265,-81.6847 247,-94 250.718,-95.4428 254.556,-96.8575 258.449,-98.2342"/>
+<polygon fill="black" stroke="black" points="257.603,-101.644 268.198,-101.572 259.871,-95.0216 257.603,-101.644"/>
+</g>
+</g>
+</svg>