File Coverage

blib/lib/Plack/Middleware/XSendfile.pm
Criterion Covered Total %
statement 37 48 77.0
branch 7 18 38.8
condition 5 14 35.7
subroutine 9 10 90.0
pod 1 2 50.0
total 59 92 64.1


line stmt bran cond sub pod time code
1             package Plack::Middleware::XSendfile;
2 1     1   7 use strict;
  1         3  
  1         62  
3 1     1   9 use warnings;
  1         2  
  1         29  
4 1     1   4 use parent qw(Plack::Middleware);
  1         7  
  1         6  
5              
6 1     1   64 use Plack::Util;
  1         2  
  1         23  
7 1     1   5 use Scalar::Util;
  1         1  
  1         39  
8 1     1   6 use Plack::Util::Accessor qw( variation );
  1         1  
  1         6  
9              
10             sub call {
11 1     1 1 3 my $self = shift;
12 1         2 my $env = shift;
13              
14 1         7 my $res = $self->app->($env);
15             $self->response_cb($res, sub {
16 1     1   2 my $res = shift;
17 1         3 my($status, $headers, $body) = @$res;
18 1 50       2 return unless defined $body;
19              
20 1 50 33     15 if (Scalar::Util::blessed($body) && $body->can('path')) {
21 1   50     5 my $type = $self->_variation($env) || '';
22 1         6 my $h = Plack::Util::headers($headers);
23 1 50 33     15 if ($type && !$h->exists($type)) {
24 1 50 33     15 if ($type eq 'X-Accel-Redirect') {
    50          
25 0         0 my $path = $body->path;
26 0         0 my $url = $self->map_accel_path($env, $path);
27 0 0       0 $h->set($type => $url) if $url;
28 0         0 $h->set('Content-Length', 0);
29 0         0 $body = [];
30             } elsif ($type eq 'X-Sendfile' or $type eq 'X-Lighttpd-Send-File') {
31 1         4 my $path = $body->path;
32 1 50       10 $h->set($type => $path) if defined $path;
33 1         7 $h->set('Content-Length', 0);
34 1         16 $body = [];
35             } else {
36 0         0 $env->{'psgi.errors'}->print("Unknown x-sendfile variation: $type");
37             }
38             }
39             }
40              
41 1         18 @$res = ( $status, $headers, $body );
42 1         27 });
43             }
44              
45             sub map_accel_path {
46 0     0 0 0 my($self, $env, $path) = @_;
47              
48 0 0       0 if (my $mapping = $env->{HTTP_X_ACCEL_MAPPING}) {
49 0         0 my($internal, $external) = split /=/, $mapping, 2;
50 0         0 $path =~ s!^\Q$internal\E!$external!i;
51             }
52              
53 0         0 return $path;
54             }
55              
56             sub _variation {
57 1     1   2 my($self, $env) = @_;
58 1 50 33     4 $self->variation || $env->{'plack.xsendfile.type'} || $env->{HTTP_X_SENDFILE_TYPE};
59             }
60              
61             1;
62              
63             __END__