|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Cake::Dispatcher;
  | 
| 
2
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
45
 | 
 use strict;
  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
245
 | 
    | 
| 
3
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
40
 | 
 use warnings;
  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
171
 | 
    | 
| 
4
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
44
 | 
 use Carp;
  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17839
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #============================================================================
  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # setup
  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #============================================================================
  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub setup {
  | 
| 
10
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
1918
 | 
     my $self = shift;
  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #match current route
  | 
| 
12
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     $self->match();
  | 
| 
13
 | 
3
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
16
 | 
     if (defined $self->controller and $self->controller->can('begin')){
  | 
| 
14
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->controller->begin($self);
  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ##dispatch & excute
  | 
| 
18
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     $self->dispatch();
  | 
| 
19
 | 
3
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
16
 | 
     if (defined $self->controller and $self->controller->can('end')){
  | 
| 
20
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->controller->end($self);
  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }
  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #============================================================================
  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # dispatch: sending to the match route and execute
  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #============================================================================
  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub dispatch {
  | 
| 
28
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
8
 | 
     my $self = shift;
  | 
| 
29
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my $args = shift;
  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
31
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     my $actionclass = $self->ActionClass;
  | 
| 
32
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     my $controller = $self->controller;
  | 
| 
33
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     my $code = $self->code;
  | 
| 
34
 | 
3
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
20
 | 
     $args ||= $self->action->{args};
  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ##running actions
  | 
| 
37
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     if ($actionclass){
  | 
| 
38
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $actionclass->execute($controller,$self,$code,$args);
  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ##running auto blocks
  | 
| 
42
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     if (my $auto = $self->auto_chain->{ref $controller}){
  | 
| 
43
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $line = $self->action->{line};
  | 
| 
44
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         map { __PACKAGE__->execute($controller,$self,$_->{code},$args) if $_->{line} < $line } @{$auto};
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
47
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     __PACKAGE__->execute($controller,$self,$code,$args);
  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }
  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #============================================================================
  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # match : match current request path with routes
  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #============================================================================
  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##match sequence
  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ## 1) direct paths - 2) paths with defined arguments - 3) chained - 4) regex
  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub match {
  | 
| 
57
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
13
 | 
     my $self = shift;
  | 
| 
58
 | 
3
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
37
 | 
     my $path = shift || $self->path;
  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
60
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     $self->log("Start Searching For $path path");
  | 
| 
61
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
     my $method = $self->method;
  | 
| 
62
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
84
 | 
     my $dispatch = $self->dispatcher;
  | 
| 
63
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     my $match;
  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my @captures;
  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
66
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     $self->log("1- Trying Direct Path Match");
  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
68
 | 
3
 | 
  
  0
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
31
 | 
     if ($dispatch->{$path} && ($match = $dispatch->{$path}->{$method}) && !$dispatch->{$path}->{$method}->{chain}){
  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->addAction($match,"Direct Match");
  | 
| 
70
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         return;
  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
73
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     $self->log("2- Trying PAths With Arguments");
  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ## nothing found in direct paths, lets try with args
  | 
| 
75
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     (my $tpath = $path) =~ s/^\///;
  | 
| 
76
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     my @args = split(/\//,$tpath);
  | 
| 
77
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
84
 | 
     my $i = $#args+1;
  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ####get sequence of path - arg ...   /first/second(1)   /first(2)   /(3)
  | 
| 
80
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     my $t;
  | 
| 
81
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     my @t = reverse (map { --$i; $t .= '/'.$_;  $t.'('.$i.')' } @args);
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
82
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     push(@t,'/'.'('.($#args+1).')');
  | 
| 
83
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     foreach my $this (@t){
  | 
| 
84
 | 
3
 | 
  
  0
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
15
 | 
         if ($dispatch->{$this} && ($match = $dispatch->{$this}->{$method}) && !$dispatch->{$this}->{$method}->{chain}){
  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ##capture
  | 
| 
86
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             @captures = splice(@args,-$i,$i);
  | 
| 
87
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $self->addAction($match,"Path with arguments Match", @captures);
  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             
  | 
| 
89
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             return;
  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }
  | 
| 
91
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         $i++;
  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
94
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     $self->log("3- Trying Chained Actions");
  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ##lets try chains
  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ####start with chain indexes and search for best match
  | 
| 
97
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     if ( my $indexes = $dispatch->{chains_index} ){
  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         
  | 
| 
99
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         local $self->{chain_action};
  | 
| 
100
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         local $self->{chain_sequence};
  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         
  | 
| 
102
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         for my $index (@{$indexes}){
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #die Dumper $chain->{$index_path};
  | 
| 
104
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $return = $self->_loop_chains($path,$index,1);
  | 
| 
105
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
             $return && $return == 1 ? next : last;
  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }
  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         
  | 
| 
108
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if ($self->{chain_action}){
  | 
| 
109
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my @chain = @{$self->{chain_action}};
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
110
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $lastaction = pop @chain;
  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             
  | 
| 
112
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             for my $action (@chain){
  | 
| 
113
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $self->addAction($action,"Chained Match");
  | 
| 
114
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $self->dispatch();
  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }
  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
            
  | 
| 
117
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $self->addAction($lastaction,"Last Chained Match");
  | 
| 
118
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             return;
  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             
  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }
  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
123
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     $self->log("4- Trying Regex Match");
  | 
| 
124
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     if ($dispatch->{regex}){
  | 
| 
125
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         my $oldstrength = '';
  | 
| 
126
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         my $match;
  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         
  | 
| 
128
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
         foreach my $this (@{$dispatch->{regex}}){
  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
129
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
             if ($path =~ m/$this->{regex}/){
  | 
| 
130
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 next if (!grep(/$method/,@{$this->{methods}}));
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 ###select the strongest
  | 
| 
132
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 my $localpath = $path; $localpath =~ s/$this->{regex}//;
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
133
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 my $strength = length $localpath;
  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 
  | 
| 
135
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
                 if ($oldstrength eq '' || $strength < $oldstrength){
  | 
| 
136
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     $match = $this;
  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }
  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 
  | 
| 
139
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $oldstrength = $strength;
  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 #return;
  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }
  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }
  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         
  | 
| 
144
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         if ($match){
  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ##capture it
  | 
| 
146
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             @captures = ($path =~ m/$match->{regex}$/);
  | 
| 
147
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             @{$self->{capture}} = map { split('/',$_) } @captures;
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
148
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $self->addAction($match->{action},"Regex Match",@{$self->{capture}});
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
149
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             return;
  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }
  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
153
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     $self->log("There is no matching route for $path");
  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ##does the app defined a sub to process not found locations?
  | 
| 
156
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     if ($self->app->can('notfound')){
  | 
| 
157
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->app->notfound($self);
  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {
  | 
| 
159
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
         $self->status_code('404');
  | 
| 
160
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
         $self->body('Not Found');
  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }
  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _loop_chains {
  | 
| 
165
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my $self = shift;
  | 
| 
166
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $path = shift;
  | 
| 
167
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $dir = shift;
  | 
| 
168
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $add_namespace = shift;
  | 
| 
169
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $regex;
  | 
| 
170
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $dispatch = $self->dispatcher;
  | 
| 
171
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $chain = $dispatch->{chains};
  | 
| 
172
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $thisChain = $chain->{$dir};
  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
174
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $route = $add_namespace ?
  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $dir :
  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $thisChain->{dir};
  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
178
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $args = $thisChain->{args};
  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
180
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($args){
  | 
| 
181
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $regex = qr{^$route/(.*?)$};
  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {
  | 
| 
183
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $regex = qr{^$route(.*?)$};
  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
186
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if (my ($newpath) = $path =~ m#$regex#){
  | 
| 
187
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $match = $dispatch->{$thisChain->{path}}->{$self->method}
  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         or return 1;
  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         
  | 
| 
190
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my @captures;
  | 
| 
191
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if ($args){
  | 
| 
192
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             @captures = split '/',$newpath;
  | 
| 
193
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my @args = splice @captures,0,$args;
  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ##re construct path
  | 
| 
195
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $newpath = '/'.join '/',@captures;
  | 
| 
196
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $match->{captures} = \@args;
  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }
  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         
  | 
| 
199
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $next_chain = $thisChain->{chained_by};
  | 
| 
200
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
         return 1 if !$next_chain && $newpath && (!$args || $args && @captures);
  | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
201
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         push @{$self->{action_sequence}},$match;
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         
  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ###last action in the chain
  | 
| 
204
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
         $self->{chain_action} = $self->{action_sequence} and return
  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if !$next_chain;
  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         
  | 
| 
207
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         for my $next (@{$next_chain}){
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
208
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $nextnamespace = $chain->{$next}->{namespace};
  | 
| 
209
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $return = $self->_loop_chains($newpath,$next,$nextnamespace ne $thisChain->{namespace} ? 1 : 0);
  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             
  | 
| 
211
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
             if ($return && $return == 1){
  | 
| 
212
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 next;
  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }
  | 
| 
214
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             return;
  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }
  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         
  | 
| 
217
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         @{$self->{action_sequence}} = splice @{$self->{action_sequence}},0,-1;
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
220
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return 1;
  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }
  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub addAction {
  | 
| 
226
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     my $self = shift;
  | 
| 
227
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $match = shift;
  | 
| 
228
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $type = shift;
  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
230
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->log("PINGO: $type Found in " . $match->{class} . " at line " . $match->{line} );
  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
232
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my @captures;
  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
234
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if (@_) {
  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
235
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         @captures = @_;
  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($match->{captures}){
  | 
| 
237
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         @captures = @{$match->{captures}};
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->action({
  | 
| 
241
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
         ActionClass => $match->{ActionClass},
  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         controller => bless($self->config->{$match->{class}} || {},$match->{class}),
  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         code => _get_code($match->{class},$match->{code}),
  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         line => $match->{line},
  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         namespace => $match->{namespace},
  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         args => \@captures
  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     });
  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ##log captures
  | 
| 
250
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     if ($self->debug && @captures){
  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->log(sub {
  | 
| 
252
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
             my $msg = '';
  | 
| 
253
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $msg .= "=================\n";
  | 
| 
254
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $msg .= "  Captured Args  \n";
  | 
| 
255
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $msg .= "=================\n";
  | 
| 
256
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             foreach my $arg (@captures){
  | 
| 
257
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $msg .= $arg."\n";
  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }
  | 
| 
259
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             return $msg;
  | 
| 
260
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         });
  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
263
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     if (@captures && ref $match->{args} eq 'ARRAY'){
  | 
| 
264
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $count = -1;
  | 
| 
265
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my %capture = map {  ++$count; $_ => $captures[$count] } @{$match->{args}};
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
266
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->action->{args} = \%capture;
  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     
  | 
| 
269
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return;
  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }
  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #============================================================================
  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # excute : execute current action
  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #============================================================================
  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub execute {
  | 
| 
276
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
10
 | 
     shift;
  | 
| 
277
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     my ($controller,$c,$method,$args) = @_;
  | 
| 
278
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     if (ref $method eq 'CODE'){
  | 
| 
279
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my @args = ref $args eq 'HASH' ? values %{$args} : @{$args};
  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
280
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return $method->($controller,$c,@args);
  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }
  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #============================================================================
  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # private method
  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #============================================================================
  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _get_code {
  | 
| 
289
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
     my $controller = shift;
  | 
| 
290
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $method = shift;
  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ###convert method to CODE ref
  | 
| 
292
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (ref $method ne 'CODE'){
  | 
| 
293
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $method = $controller.'::'.$method;
  | 
| 
294
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $method = \&$method;
  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }
  | 
| 
296
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $method;
  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }
  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;
  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__
  |