This file is indexed.

/usr/share/perl5/Web/Dispatch.pm is in libweb-simple-perl 0.033-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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package Web::Dispatch;

use Sub::Quote;
use Scalar::Util qw(blessed);

sub MAGIC_MIDDLEWARE_KEY { __PACKAGE__.'.middleware' }

use Moo;
use Web::Dispatch::Parser;
use Web::Dispatch::Node;

with 'Web::Dispatch::ToApp';

has dispatch_app => (
  is => 'lazy', builder => sub { shift->dispatch_object->to_app }
);
has dispatch_object => (is => 'ro', required => 0, weak_ref => 1);
has parser_class => (
  is => 'ro', default => quote_sub q{ 'Web::Dispatch::Parser' }
);
has node_class => (
  is => 'ro', default => quote_sub q{ 'Web::Dispatch::Node' }
);
has _parser => (is => 'lazy');

after BUILDARGS => sub {
  my ( $self, %args ) = @_;
  die "Either dispatch_app or dispatch_object need to be supplied."
    if !$args{dispatch_app} and !$args{dispatch_object}
};

sub _build__parser {
  my ($self) = @_;
  $self->parser_class->new;
}

sub call {
  my ($self, $env) = @_;
  my $res = $self->_dispatch($env, $self->dispatch_app);
  return $res->[0] if ref($res) eq 'ARRAY' and @{$res} == 1 and ref($res->[0]) eq 'CODE';
  return $res;
}

sub _dispatch {
  my ($self, $env, @match) = @_;
  while (defined(my $try = shift @match)) {

    return $try if ref($try) eq 'ARRAY';
    if (ref($try) eq 'HASH') {
      $env = { 'Web::Dispatch.original_env' => $env, %$env, %$try };
      next;
    }

    my @result = $self->_to_try($try, \@match)->($env, @match);
    next unless @result and defined($result[0]);

    my $first = $result[0];

    if (my $res = $self->_have_result($first, \@result, \@match, $env)) {

      return $res;
    }

    # make a copy so we don't screw with it assigning further up
    my $env = $env;
    unshift @match, sub { $self->_dispatch($env, @result) };
  }

  return;
}

sub _have_result {
  my ($self, $first, $result, $match, $env) = @_;

  if (ref($first) eq 'ARRAY') {
    return $first;
  }
  elsif (blessed($first) && $first->isa('Plack::Middleware')) {
    return $self->_uplevel_middleware($first, $result);
  }
  elsif (ref($first) eq 'HASH' and $first->{+MAGIC_MIDDLEWARE_KEY}) {
    return $self->_redispatch_with_middleware($first, $match, $env);
  }
  elsif (
    blessed($first) &&
    not($first->can('to_app')) &&
    not($first->isa('Web::Dispatch::Matcher'))
  ) {
    return $first;
  }
  return;
}

sub _uplevel_middleware {
  my ($self, $match, $results) = @_;
  die "Multiple results but first one is a middleware ($match)"
    if @{$results} > 1;
  # middleware needs to uplevel exactly once to wrap the rest of the
  # level it was created for - next elsif unwraps it
  return { MAGIC_MIDDLEWARE_KEY, $match };
}

sub _redispatch_with_middleware {
  my ($self, $first, $match, $env) = @_;

  my $mw = $first->{+MAGIC_MIDDLEWARE_KEY};

  $mw->app(sub { $self->_dispatch($_[0], @{$match}) });

  return $mw->to_app->($env);
}

sub _to_try {
  my ($self, $try, $more) = @_;

  # sub (<spec>) {}      becomes a dispatcher
  # sub {}               is a PSGI app and can be returned as is
  # '<spec>' => sub {}   becomes a dispatcher
  # $obj isa WD:Predicates::Matcher => sub { ... } -  become a dispatcher
  # $obj w/to_app method is a Plack::App-like thing - call it to get a PSGI app
  #

  if (ref($try) eq 'CODE') {
    if (defined(my $proto = prototype($try))) {
      $self->_construct_node(match => $proto, run => $try);
    } else {
      $try
    }
  } elsif (!ref($try)
    and (ref($more->[0]) eq 'CODE'
      or ($more->[0] and !ref($more->[0]) and $self->dispatch_object
        and $self->dispatch_object->can($more->[0])))
  ) {
    $self->_construct_node(match => $try, run => shift(@$more));
  } elsif (
    (blessed($try) && $try->isa('Web::Dispatch::Matcher'))
    and (ref($more->[0]) eq 'CODE')
  ) {
    $self->_construct_node(match => $try, run => shift(@$more));
  } elsif (blessed($try) && $try->can('to_app')) {
    $try->to_app;
  } else {
    die "No idea how we got here with $try";
  }
}

sub _construct_node {
  my ($self, %args) = @_;
  $args{match} = $self->_parser->parse($args{match}) if !ref $args{match};
  if ( my $obj = $self->dispatch_object) {
    # if possible, call dispatchers as methods of the app object
    my $dispatch_sub = $args{run};
    $args{run} = sub { $obj->$dispatch_sub(@_) };
  }
  $self->node_class->new(\%args)->to_app;
}

1;