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