このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

ErlangのWebサーバー・モジュールを試してみたよ

ErlangによるWebサーバーといえば、YAWSというのが有名らしいです。が、もっと原始的な付属ライブラリ・モジュールhttpdを使ってみました。

解説文書が(あるかも知れないけど)見つからなかったので、manページとソースを拾い読み。

[追記 date="2007-06-29"]今まで見落としていたのですが、ERLANG_HOMEをErlangを置いたディレクトリ、VSNをバージョンとして $ERLANG_HOME/lib/inets-$VSN/examples/server_root/ の下に参考になるサンプルがあります。[/追記]

静的ページが表示されるまで

設定ファイルのパスを引数にしてhttpd:startを呼ぶとWebサーバーが起動するようなので、httpd:start("test.conf").とすると、(カレントディレクトリにある)test.confを読んでくれるはず。で、設定ファイルtest.confですが、とりあえず次のようなもの。


ServerName localhost
Port 8888
ServerRoot .
DocumentRoot htdocs

Modules mod_alias mod_auth mod_actions mod_cgi mod_responsecontrol mod_trace mod_range mod_head mod_include mod_dir mod_get mod_log mod_disk_log

DirectoryIndex index.html

ErrorLog htlogs/error.log
TransferLog htlogs/access.log
SecurityLog htlogs/security.log

設定項目の意味はだいたい察しがつくでしょう(他にも項目はイッパイあります)。ServerRootを最初./と書いたら構文エラーだったので、ディレクトリ指定に、末尾のスラッシュは入れないようです。DocumentRootと*Logの指定はServerRootからの相対パス(先頭スラッシュなし)です。([追記 date="2007-06-29"]先頭にスラッシュをつけてもよく、その場合は相対パスではなくて、絶対パスとみなされます。[/追記]

設定ファイル以外に、$ServerRoot/conf/mime.typesが必要です。今はとりあえずあればいいので、次のような簡単なものでもOK。


# MIME type Extension

text/html html htm
text/plain txt
image/gif gif
image/jpeg jpeg jpg

それと、トップページとなるindex.htmlを準備すると、ディレクトリ構造は次のようになります。


$ServerRoot/
+-- conf/
+-- mime.types
+-- htdocs/
+-- index.html
+-- htlogs/
+-- (error.log) 自動的に作られる
+-- (access.log)
+-- (security.log)

Erlangシェルから:


Erlang (BEAM) emulator version 5.5.4 [async-threads:0]

Eshell V5.5.4 (abort with ^G)
1> httpd:start("test.conf").
{ok,<0.34.0>}
2>

それで http://localhost:8888/ にアクセスするとhtdocs/index.htmlの内容が表示されます。めでたし、めでたし。

httpdプラグイン・モジュール

設定ファイルのModulesの行には、Erlanghttpdが使用する“モジュール”名を列挙します。httpdのモジュール(プラグイン)は、Erlangの意味のモジュールでもありますが、mod_*.erlと命名するのが習慣のようです。

コールバック(httpd本体から呼ばれる)関数do/1(「/1」は引数が1個の意味)だけ準備すれば、httpdプラグインモジュールとして機能します(他に、load/2, store/2, remove/2のコールバックがあります)。


-module(mod_test).
-export([do/1]).
-include_lib("inets/src/httpd.hrl").

do(Info) ->
io:fwrite("mod_test called. URI:~s\n", [Info#mod.absolute_uri]),
OldData = Info#mod.data,
{proceed, OldData}.

doの引数にはHTTPリクエストの情報が詰まっています。この例では、absolute_uriという項目だけ取り出してコンソール表示してます(それだけ)。

設定ファイル(この例ではtest.conf)のModules行にmod_testを付け加え、Webサーバーを再起動してからhttp://localhost:8888/にアクセスすると:


2> httpd:stop().
ok
3> c(mod_test).
{ok,mod_test}
4> httpd:start("test.conf").
{ok,<0.60.0>}
mod_test called. URI:localhost:8888/
5>

モジュールmod_testのdo/1が実行されました。めでたし、めでたし。