lighttpdでファイルが存在しない場合にFastCGI-Catalystへ飛ばす設定とプラグイン

「そんなことしなくてもいいよ」的な猛烈な勘違いをしてたらすみませんがこっそり教えてください。

Apache

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ http://127.0.0.1:3000/$1 [L,QSA]

みたいなイメージで、

  • ファイルが存在する→そのファイルを返す
  • ファイルが存在しない→Catalystへ飛ばす

というのがしたかった。

環境は

http://unknownplace.org/slides/shibuyapm-7/start.html#slide30 を参考に

setenv.add-environment = ("SCRIPT_NAME" => "/")
server.error-handler-404 = "/myapp"
fastcgi.server = ("/myapp" => (
        ("host" => "127.0.0.1", "port" => 3000, "check-local" => "disable" )
        ))

としてみるも、$c->req->pathや$c->req->paramが空になってしまって http://localhost/foo/bar が foo/barアクションに飛んでくれない。setenv.add-environmentをコメントアウトしても同様。

ここまでは昔lighttpdを使い始めた頃にやったことがあって、ここで諦めてた。

         ,. ‐''三ヾ´彡シ,=`丶、
     /'".:=≡ミ_≧_尨彡三:ヽ、
    //.:;:彡:f'"´‐------ ``'r=:l
    /〃彡_彡′,.=、 ̄ ̄ ,.=、 |ミ:〉
   'y=、、:f´===tr==、.___,. ==、._ゞ{
   {´yヘl'′   |   /⌒l′  |`Y}
   ゙、ゝ)       `''''ツ_  _;`ー‐'゙:::::l{   あきらめたら
.    ヽ.__     ,ィnmmm、   .:::|!   そこで試合終了ですよ・・・・
  ,.ィ'´ト.´     ´`"`"`゙″ .::::;'
イ´::ノ|::::l \         "'   :::/
::::::::::::|:::::l   ヽ、      ..::  .:::/.、
:::::: ::: |:::::ヽ    ヽ、.......::::/..:::/!\\
::::::::::: |::::::::ヽ    ``''‐--ァt''′ |!:::ヽ:::\
:::::::::::::|::::::::::::ヽ、       /i|iト、  |l:::::::ヽ:::::\
:::::::::::::|::::::::::::::/:ヽ、   ∧|i|i|i|〉. ||::::::::::ヽ:::::::\

おぉ、天の声・・・



先生に励まされて調べてみた。PATH_INFOとQUERY_STRINGが設定されていない模様。一応Catalyst/Engine/FastCGI.pmには

        # If we're running under Lighttpd, swap PATH_INFO and SCRIPT_NAME
        # http://lists.rawmode.org/pipermail/catalyst/2006-June/008361.html
        # Thanks to Mark Blythe for this fix
        if ( $env{SERVER_SOFTWARE} && $env{SERVER_SOFTWARE} =~ /lighttpd/ ) {
            $env{PATH_INFO} ||= delete $env{SCRIPT_NAME};
        }

と書いてあるんだけど、そもそもSCRIPT_NAMEが固定なので(リクエストを反映できてないので)意味無さそうなんだけど。



REQUEST_URIはちゃんと入ってるっぽかったので、自前で解析するプラグイン

#
# $Id$
#
package CatalystX::Engine::FastCGI::Lighttpd;
use strict;
use warnings;
use version; our $VERSION = qv('0.0.1');

use NEXT;

sub handle_request {
    my ( $c, %args ) = @_;

    if (   $args{env}{SERVER_SOFTWARE}
        && $args{env}{SERVER_SOFTWARE} =~ /lighttpd/msx )
    {
        ( $args{env}{PATH_INFO}, $args{env}{QUERY_STRING} ) =
          ( split /\?/msx, $args{env}{REQUEST_URI}, 2 );
    }

    return $c->NEXT::handle_request(%args);
}

1;

を書いて、

# lib/MyApp.pm
use Catalyst qw(+CatalystX::Engine::FastCGI::Lighttpd);
# __PACKAGE__->setup(qw(+CatalystX::Engine::FastCGI::Lighttpd));

読み込ませると、いい感じに動いてくれました。

さっき書いたばかりなので怪しいところは多々あるかもだけど。

とりあえず気になる点と言えば REDIRECT_URL=/myappになっていて、これをどうすればいいのか分からないので放置中。Catalyst::Engine::CGIが見てるっぽいんだけど。