mod_perl 2.0 でのハンドラの戻り値
mod_perl で ModPerl::Registry や ModPerl::PerlRun を使わずに,自力でハンドラを書く場合,
sub handler : method { my ($class, $r) = @_; ... return Apache2::Const::OK; }
みたく書き始めるわけです*1。ここで,エラーが発生した場合や,リダイレクト(302 等)を行う場合,最後の戻り値に,Apache2::Const::SERVER_ERROR や Apache2::Const::REDIRECT を返したくなります(生の 500 や 302 でも等価です)。しかし,戻り値でそれらの値を返してしまうと Apache は自力でエラーページ等を用意するので,出力の最後にそれがくっついてしまいます。また OK 以外を返した場合,$r->headers_out() に設定したヘッダは出力されません(それでもヘッダを出力したい場合,$r->err_headers_out() の方を使います)。ですから Status: ヘッダに返す値にかかわらず,Apache2::Const::OK(すなわち 0)を返すほうがコントロールが効きます。もちろん,$r->status() or $r->status_line() するのをお忘れなく。
まとめると,
- (自作フレームワーク等で)自力でリダイレクトページやエラーページを作っている場合,Apache2::Const::OK を返す。
- 自分で用意する気がないか fatal なエラーの場合,レスポンスコードを返す(Content-Type 以外のヘッダは $r->err_headers() のほうに設定)。
- いずれにしても,$r->status() や $r->status_line() で,ステータスをセットする。
ということになります。
*1:ちなみに「: method」をつけずにハンドラを定義した場合,クラスメソッドとしてではなくグローバルメソッドとして呼び出されるっぽいです。この例だと,先頭の $class が渡されない