ErlangによるWebサーバーといえば、YAWSというのが有名らしいです。が、もっと原始的な付属ライブラリ・モジュールhttpdを使ってみました。
解説文書が(あるかも知れないけど)見つからなかったので、manページとソースを拾い読み。
- man httpd -- http://www.erlang.org/doc/man/httpd.html
- man httpd_conf -- http://www.erlang.org/doc/man/httpd_conf.html
- ソース otp_src_R11B-4/lib/inets/src/http_server/*.erl
[追記 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 htdocsModules 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 Extensiontext/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の行には、Erlangのhttpdが使用する“モジュール”名を列挙します。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が実行されました。めでたし、めでたし。