2012-06-24 5 views
6

Questo sto cercando di trasferire il mio attuale sito Apache/Modperl su Starman e ho bisogno di creare app.psgi con diversi gestori per diverse estensioni di file. Somthing come nel Apache:Conversione di Modperl config in Plack - esecuzione di diversi gestori per estensione file

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

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

Ora ho:

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

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

ma come utilizzare il costruttore?

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 
}; 

necessarie "regole":

  • non se la richiesta fa ha alcuna estensione o la richiesta termina con '/'
    • deve essere maneggiato con $Mapp
  • se la richiesta termina con qualche estensione, quindi
    • .m e .mh devono essere gestite dal $Mapp
    • .p e .ph devono essere gestite dal $Papp
    • tutti gli altri file con le estensioni (come css js .pdf .jpg ...) devono essere trattati come statica.

Certo, sarà molto più facile mettere ogni file statico in qualche albero, ma l'applicazione corrente è data e ora voglio solo spostarlo in Startman, refactoring - in seguito.

risposta

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' 
+0

eh! Andando a provare a capire questo. :) – kobame

+0

ma SÌ! Il trucco principale è usare un "sub" nel percorso per lo statico e raggruppare due app in una per decisione. BTW, mai usato nessun legame ancora ..;) THANX molto !!! :) – kobame

Problemi correlati