HTTP::Responseのis_hogehoge

PerlのHTTP::Responseモジュールだがis_successというメソッドがある。
前回のHTTPSクローラーでも正常な通信の判定に利用していたが、これに落とし穴が。
サーバーが302のMoved Permanentlyを返した時にFALSEとなるのである。

CPANにあるドキュメントを読んでみると、
http://search.cpan.org/~gaas/libwww-perl-5.808/lib/HTTP/Response.pm

$r->is_info
$r->is_success
$r->is_redirect
$r->is_error

These methods indicate if the response was informational, successful, a redirection, or an error. See HTTP::Status for the meaning of these.

とあるのでHTTP::Statusのドキュメントを読む。

is_info( $code )

Return TRUE if $code is an Informational status code. This class of status code indicates a provisional response which can't have any content.

is_success( $code )

Return TRUE if $code is a Successful status code.

is_redirect( $code )

Return TRUE if $code is a Redirection status code. This class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request.

is_error( $code )

Return TRUE if $code is an Error status code. The function return TRUE for both client error or a server error status codes.

is_client_error( $code )

Return TRUE if $code is an Client Error status code. This class of status code is intended for cases in which the client seems to have erred.

This function is not exported by default.

is_server_error( $code )

Return TRUE if $code is an Server Error status code. This class of status codes is intended for cases in which the server is aware that it has erred or is incapable of performing the request.

だそうだ。


念のためにソースも確認すると、

sub is_info         ($) { $_[0] >= 100 && $_[0] < 200; }
sub is_success      ($) { $_[0] >= 200 && $_[0] < 300; }
sub is_redirect     ($) { $_[0] >= 300 && $_[0] < 400; }
sub is_error        ($) { $_[0] >= 400 && $_[0] < 600; }
sub is_client_error ($) { $_[0] >= 400 && $_[0] < 500; }
sub is_server_error ($) { $_[0] >= 500 && $_[0] < 600; }

これは分かりやすい。


HTTP::Responseのコードは、

sub is_info     { HTTP::Status::is_info     (shift->{'_rc'}); }
sub is_success  { HTTP::Status::is_success  (shift->{'_rc'}); }
sub is_redirect { HTTP::Status::is_redirect (shift->{'_rc'}); }
sub is_error    { HTTP::Status::is_error    (shift->{'_rc'}); }

ということ。


まとめるとHTTPのレスポンスコードによって、

  • 100番台 ⇒ is_infoがTRUE
  • 200番台 ⇒ is_successがTRUE
  • 300番台 ⇒ is_redirectがTRUE
  • 400番台 ⇒ is_client_errorがTRUE,is_errorがTRUE
  • 500番台 ⇒ is_server_errorがTRUE,is_errorがTRUE

となる。
ただしis_client_errorとis_server_errorはHTTP::Responseでは未実装。


ログイン認証つきのクローラーを書く時、ログインした時にリダイレクトするケースが多いのでis_successを安易に使うとはまります。