6

これは、現在のApache / ModperlサイトをStarmanに転送しようとしているため、ファイル拡張子ごとに異なるハンドラーを使用してapp.psgiをビルドする必要があります。Apacheのようなもの:

<LocationMatch "(\.m|\.mh|\/)$">
     SetHandler              perl-script
     PerlHandler             MyApp::Mhandler
</LocationMatch>

<LocationMatch "(\.p|\.ph)$">
     SetHandler              perl-script
     PerlHandler             MyApp::Phandler
</LocationMatch>

今私が持っています:

#app for handle .m and .mh
my $Mapp = Some::PSGI->handler( sub {
...
});

#app for handling .p and .ph
my $Papp = SomeOther::PSGI->handler( sub {
...
});

しかし、ビルダーの使い方は?

builder {

    #any extension what is not .m .mh .p .ph - handle as static
    #but, only when the request have any extension
    enable "Plack::Middleware::Static",
      path => __what here__, ???
      root => "/my/doc/root";

    #and what here to achieve the following "rules".

    #??? $Papp
    #default $Mapp
};

必要な「ルール」:

  • リクエストに拡張子がない場合、またはリクエストが「/」で終わる場合
    • で処理する必要があります$Mapp
  • リクエストが何らかの拡張子で終了する場合は、
    • .m.mhによって処理する必要があります$Mapp
    • .p.phによって処理する必要があります$Papp
    • 拡張子が付いた他のすべてのファイル(.css .js .pdf .jpg ...など)は静的として処理する必要があります。

もちろん、すべての静的ファイルをツリーに配置する方がはるかに簡単ですが、現在のアプリ提供されているので、後でリファクタリングしてStartmanに移動するだけです。

4

1 に答える 1

2
use strictures;
use Plack::Request qw();
use Plack::Builder qw(builder enable);
use Tie::REHash do_cache => 1;

tie my %location_match, 'Tie::REHash';
%location_match = (
    qr'(\.m|\.mh|/|/[^.]+)$' => sub {[200,[],['Mhandler']]},
    qr'(\.p|\.ph)$'          => sub {[200,[],['Phandler']]},
);

my $app = sub {
    my ($env) = @_;
    my $req = Plack::Request->new($env);
    my $res;
    if ($location_match{$req->path_info}) {
        printf "path [%s] dispatches to %s\n", $req->path_info, $location_match{$req->path_info};
        $res = $location_match{$req->path_info};
    } else {
        die sprintf "no match for path [%s], check routing configuration\n", $req->path_info;
    }
    return $res->($env);
};

builder {
    enable 'Static', path => sub {
        my ($path) = @_;
        if ($location_match{$path}) {
            print "redispatch\n";
            return;
        } elsif ($path =~ qr'/ [^/]+ [.] [^/]+ $'x) {
            return 1;
        } else {
            die "no match for path [$path], check routing configuration\n";
        }
    }, root => './htdocs/';
    $app;
}

__END__
GET 'http://localhost:5000/foo?bar=baz;quux#fnord'
GET 'http://localhost:5000/foo/?bar=baz;quux#fnord'
GET 'http://localhost:5000/foo.m?bar=baz;quux#fnord'
GET 'http://localhost:5000/foo.mh?bar=baz;quux#fnord'
GET 'http://localhost:5000/foo.p?bar=baz;quux#fnord'
GET 'http://localhost:5000/foo.ph?bar=baz;quux#fnord'
GET 'http://localhost:5000/foo.css?bar=baz;quux#fnord'
GET 'http://localhost:5000/foo.js?bar=baz;quux#fnord'
GET 'http://localhost:5000/foo.pdf?bar=baz;quux#fnord'
GET 'http://localhost:5000/foo.jpg?bar=baz;quux#fnord'
于 2012-06-24T14:50:56.973 に答える