2012-06-24 23 views
6

Điều này tôi đang cố chuyển trang web Apache/Modperl hiện tại của tôi sang Starman và cần xây dựng app.psgi với các trình xử lý khác nhau cho các phần mở rộng tệp khác nhau. Somthing như trong Apache:Chuyển đổi cấu hình Modperl thành Plack - chạy các trình xử lý khác nhau theo phần mở rộng tập tin

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

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

Bây giờ tôi có:

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

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

nhưng làm thế nào để sử dụng xây dựng?

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

Needed "quy tắc":

  • nếu yêu cầu không có bất kỳ phần mở rộng, hoặc các yêu cầu kết thúc bằng '/'
    • cần được xử lý với $Mapp
  • nếu yêu cầu kết thúc bằng một số tiện ích, sau đó
    • .m.mh nên được xử lý bởi $Mapp
    • .p.ph nên được xử lý bởi $Papp
    • tất cả các file khác với phần mở rộng (như .css .js .pdf .jpg ...) nên được xử lý như tĩnh.

Chắc chắn, sẽ dễ dàng hơn đưa mỗi tập tin tĩnh vào một số cây, nhưng các ứng dụng hiện tại đưa ra và bây giờ tôi chỉ muốn di chuyển nó vào Startman, refactoring - sau đó.

Trả lời

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

huh! Cố gắng hiểu điều này. :) – kobame

+0

nhưng CÓ! Bí quyết chính là sử dụng "phụ" trong đường dẫn cho Tĩnh và nhóm hai ứng dụng thành một để quyết định. BTW, không bao giờ sử dụng bất kỳ Tie nào ..;) THANX rất nhiều !!! :) – kobame

Các vấn đề liên quan