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 が渡されない