mod_subsitute と mod_ext_filter

HTTPなアプリケーションのデバッグのために出力の一部を書き換えたいということがある。アプリケーションを書き換えたくない状況ではApache HTTPサーバのフィルタで対応できそうだ。そういうわけで、何か適当なモジュールはないだろうか検索してみたところ、Apache HTTPサーバのバージョン2.2には標準でmod_substituteというモジュールが用意されていた。

mod_substitute(Apache 2.2) - \ay diary

な,なんとそんな便利なものが,と思って調べてみたら,Apache 2.2.8 以降(厳密には 2.2.7 以降)で追加されてたんですね。

レスポンスボディを正規表現で書き換えるもので、設定の都合上「/」をうまく扱えないようなのがいまいちだが

mod_substitute(Apache 2.2) - \ay diary

とのことですが,

If either the pattern or the substitution contain a slash character then an alternative delimiter should be used:

# Example of using an alternate delimiter

<Location />
   AddOutputFilterByType SUBSTITUTE text/html
   Substitute "s|<BR */?>|<br />|i"
</Location> 
mod_substitute - Apache HTTP Server Version 2.2

にあるように,デリミタをスラッシュ以外に変えてあげれば OK*1。でもソースをさっくり眺めた感じでは,デリミタをエスケープしてパターン等に使うのはできなさそうですね。


なお,Apache-2.2.5 以前なら mod_ext_filter という標準モジュールが使えます。

同等の例だと,

LoadModule ext_filter_module modules/mod_ext_filter.so

ExtFilterDefine substitute-filter mode=output intype=text/html \
    cmd="/bin/sed s|www\.example\.jp|www.debug.example.jp|ig"

<Location />
    SetOutputFilter substitute-filter
</Location>

になります。外部コマンド*2を使ってカスタムフィルタを定義できるモジュールであり(なので上記で substitute-filter としてますが任意の名前で構いません),外部コマンドを実行する分パフォーマンスは悪くなります。

いつフィルタコマンドを実行するのか,とか,再利用されるかどうか,とかは,初めて使うときにソースを読み込んだはずなんですが失念しました。


んー mod_substitute 魅力的だなぁ。

*1:上記でダブルクォーテーションが入っているのは例示パターンに空白が含まれているためであり,デリミタを変更するだけなら不要

*2:Linux って sed が /bin にあるのかよっ