File Coverage

blib/lib/Plack/Middleware/ErrorDocument.pm
Criterion Covered Total %
statement 66 66 100.0
branch 18 22 81.8
condition 3 3 100.0
subroutine 9 9 100.0
pod 1 1 100.0
total 97 101 96.0


line stmt bran cond sub pod time code
1             package Plack::Middleware::ErrorDocument;
2 2     2   15 use strict;
  2         4  
  2         60  
3 2     2   10 use warnings;
  2         4  
  2         55  
4 2     2   9 use parent qw(Plack::Middleware);
  2         5  
  2         10  
5 2     2   1021 use Plack::MIME;
  2         5  
  2         72  
6 2     2   14 use Plack::Util;
  2         4  
  2         53  
7 2     2   10 use Plack::Util::Accessor qw( subrequest );
  2         3  
  2         11  
8              
9 2     2   1076 use HTTP::Status qw(is_error);
  2         9712  
  2         1176  
10              
11             sub call {
12 10     10 1 23 my $self = shift;
13 10         16 my $env = shift;
14              
15 10         66 my $r = $self->app->($env);
16              
17             $self->response_cb($r, sub {
18 10     10   22 my $r = shift;
19 10 100 100     30 unless (is_error($r->[0]) && exists $self->{$r->[0]}) {
20 6         56 return;
21             }
22              
23 4         81 my $path = $self->{$r->[0]};
24 4 100       27 if ($self->subrequest) {
25 2         13 for my $key (keys %$env) {
26 44 100       106 unless ($key =~ /^psgi/) {
27 26         69 $env->{'psgix.errordocument.' . $key} = $env->{$key};
28             }
29             }
30              
31             # TODO: What if SCRIPT_NAME is not empty?
32 2         7 $env->{REQUEST_METHOD} = 'GET';
33 2         4 $env->{REQUEST_URI} = $path;
34 2         5 $env->{PATH_INFO} = $path;
35 2         10 $env->{QUERY_STRING} = '';
36 2         5 delete $env->{CONTENT_LENGTH};
37              
38 2         8 my $sub_r = $self->app->($env);
39 2 50       20 if ($sub_r->[0] == 200) {
40 2         7 $r->[1] = $sub_r->[1];
41 2 100       6 if (@$r == 3) {
42 1         6 $r->[2] = $sub_r->[2];
43             }
44             else {
45 1         3 my $full_sub_response = '';
46             Plack::Util::foreach($sub_r->[2], sub {
47 1         20 $full_sub_response .= $_[0];
48 1         19 });
49              
50 1         11 my $returned;
51             return sub {
52 2 100       16 if ($returned) {
53 1 50       11 return defined($_[0]) ? '' : undef;
54             }
55 1         3 $returned = 1;
56 1         7 return $full_sub_response;
57             }
58 1         16 }
59             }
60             # TODO: allow 302 here?
61             } else {
62 2         23 my $h = Plack::Util::headers($r->[1]);
63 2         27 $h->remove('Content-Length');
64 2         13 $h->remove('Content-Encoding');
65 2         10 $h->remove('Transfer-Encoding');
66 2         30 $h->set('Content-Type', Plack::MIME->mime_type($path));
67              
68 2 50       97 open my $fh, "<", $path or die "$path: $!";
69 2 100       23 if ($r->[2]) {
70 1         16 $r->[2] = $fh;
71             } else {
72 1         2 my $done;
73             return sub {
74 2 100       5 unless ($done) {
75 1         2 $done = 1;
76 1         40 return join '', <$fh>;
77             }
78 1 50       6 return defined $_[0] ? '' : undef;
79 1         17 };
80             };
81             }
82 10         199 });
83             }
84              
85             1;
86              
87             __END__