File Coverage

blib/lib/Puncheur/Plugin/HandleStatic.pm
Criterion Covered Total %
statement 34 53 64.1
branch 6 20 30.0
condition 3 15 20.0
subroutine 8 8 100.0
pod 0 1 0.0
total 51 97 52.5


line stmt bran cond sub pod time code
1             package Puncheur::Plugin::HandleStatic;
2 1     1   695 use 5.010;
  1         4  
  1         38  
3 1     1   6 use strict;
  1         2  
  1         30  
4 1     1   5 use warnings;
  1         3  
  1         28  
5              
6 1     1   854 use MIME::Base64;
  1         1328  
  1         81  
7 1     1   8 use Encode;
  1         2  
  1         746  
8              
9             our @EXPORT = qw/to_psgi/;
10              
11             sub to_psgi {
12 1     1 0 4 my ($self, %opts) = @_;
13 1 50       5 $self = $self->new unless ref $self;
14              
15 1         6 my $app = $self->Puncheur::to_psgi;
16 1 50 33     12 if (delete $opts{handle_static} || $self->{handle_static}) {
17             my $vpath = sub {
18 1     1   15 for my $dir (@{ $self->template_dir }) {
  1         9  
19 1 50       7 return $dir if ref $dir eq 'HASH';
20             }
21 1         7 }->();
22 1         929 require Plack::App::File;
23 1         16323 my $orig_app = $app;
24 1         2 my $app_file_1;
25             my $app_file_2;
26              
27 1         24 my $asset_dir = $self->asset_dir;
28 1         13 my $static_dir = File::Spec->catdir( $asset_dir, 'static' );
29             $app = sub {
30 2     2   49407 my $env = shift;
31 2         7 my $path_info = $env->{PATH_INFO};
32 2 50 33     51 if ($vpath and my $content = $vpath->{$path_info} and $path_info =~ m{^/}) {
    50 33        
    50          
33 0         0 my $ct = Plack::MIME->mime_type($path_info);
34              
35 0         0 my $app_name = $self->app_name;
36 0         0 my $is_text = qr/\b(?:text|xml|javascript|json)\b/;
37 0         0 state $cache = {};
38 0 0       0 if ($cache->{$app_name}{$path_info}) {
39 0         0 $content = $cache->{$app_name}{$path_info};
40             }
41             else {
42 0 0       0 if ($ct =~ $is_text) {
43 0         0 $content = encode($self->encoding, $content);
44             }
45             else {
46 0         0 $content = decode_base64($content);
47             }
48 0         0 $cache->{$app_name}{$path_info} = $content;
49             }
50              
51 0 0       0 if ($ct =~ $is_text) {
52 0         0 my $encoding = $self->encoding;
53 0 0       0 $encoding = lc $encoding->mime_name if ref $encoding;
54 0         0 $ct .= "; charset=$encoding";
55             }
56 0         0 return [200, ['Content-Type' => $ct, 'Content-Length' => length($content)], [$content]];
57             }
58             elsif ($path_info =~ qr{^(?:/robots\.txt|/favicon\.ico)$}) {
59 0   0     0 $app_file_1 ||= Plack::App::File->new({ root => $static_dir });
60 0         0 return $app_file_1->call($env);
61             }
62             elsif ($path_info =~ m{^/static/}) {
63 0   0     0 $app_file_2 ||= Plack::App::File->new({ root => $asset_dir });
64 0         0 return $app_file_2->call($env);
65             }
66             else {
67 2         14 return $orig_app->($env);
68             }
69 1         10 };
70             }
71 1         6 $app;
72             }
73              
74             1;