File Coverage

blib/lib/Plack/Middleware/Rewrite.pm
Criterion Covered Total %
statement 62 65 95.3
branch 34 38 89.4
condition 11 15 73.3
subroutine 10 10 100.0
pod 1 1 100.0
total 118 129 91.4


line stmt bran cond sub pod time code
1 3     3   2228 use 5.006;
  3         12  
2 3     3   15 use strict;
  3         6  
  3         67  
3 3     3   25 use warnings;
  3         7  
  3         162  
4              
5             package Plack::Middleware::Rewrite;
6             $Plack::Middleware::Rewrite::VERSION = '2.101';
7             # ABSTRACT: mod_rewrite for Plack
8              
9 3     3   40 use parent 'Plack::Middleware';
  3         6  
  3         32  
10              
11 3     3   252 use Plack::Util::Accessor qw( request response rules );
  3         7  
  3         26  
12 3     3   2002 use Plack::Request ();
  3         186228  
  3         84  
13 3     3   33 use Plack::Util ();
  3         7  
  3         51  
14 3     3   17 use overload ();
  3         8  
  3         2010  
15              
16             sub call {
17 38     38 1 154859 my $self = shift;
18 38         89 my ( $env ) = @_;
19              
20 38         69 my ( $app, $res, $legacy );
21 38         136 my ( $rules, $modify_cb ) = ( $self->request, $self->response );
22              
23 38 100 100     559 unless ( $rules or $modify_cb ) {
24 19         47 $rules = $self->rules;
25 19         82 $legacy = 1;
26             }
27              
28             # call rules with $_ aliased to PATH_INFO
29 38 100       142 ( $res ) = map { scalar $rules->( $env ) } $env->{'PATH_INFO'}
  31         88  
30             if $rules;
31              
32 38 100       502 if ( $legacy ) {
33 19 100       63 if ( 'CODE' eq ref $res ) { ( $modify_cb, $res ) = $res }
  6 100       13  
    50          
34 4 100       14 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     58 $res = ( defined $res and $res =~ /\A[1-5][0-9][0-9]\z/ )
39             ? [ $res, [], [] ]
40             : undef;
41             }
42             }
43             else {
44 19 50       74 if ( 'CODE' eq ref $res ) { ( $app, $res ) = $res }
  0 100       0  
    50          
45 9 100       27 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 10         21 else { undef $res }
48             }
49              
50 38 100       107 if ( $res ) { # external redirect, or explicit response
51 17         41 push @$res, map { [] } @$res .. 2;
  10         24  
52              
53 17 100       85 if ( $res->[0] =~ /\A3[0-9][0-9]\z/ ) {
54 11         50 my $dest = Plack::Util::header_get( $res->[1], 'Location' );
55 11 100       123 if ( not $dest ) {
56 9         69 $dest = Plack::Request->new( $env )->uri;
57 9         2959 Plack::Util::header_set( $res->[1], Location => $dest );
58             }
59              
60 11 100 66     132 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         296 my $href = Plack::Util::encode_html( $dest );
65 9         266 Plack::Util::header_set( $res->[1], qw( Content-Type text/html ) );
66 9         184 $res->[2] = [ qq'MovedThis resource has moved to a new address.' ];
67             }
68             }
69             }
70             else { # internal redirect
71 21   33     132 $app ||= $self->app;
72 21         194 $res = $app->( $env );
73             }
74              
75 38 100       416 return $res if not $modify_cb;
76             Plack::Util::response_cb( $res, sub {
77 13     13   194 my $response = $_[0];
78 13         46 my $hdrs = Plack::Util::headers( $response->[1] );
79 13 50       373 $hdrs->{'status'} = sub { @_ ? $response->[0] = $_[0] : $response->[0] };
  2         51  
80 13         47 my ( $result ) = map $modify_cb->( $env ), $hdrs;
81 13 100       321 return 'CODE' eq ref $result ? $result : ();
82 13         79 } );
83             }
84              
85             1;
86              
87             __END__