File Coverage

blib/lib/Plack/Middleware/Rewrite.pm
Criterion Covered Total %
statement 61 64 95.3
branch 34 38 89.4
condition 9 12 75.0
subroutine 10 10 100.0
pod 1 1 100.0
total 115 125 92.0


line stmt bran cond sub pod time code
1 3     3   1717 use 5.006; use strict; use warnings;
  3     3   9  
  3     3   24  
  3         5  
  3         51  
  3         11  
  3         5  
  3         186  
2              
3             package Plack::Middleware::Rewrite;
4              
5             our $VERSION = '2.102';
6              
7 3     3   17 BEGIN { require Plack::Middleware; our @ISA = 'Plack::Middleware' }
  3         122  
8              
9 3     3   16 use Plack::Util::Accessor qw( request response rules );
  3         3  
  3         24  
10 3     3   1448 use Plack::Request ();
  3         155126  
  3         63  
11 3     3   23 use Plack::Util ();
  3         5  
  3         35  
12 3     3   13 use overload ();
  3         5  
  3         1500  
13              
14             sub call {
15 39     39 1 119171 my $self = shift;
16 39         61 my ( $env ) = @_;
17              
18 39         58 my ( $app, $res, $legacy );
19 39         96 my ( $rules, $modify_cb ) = ( $self->request, $self->response );
20              
21 39 100 100     413 unless ( $rules or $modify_cb ) {
22 19         31 $rules = $self->rules;
23 19         61 $legacy = 1;
24             }
25              
26             # call rules with $_ aliased to PATH_INFO
27 39 100       86 ( $res ) = map { scalar $rules->( $env ) } $env->{'PATH_INFO'}
  32         67  
28             if $rules;
29              
30 39 100       433 if ( $legacy ) {
31 19 100       55 if ( 'CODE' eq ref $res ) { ( $modify_cb, $res ) = $res }
  6 100       8  
    50          
32 4 100       9 elsif ( 'ARRAY' eq ref $res ) { undef $res if not @$res }
33 0         0 elsif ( ref $res ) { undef $res }
34             else {
35             # upgrade scalar to response if it looks like an HTTP status
36 9 100 100     45 $res = ( defined $res and $res =~ /\A[1-5][0-9][0-9]\z/ )
37             ? [ $res, [], [] ]
38             : undef;
39             }
40             }
41             else {
42 20 50       63 if ( 'CODE' eq ref $res ) { ( $app, $res ) = $res }
  0 100       0  
    50          
43 10 100       21 elsif ( 'ARRAY' eq ref $res ) { @$res = ( 303, [], [] ) if not @$res }
44 0         0 elsif ( ref $res ) { die 'Unhandled reference type in request rewrite: ', overload::StrVal( $res ), "\n" }
45 10         18 else { undef $res }
46             }
47              
48 39 100       74 if ( $res ) { # external redirect, or explicit response
49 18         33 push @$res, map { [] } @$res .. 2;
  12         20  
50              
51 18 100       70 if ( $res->[0] =~ /\A3(?:0[0-35-9]|[1-9][0-9])\z/ ) {
52 11         39 my $dest = Plack::Util::header_get( $res->[1], 'Location' );
53 11 100       94 if ( not $dest ) {
54 9         35 $dest = Plack::Request->new( $env )->uri;
55 9         2181 Plack::Util::header_set( $res->[1], Location => $dest );
56             }
57              
58 11 100 66     84 unless (
59             Plack::Util::content_length( $res->[2] )
60             or Plack::Util::header_exists( $res->[1], 'Content-Length' )
61             ) {
62 9         216 my $href = Plack::Util::encode_html( $dest );
63 9         185 Plack::Util::header_set( $res->[1], qw( Content-Type text/html ) );
64 9         133 $res->[2] = [ qq'MovedThis resource has moved to a new address.' ];
65             }
66             }
67             }
68             else { # internal redirect
69 21   33     101 $app ||= $self->app;
70 21         116 $res = $app->( $env );
71             }
72              
73 39 100       297 return $res if not $modify_cb;
74             Plack::Util::response_cb( $res, sub {
75 13     13   163 my $response = $_[0];
76 13         31 my $hdrs = Plack::Util::headers( $response->[1] );
77 13 50       277 $hdrs->{'status'} = sub { @_ ? $response->[0] = $_[0] : $response->[0] };
  2         43  
78 13         30 my ( $result ) = map $modify_cb->( $env ), $hdrs;
79 13 100       273 return 'CODE' eq ref $result ? $result : ();
80 13         66 } );
81             }
82              
83             1;
84              
85             __END__