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