File Coverage

blib/lib/Plack/Middleware/Rewrite.pm
Criterion Covered Total %
statement 61 64 95.3
branch 33 36 91.6
condition 11 15 73.3
subroutine 10 10 100.0
pod 1 1 100.0
total 116 126 92.0


line stmt bran cond sub pod time code
1 3     3   1805 use 5.006;
  3         8  
  3         107  
2 3     3   13 use strict;
  3         4  
  3         81  
3 3     3   10 use warnings;
  3         4  
  3         171  
4              
5             package Plack::Middleware::Rewrite;
6             $Plack::Middleware::Rewrite::VERSION = '2.000';
7             # ABSTRACT: mod_rewrite for Plack
8              
9 3     3   13 use parent 'Plack::Middleware';
  3         3  
  3         20  
10              
11 3     3   180 use Plack::Util::Accessor qw( request response rules );
  3         8  
  3         19  
12 3     3   1538 use Plack::Request ();
  3         80400  
  3         59  
13 3     3   21 use Plack::Util ();
  3         3  
  3         32  
14 3     3   11 use overload ();
  3         4  
  3         1249  
15              
16             sub call {
17 36     36 1 95411 my $self = shift;
18 36         54 my ( $env ) = @_;
19              
20 36         32 my ( $app, $res, $legacy );
21 36         97 my ( $rules, $modify_cb ) = ( $self->request, $self->response );
22              
23 36 100 100     548 unless ( $rules or $modify_cb ) {
24 18         30 $rules = $self->rules;
25 18         53 $legacy = 1;
26             }
27              
28             # call rules with $_ aliased to PATH_INFO
29 36 100       92 ( $res ) = map { scalar $rules->( $env ) } $env->{'PATH_INFO'}
  30         56  
30             if $rules;
31              
32 36 100       371 if ( $legacy ) {
33 18 100       48 if ( 'CODE' eq ref $res ) { ( $modify_cb, $res ) = $res }
  5 100       10  
    50          
34 4 100       10 elsif ( 'ARRAY' eq ref $res ) { undef $res if not @$res }
35 0         0 elsif ( ref $res ) { undef $res }
36             else {
37             # upgrade scalar to response if it looks like an HTTP status
38 9 100 100     53 $res = ( defined $res and $res =~ /\A[1-5][0-9][0-9]\z/ )
39             ? [ $res, [], [] ]
40             : undef;
41             }
42             }
43             else {
44 18 50       52 if ( 'CODE' eq ref $res ) { ( $app, $res ) = $res }
  0 100       0  
    50          
45 9 100       23 elsif ( 'ARRAY' eq ref $res ) { @$res = ( 303, [], [] ) if not @$res }
46 0         0 elsif ( ref $res ) { die 'Unhandled reference type in request rewrite: ', overload::StrVal( $res ), "\n" }
47 9         14 else { undef $res }
48             }
49              
50 36 100       48 if ( $res ) { # external redirect, or explicit response
51 17         30 push @$res, map { [] } @$res .. 2;
  10         13  
52              
53 17 100       61 if ( $res->[0] =~ /\A3[0-9][0-9]\z/ ) {
54 11         32 my $dest = Plack::Util::header_get( $res->[1], 'Location' );
55 11 100       172 if ( not $dest ) {
56 9         42 $dest = Plack::Request->new( $env )->uri;
57 9         1868 Plack::Util::header_set( $res->[1], Location => $dest );
58             }
59              
60 11 100 66     192 if ( 304 ne $res->[0] and not (
      66        
61             Plack::Util::content_length( $res->[2] )
62             or Plack::Util::header_exists( $res->[1], 'Content-Length' )
63             ) ) {
64 9         233 my $href = Plack::Util::encode_html( $dest );
65 9         150 Plack::Util::header_set( $res->[1], qw( Content-Type text/html ) );
66 9         158 $res->[2] = [ qq'MovedThis resource has moved to a new address.' ];
67             }
68             }
69             }
70             else { # internal redirect
71 19   33     68 $app ||= $self->app;
72 19         128 $res = $app->( $env );
73             }
74              
75 36 100       311 return $res if not $modify_cb;
76             Plack::Util::response_cb( $res, sub {
77 11     11   133 my ( $res ) = map { $modify_cb->( $env ) } Plack::Util::headers( $_[0][1] );
  11         196  
78 11 100       250 return $res if 'CODE' eq ref $res;
79 9         32 return;
80 11         47 } );
81             }
82              
83             1;
84              
85             __END__