debianでapache2のmod_filter mod_ext_filerを動かす

apache2はインプットフィルター、アウトプットフィルターが使えるとのこと。
それどころかSSIはアウトプットフィルターとして実装されている。おそらくCGIもそうだろう。
ということで任意のプログラムをフィルターとして実行できるext_filterを実験してみる。

まずはモジュールをロード(ついでにrewriteとuserdirもロード)

# cd /etc/apache2/mods-enabled 
# ln -s ../mods-available/filter.load .
# ln -s ../mods-available/ext_filter.load .
# ln -s ../mods-available/rewrite.load .
# ln -s ../mods-available/userdir.load .
# cat > ../httpd.conf
ServerName debian-etch
UserDir public_html
UserDir disabled root
<Directory "/home/*/public_html">
    AllowOverride All
    Order allow,deny
    allow from all
    Options MultiViews Indexes SymLinksIfOwnerMatch  ExecCGI IncludesNoExec
    AddHandler cgi-script cgi
</Directory>
# apache2ctl restart

userdirに試験用のデータを準備する

$ cd public_html/
$ cat > index.html
<html>
<body>
hello,world
abcdefghijk
bye
</body>
</html>
$ wget -q -O - http://localhost/~$USER/
<html>
<body>
hello,world
abcdefghijk
bye
</body>
</html>

http.confへext_filterの記述を追記する

# cd /etc/apache2
# cat >> /httpd.conf
ExtFilterDefine fixtext mode=output intype=text/html \
 cmd="/bin/sed s/abcdefg/aaaaaa/g"
<Directory "/home/*/public_html">
    SetOutputFilter fixtext
</Directory>
# apache2ctl restart

できた

abcdefg->aaaaaaになっている。

$ wget -q -O - http://localhost/~$USER/
<html>
<body>
hello,world
aaaaaahijk
bye
</body>
</html>

フィルタを2段にする

やっぱりフィルタというからには何段も通過できなきゃおかしいのでアウトプットフィルタを2段にしてみる

/etc/apache2/httpd.confの最後を以下のように書き直す

ExtFilterDefine fixtext mode=output intype=text/html cmd="/bin/sed s/abcdefg/aaaaaa/g"
ExtFilterDefine fixtext2 mode=output intype=text/html cmd="/bin/sed s/world/japan/g"
<Directory "/home/*/public_html">
    SetOutputFilter fixtext;fixtext2
</Directory>

apacheをリブートした後、実験すると
abcdefg->aaaaa , world->japan
と、確かに変わっている。すばらしい。

$ wget -q -O - http://localhost/~$USER/
<html>
<body>
hello,japan
aaaaaahijk
bye
</body>
</html>

.htaccessをかく

.htaccessではfilterの設定ができないみたいだ。

$ cat > .htaccess
# mod_ext_filter directive to define a filter which
# replaces text in the response
#
ExtFilterDefine fixtext mode=output intype=text/html \
 cmd="/bin/sed s/abcdefg/aaaaaa/g"
<Location />
# core directive to cause the fixtext filter to
# be run on output
SetOutputFilter fixtext
</Location>

これで実験しても動かない。ログをみると

[Wed Aug 20 23:27:38 2008] [alert] [client 127.0.0.1] /home/a/public_html/.htaccess: ExtFilterDefine not allowed here

httpd.confじゃないとだめなのかな?

SetOutputFilterは.htaccessでも動作する。