Catalyst::Request#pathの値に、LocationMatchでマッチした文字列がくっつく(3)
Catalyst::Request#pathの値に、LocationMatchでマッチした文字列がくっつく - ヒルズで働く@robarioの技ログ
Catalyst::Request#pathの値に、LocationMatchでマッチした文字列がくっつく(2) - ヒルズで働く@robarioの技ログ
というわけで、Catalystにパッチを当ててみる試み。
Root.pmのdefaultハンドラを以下のようにして、
sub default : Private { my ( $self, $c ) = @_; my $content = sprintf <<EOF, $c->req->path, ( join ', ', @{ $c->req->arguments } ), $c->req->base; path = %s arguments = %s base = %s EOF $c->res->content_type('text/plain'); $c->res->body($content); }
Locationディレクティブの値が異なる2種類のhttpd.confを用意して
PerlModule MyApp <LocationMatch "/"> SetHandler modperl PerlResponseHandler MyApp </LocationMatch>
PerlModule MyApp <LocationMatch "^/.*$"> SetHandler modperl PerlResponseHandler MyApp </LocationMatch>
http://localhost:3000/abc/def/ghiにアクセスする実験をしました。
パッチを当てていない状態
Locationディレクティブの設定が"/"の場合
path = abc/def/ghi arguments = abc, def, ghi base = http://localhost:3000/
Locationディレクティブの設定が"^/.*$"の場合
path = abc/def/ghi arguments = abc, def, ghi base = http://localhost:3000/%5E/.*$/
baseの値が変になりました。「変」と言っても、Catalyst的には合っているのかも。
パッチを当てた状態
Apache2::RequestUtil#locationの代わりにApache2::RequestRec#path_infoを使うようにしてみます。
% diff -Nau Apache.pm.orig Apache.pm
--- Apache.pm.orig 2006-10-28 12:39:47.079233600 +0900 +++ Apache.pm 2006-10-28 12:39:54.570004800 +0900 @@ -92,7 +92,7 @@ my $base_path = q{}; # Are we running in a non-root Location block? - my $location = $self->apache->location; + my $location = $self->apache->path_info; if ( $location && $location ne '/' ) { $base_path = $location; }
Locationディレクティブの設定が"/"の場合
path = abc/def/ghi arguments = abc, def, ghi base = http://localhost:3000/abc/def/ghi/
Locationディレクティブの設定が"^/.*$"の場合
path = abc/def/ghi arguments = abc, def, ghi base = http://localhost:3000/abc/def/ghi/
どちらもbaseが一致するようになりました。
何かがおかしい。。。
うーん。Catalyst的にはこれらのbaseは一致しちゃったらダメな気がする。Locationでの設定値がbaseに反映されるようにしたいんじゃないかな。ってことでパッチを変更。
% diff -Nau Apache.pm.orig Apache.pm
--- Apache.pm.orig 2006-10-28 12:39:47.079233600 +0900 +++ Apache.pm 2006-10-28 12:52:07.864430400 +0900 @@ -94,7 +94,7 @@ # Are we running in a non-root Location block? my $location = $self->apache->location; if ( $location && $location ne '/' ) { - $base_path = $location; + $base_path = $self->apache->path_info; } # Are we an Apache::Registry script? Why anyone would ever want to run
Locationディレクティブの設定が"/"の場合
path = abc/def/ghi arguments = abc, def, ghi base = http://localhost:3000/
Locationディレクティブの設定が"^/.*$"の場合
path = abc/def/ghi arguments = abc, def, ghi base = http://localhost:3000/abc/def/ghi/
うーん。これでいいんじゃね?と思ったんだけど、baseにabc/def/ghiが含まれているのにpathがabc/def/ghiなのはおかしい。
ん〜何か分かってきたぞ。
Locationに設定された部分は、Catalystが関知しない領域として扱いたいらしい。なので、
<LocationMatch "/abc">
とすると
path = def/ghi arguments = ghi base = http://localhost:3000/abc/
となる。Locationディレクティブの"/abc"を"^/[^/]+"に変えたときに同じ挙動になるためには、
% diff -Nau Apache.pm.orig Apache.pm
--- Apache.pm.orig 2006-10-28 12:39:47.079233600 +0900 +++ Apache.pm 2006-10-28 18:53:32.058046400 +0900 @@ -94,7 +94,8 @@ # Are we running in a non-root Location block? my $location = $self->apache->location; if ( $location && $location ne '/' ) { - $base_path = $location; + $self->apache->path_info =~ m/$location/msx; + $base_path = $&; } # Are we an Apache::Registry script? Why anyone would ever want to run
とすれば良さげ。
Catalystの中の人にパッチ投げて感想聞いてみよう。