This file is indexed.

/usr/share/perl5/Plack/Middleware/Recursive.pm is in libplack-perl 1.0033-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package Plack::Middleware::Recursive;
use strict;
use parent qw(Plack::Middleware);

use Try::Tiny;
use Scalar::Util qw(blessed);

open my $null_io, "<", \"";

sub call {
    my($self, $env) = @_;

    $env->{'plack.recursive.include'} = $self->recurse_callback($env, 1);

    my $res = try {
        $self->app->($env);
    } catch {
        if (blessed $_ && $_->isa('Plack::Recursive::ForwardRequest')) {
            return $self->recurse_callback($env)->($_->path);
        } else {
            die $_; # rethrow
        }
    };

    return $res if ref $res eq 'ARRAY';

    return sub {
        my $respond = shift;

        my $writer;
        try {
            $res->(sub { return $writer = $respond->(@_) });
        } catch {
            if (!$writer && blessed $_ && $_->isa('Plack::Recursive::ForwardRequest')) {
                $res = $self->recurse_callback($env)->($_->path);
                return ref $res eq 'CODE' ? $res->($respond) : $respond->($res);
            } else {
                die $_;
            }
        };
    };
}

sub recurse_callback {
    my($self, $env, $include) = @_;

    my $old_path_info = $env->{PATH_INFO};

    return sub {
        my $new_path_info = shift;
        my($path, $query) = split /\?/, $new_path_info, 2;

        Scalar::Util::weaken($env);

        $env->{PATH_INFO}      = $path;
        $env->{QUERY_STRING}   = $query;
        $env->{REQUEST_METHOD} = 'GET';
        $env->{CONTENT_LENGTH} = 0;
        $env->{CONTENT_TYPE}   = '';
        $env->{'psgi.input'}   = $null_io;
        push @{$env->{'plack.recursive.old_path_info'}}, $old_path_info;

        $include ? $self->app->($env) : $self->call($env);
    };
}

package Plack::Recursive::ForwardRequest;
use overload q("") => \&as_string, fallback => 1;

sub new {
    my($class, $path) = @_;
    bless { path => $path }, $class;
}

sub path { $_[0]->{path} }

sub throw {
    my($class, @args) = @_;
    die $class->new(@args);
}

sub as_string {
    my $self = shift;
    return "Forwarding to $self->{path}: Your application should be wrapped with Plack::Middleware::Recursive.";
}

package Plack::Middleware::Recursive;

1;

__END__

=head1 NAME

Plack::Middleware::Recursive - Allows PSGI apps to include or forward requests recursively

=head1 SYNOPSIS

  # with Builder
  enable "Recursive";

  # in apps
  my $res = $env->{'plack.recursive.include'}->("/new_path");

  # Or, use exceptions
  my $app = sub {
      # ...
      Plack::Recursive::ForwardRequest->throw("/new_path");
  };

=head1 DESCRIPTION

Plack::Middleware::Recursive allows PSGI applications to recursively
include or forward requests to other paths. Applications can make use
of callbacks stored in C<< $env->{'plack.recursive.include'} >> to
I<include> another path to get the response (whether it's an array ref
or a code ref depending on your application), or throw an exception
Plack::Recursive::ForwardRequest anywhere in the code to I<forward>
the current request (i.e. abort the current and redo the request).

=head1 EXCEPTIONS

This middleware passes through unknown exceptions to the outside
middleware stack, so if you use this middleware with other exception
handlers such as L<Plack::Middleware::StackTrace> or
L<Plack::Middleware::HTTPExceptions>, be sure to wrap this so
L<Plack::Middleware::Recursive> gets as inner as possible.

=head1 AUTHORS

Tatsuhiko Miyagawa

Masahiro Honma

=head1 SEE ALSO

L<Plack> L<Plack::Middleware::HTTPExceptions>

The idea, code and interface are stolen from Rack::Recursive and paste.recursive.

=cut