2011-09-07 13 views
5

Tek app uygulamasının bir dansçıya sahip olmasının bir yolu var, ancak birden fazla appdir.Dancer perl ile çoklu uygulama dizinleri

Projem dir 'foo' içinde:

Ya böyle bir şey yapabilirdi. Ve diyelim ki 'public' adında bir dizine sahip bir 'bar' ('foo' içinde değil) var. Uygulamamın bu halkı kendi halkı olarak kullanması için yaptıklarım ve eğer '/css/style.css' yazalımsa ve '/ bar/public /' konumunda değilse '/ foo/kelimesini aramalıyız halka açık/'. Bunu nasıl yapabilirim?

cevap

2

Statik (ve bazı işlevlerin yerine geçer) işleyen bir eklenti yazmanın yollarından biri. Örnek olarak Dancer::Plugin::Thumbnail'u kullanabilirsiniz. Gördüğüm başka bir şey de, Dancer::Renderer numaralı maymunda get_file_response() maymun düzeltme eki için gerçekten iyi bir fikir değil.

Aşağıdaki kod, her bir direkte @dirs dizisinden gelen statik dosyaları arar. Kirli, çirkin ve güvensiz. Bu, gelecekteki sürümde bozulabilir ve aşina olmadığınız Dancer çerçevesinin diğer kısımlarında sorunlara neden olabilir. Sen uyardın.

#!/usr/bin/env perl 
use Dancer; 
use Dancer::Renderer; 
use MyWeb::App; 

my $get_file_response_original = \&Dancer::Renderer::get_file_response; 
my @dirs = ('foo'); 

*Dancer::Renderer::get_file_response = sub { 
    my $app = Dancer::App->current; 

    my $result; 

    # Try to find static in default dir 
    if ($result = $get_file_response_original->(@_)) { 
     return $result; 
    } 

    # Save current settings 
    my $path_backup = $app->setting('public'); 

    # Go through additional dirs 
    foreach my $dir (@dirs) { 
     $app->setting(public => $dir); 
     if ($result = $get_file_response_original->(@_)) { 
      last; 
     } 
    } 

    # Restore public 
    $app->setting('public' => $path_backup); 

    return $result 
}; 

dance; 

Üçüncü yolları uygulamanız için uygun nginx yapılandırma yazarak nginx sadece sizin için bu işi yapmak izin vermektir.

+0

olacak Yakında GitHub'dan bugün bu modülü yüklendi edebilirsiniz. – bliof

+0

@bliof Cevabımı güncelledim, bunu deneyebilirsiniz, ancak nginx ile devam etseniz iyi olur. – yko

+0

Başka bir şey düşünüyordum. Bir eklentiyi 'foo' yapabilir miyim ve 'bar' içinde kullanabilir miyim? Asıl soru, bir Dancer eklentisinin bir dansçı uygulamasının işlevselliğine sahip olmasıdır. URL'leri ondan eşleyebilir ve 'views' klasöründen şablon yükleyebilir miyim?/Hiç bir eklenti yazmamıştım/ – bliof

7

Tamam, işte yapmanız gereken en iyi yol. Elbette bir eklenti olabilir.

Sen Dancer çekirdeğinde içine hack yoluyla bu tür şeyleri yapmaya asla

, yerine her zaman işi yapmak için bir rota işleyicisi uygulamak düşünmelisiniz:

#!/usr/bin/env perl 
use Dancer; 
use File::Spec; 
use Dancer::FileUtils 'read_file_content'; 
use Dancer::MIME; 
use HTTP::Date; 

# your routes here 

# then the catchall route for 
# serving static files 

# better in config 
my @public_dirs = qw(/tmp/test/foo /tmp/test/bar /tmp/test/baz); 

get '/**' => sub { 
    my $path = request->path; 
    my $mime = Dancer::MIME->instance; 

    # security checks 
    return send_error("unauthrorized request", 403) if $path =~ /\0/; 
    return send_error("unauthrorized request", 403) if $path =~ /\.\./; 

    # decompose the path_info into a file path 
    my @path = split '/', $path; 

    for my $location (@public_dirs) { 
     my $file_path = File::Spec->catfile($location, @path); 

     next if ! -f $file_path; 

     my $content = read_file_content($file_path); 
     my $content_type = $mime->for_file($file_path); 
     my @stat = stat $file_path; 

     header 'Content-Type', $content_type; 
     header 'Content-Length', $stat[7]; 
     header 'Last-Modified', HTTP::Date::time2str($stat[9]); 
     return $content; 
    } 

    pass; 
}; 

start; 

Bu uygulamanın çalışması örneği:

$ mkdir -p /tmp/test/foo /tmp/test/bar /tmp/test/baz 
$ echo 1 > /tmp/test/foo/foo.txt 
$ echo 2 > /tmp/test/bar/bar.txt 
$ echo 3 > /tmp/test/baz/baz.txt 
$ ./bin/app.pl 
$ curl -I http://0:3000/baz.txt 
HTTP/1.0 200 OK 
Content-Length: 2 
Content-Type: text/plain 
Last-Modified: Fri, 14 Oct 2011 11:28:03 GMT 
X-Powered-By: Perl Dancer 1.3051