|
|
||
apacheの2.4系から Luaでapacheのフックを制御できる mod_luaモジュールが入るというネタを見かけたので、svnのtrunk版(2.3.*) を引っ張って試してみました。
(元々 mod_wombatという名前で開発されてたモジュールが2.4系からはmod_luaとしてリリースされるって経緯ぽい。ドキュメントはこちら)
現状のmod_luaでサポートしてるApacheのフックは下記の通りになります。
これらのフックにLuaのコードを噛ませていろいろ制御できる、という感じです。
ざっくり触った感じだと
という感想です。Luaのフットワーク軽さを生かしつつ使えという感じなんでしょうか
( 以下はosxでの作業ログをまとめたものになります )
$ wget http://www.lua.org/ftp/lua-5.1.4.tar.gz $ tar xvfz lua-5.1.4.tar.gz $ cd lua-5.1.4 $ make macosx && sudo make install
# mod_lua用 ( だったはず.. ) $ wget 'http://downloads.sourceforge.net/sourceforge/pcre/pcre-7.9.tar.bz2?use_mirror=jaist' $ tar xvfj pcre-7.9.tar.bz2 $ cd pcre-7.9 $ ./configure && make && sudo make install $ svn checkout http://svn.apache.org/repos/asf/httpd/httpd/trunk httpd-trunk $ cd httpd-trunk $ svn co http://svn.apache.org/repos/asf/apr/apr/trunk srclib/apr $ svn co http://svn.apache.org/repos/asf/apr/apr-util/trunk srclib/apr-util $ ./buildconf $ ./configure --with-included-apr --with-lua=/usr/local --enable-mods-shared=all --enable-lua --with-mpm=worker --enable-so $ make -j2
とりあえず動くかどうかのテスト。ログに"hello, this is test_hook"と出てればok
<LuaHookTranslateName test_hook>
function test_hook(r)
r:info("hello, this is test_hook");
return apache2.DECLINED
end
</LuaHookTranslateName>
セクションの中にLuaのコードを書けるのが新鮮ですね!
これだけだとあまりに残念な紹介なんで、livedoorのいけべさんが昔公開されてたmod_vhost_mysqlの機能をmod_luaで真似してみます。以下の用な設定でいけます。
# luarocksとかいうrubyのgem的なツールを入れる $ wget http://luaforge.net/frs/download.php/3981/luarocks-1.0.1.tar.gz $ tar xvfz luarocks-1.0.1.tar.gz $ cd luarocks-1.0.1 $ ./configure && make && sudo make install # luaでmysqlするluasql.mysqlを入れる $ sudo luarocks install http://luarocks.randomba.org/luasql-mysql-2.1.1.rockspec
LuaRoot /usr/local/apache2/scripts/lua LuaCodeCache stat LuaScope once LuaHookTranslateName mysql_vhost.lua mysql_vhost
require 'luarocks.require' require 'luasql.mysql' dbuser = "root" dbname = "test" dbhost = "localhost" dbpass = nil -- ここがエントリポイント -- rは request_rec function mysql_vhost(r) local root root = find_document_root(r.hostname) if root then r.filename = root .. r.uri return apache2.OK else r:err("DocumentRoot Not Found For " .. r.hostname) return 500 end end -- mysqlからDocumentRoot引っ張ってくる function find_document_root(hostname) local root, env, conn, cursor, row env = assert(luasql.mysql()) conn = assert(env:connect(dbname, dbuser, dbpass, dbhost)) cursor = conn:execute( string.format([[ SELECT * FROM virtualhost where servername = '%s' ]], hostname)) row = cursor:fetch({}, "a") if not row then return nil end return row.document_root end