CatalystアプリをWebサーバにのっけてみる(4) Catalyst on IIS編

Catalystで作ったアプリをIIS上でCGI動作で動かしてみたら、動作が変。
例えば、sub move : Path('move')というアクションを作ったときに、http://domain/MyApp_cgi.pl/move にアクセスすると、なぜかdefaultに飛ばされる。

IIS上での動作とApacheサーバ上での動作を比較したところ、IIS環境変数PATH_INFOをスクリプトパスを含んだ形で、CGIスクリプトに渡してくるため、期待する動作になっていないようだ。

  • IIS上で動作した場合:$ENV{'PATH_INFO'} = MyApp_cgi.pl/move
  • Apache上で動作した場合:$ENV{'PATH_INFO'} = move

このIISのPATH_INFOの問題は、結構いろいろなところ*1で地雷になってるらしく、スクリプト側で対処している方が多いので、それに習ってCatalyst::Request.pmで、以下の行(# <- modifiedのある行)を変更。

=head2 $req->path

Returns the path, i.e. the part of the URI after $req->base, for the current request.

=head2 $req->path_info

Alias for path, added for compability with L<CGI>.

=cut

sub path {
   my ( $self, $params ) = @_;

   if ($params) {
       $self->uri->path($params);
   }
   else {
       return $self->{path} if $self->{path};
   }

   my $path     = $self->uri->path;
   my $location = $self->base->path;
   $path =~ s/^(\Q$location\E)?//;

   # hack to fix broken path info in IIS               # <- modified
       if ($path =~ /$ENV{'SCRIPT_NAME'}/){            # <- modified
               $path =~ s/$ENV{'SCRIPT_NAME'}\///;     # <- modified
       }                                               # <- modified
       else{                                           # <- modified
               $path =~ s/^\///;                       # <- modified
       }                                               # <- modified
   $self->{path} = $path;

   return $path;
}

 
 
BBS-サポート掲示板/686 - FreeStyleWiki
6.1.6. PATH_INFO (経路情報) (CGI/1.1 draft 03)
メモ欄に「IIS は正しい PATH_INFO をくれないことがあるそうです。」
blosxomサイトの日本語訳::FAQ - IISのPATH_INFOの問題にも関わらずBlsoxomを動作させるにはどうすれば良いのですか?
CGI アプリケーションの PATH_INFO および PATH_TRANSLATED を使用する
Micro$oftの見解「これは、セキュリティを目的とした仕様」「CGI 仕様に明記されたとおりに PATH_INFO および PATH_TRANSLATED を使用する必要がある場合は、〜〜〜」
MS独自仕様ですか、そうですか。繰り返すこれはバグではない、繰り返すこれはバグではない。

*1:いろいろなところの詳細