Hunchentoot メモ(1)

Hunchentoot (http://weitz.de/hunchentoot/) は Common Lisp で書かれた Web サーバです。

dispatch

Hunchentoot でのリクエストの処理は、以下のようになっているようです。

  • taskmaster がクライアントからのリクエストを受け付ける
  • (中略)
  • acceptor インスタンスの request-dispatcher スロットの値を取り出し、リクエスインスタンスを渡して実行(funcall)する。デフォルトではスロットの値はシンボル list-request-dispatcher である。
  • (funcall される)関数 list-request-dispacher は、変数 *dispatch-table* を用いる。
    • 変数 *dispatch-table* はリストであり、要素は、request を引数とする関数(= dispatcher )である。デフォルトでは dispatch-easy-handlers と default-dispatcher が要素となっている。
    • dispatcher は、リクエストを処理できるなら 0 引数の関数 (=action) を返す
  • list-request-dispatcher は action が返った場合、それを実行する。
    • このとき、 *request* が束縛されていれば自動的にキーワードパラメータを計算して与える、という仕組みになっている。

具体的な dispatcher である dispatch-easy-handlers について、

  • dispatch-easy-handlers は、変数 *easy-handler-alist* を用いて処理を行う。
  • 逆に言えば、マクロ define-easy-handler を用いて”ページ”を定義すると、変数 *easy-handler-alist* に値が設定される。

もう一つの具体的な dispatcher である default-dispatcher について、

  • default-dispatcher は、リクエストを無視して、変数 *default-handler* を返す。変数 *default-handler* のデフォルトはシンボル default-handler である。
  • 実際に実行されるのは関数 default-handler で(misc.lisp  で定義)、単に文字列(HTML)を返す。

このようなややこしい仕組みになっている理由は想像ですが、

  • 通常は define-easy-handler で uri を定義すれば十分
  • 特殊な処理をしたい場合は *dispatch-table* に新しい dispatcher を追加する
  • さらに特殊な処理をしたい場合は list-request-dispatcher を完全に置き換える

と考えています。

例えばリクエストされた任意のURIに応じてコンテンツを作ること、ができる気がします。うまく面白い例が思い浮かびませんが、例えば /hello-taro にアクセスされたら taro 用のコンテンツを、 /hello-jiro にアクセスされたら jiro 用のコンテンツを返す、とか。