Hatena::Grouperlang

檜山正幸のErlang未確認情報 RSSフィード

 | 

2008-12-30 (火)

appmodの使い方とか

| 08:57

appmodとは、YAWSに対するのコールバックモジュールで、out/1 というコールバック関数を持つモジュールをappmodとして指定する(その指定方法は後述)と、outの引数にYAWSが持っているリクエスト情報をすべて詰め混んだレコードを渡してくれる。適当に処理して戻せばそれがレスポンスになるという仕掛け。

out/1の引数に関しては、http://yaws.hyber.org/yman.yaws?page=yaws_api

The out(Arg) function is supplied one argument, an #arg{} structure.

We have the following relevant record definitions:

の下に書いてあるが、あてになるかどうかはわからない。使うバージョンのyaws_api.hrlを見た方が確実。(マニュアルなんてそんなものよ。)「argのダンプとか」も参照。

out/1の戻り値規約は、同じページのRETURN VALUES from out/1に書いてある。よく使うのは、html, ehtml, content, header, redirectあたりだろう。その他のAPI関数http://yaws.hyber.org/yman.yaws?page=yaws_api に書いてある。このページと http://yaws.hyber.org/yman.yaws?page=yaws.conf(設定ファイル)の2つを見ればだいたい間に合う。

さて、amod_helloとamod_dumpというモジュールをappmodとして指定するには、yaws.confに次のように書く。

<server localhost>
        port = 8888
        listen = 0.0.0.0
        docroot = /tmp
        dir_listings = true
        appmods = <hello, amod_hello> <dump, amod_dump>
</server>

appmods=の後に、<パス, モジュール名>を単にズラズラと並べればよい。パスがルートなら、</, amod_hello> のように書く(気持ち悪いが)。<hello, amod_hello> は、</hello, amod_hello> でもよい(スラッシュをチャンと書いたほうが明確かもしれない)。<"/hello", amod_hello> <"/dump arg", amod_dump> のような書き方もできる。アクセスするときは、空白を %20 にすればいい。

amod_helloは例えば次のようだとする(参照「ehtmlの基本」)。

%% -*- coding: utf-8 -*-

%% @doc helloを出力するYAWSのappmod
-module(amod_hello).
-export([out/1]).

-include("../../yaws/include/yaws_api.hrl").

%% @spec (#arg{}) -> {ehtml, term()}
out(_Arg)->
  {ehtml, 
   {h1, [],
    [
     "Hello"
    ]
   }
  }.

これをコンパイルしてamod_hello.beamを作るが、ERTSにこのbeamの在処<ありか>を認識させるためには、次の方法がある。

  1. シェルスクリプトyawsの -pa、--pa オプションを使う。これはerlに-paをそのまま渡す。
  2. ~/.erlang, ./.erlang に code:add_patha/1, code:add_pathz/1 を書いておく。
  3. 環境変数ERL_LIBSを使う。

などの方法があるが、yaws.confのebin_dir項目に書いておくのが一番お手軽だろう(お手軽なだけでお奨めとは言ってない)。

ebin_dir = "c:/Documents and Settings/Hiyama/Work/yaws_ebin"

Windowsの場合、ダブルクォートすれば空白入りのパスもOK。上の指定ならば、コンパイル済みamod_hello.beamを"c:/Documents and Settings/Hiyama/Work/yaws_ebin"の下にコピーしておく。

YAWSを yaws -i または yaws -w で起動。シェルからlists:reverse(code:get_path()). としてみると、yaws.confで指定したパスが確かに追加されていることを確認できる。さらに、code:which(amod_hello)でamod_helloが見えているかどうかを確認できる。

ブラウザから http://localhost:8888/hello にアクセスすると amod_hello:out/1 の(YEWSが変換した)実行結果が表示される。パスが hello, hello/, hello?foo=bar, hello/foo/bar などなら、リクエストは全てamod_helloに渡る。「HTTP GETで取ってきてファイルに書く」関数を使って inets_util:http_dump("http://localhost:8888/hello"). とすれば、ヘッダとかも確認できる。

{"HTTP/1.1",200,"OK"}
[
  {"date","Mon, 29 Dec 2008 23:47:28 GMT"},
  {"server","Yaws/1.77 Yet Another Web Server"},
  {"content-length","15"},
  {"content-type","text/html"}
]

 |