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