line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
393
|
use 5.008001; use strict; use warnings; |
|
1
|
|
|
1
|
|
3
|
|
|
1
|
|
|
1
|
|
4
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
16
|
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
52
|
|
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package Router::Resource; |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = '0.22'; |
6
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
415
|
use Router::Simple::Route; |
|
1
|
|
|
|
|
2279
|
|
|
1
|
|
|
|
|
45
|
|
8
|
1
|
|
|
|
|
7
|
use Sub::Exporter -setup => { |
9
|
|
|
|
|
|
|
exports => [ qw(router resource missing GET POST PUT DELETE HEAD OPTIONS TRACE CONNECT PATCH)], |
10
|
|
|
|
|
|
|
groups => { default => [ qw(resource router missing GET POST PUT DELETE HEAD OPTIONS TRACE CONNECT PATCH) ] } |
11
|
1
|
|
|
1
|
|
569
|
}; |
|
1
|
|
|
|
|
12896
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub new { |
14
|
3
|
|
|
3
|
0
|
5
|
my $class = shift; |
15
|
3
|
|
|
|
|
10
|
bless { @_, routes => [] }; |
16
|
|
|
|
|
|
|
} |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our (%METHS, $ROUTER); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
sub router(&;@) { |
21
|
3
|
|
|
3
|
0
|
3088
|
my ($block, @settings) = @_; |
22
|
3
|
|
|
|
|
9
|
local $ROUTER = __PACKAGE__->new(@settings); |
23
|
3
|
|
|
|
|
8
|
$block->(); |
24
|
3
|
|
|
|
|
123
|
return $ROUTER; |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub resource ($&) { |
28
|
5
|
|
|
5
|
0
|
146
|
my ($path, $code) = @_; |
29
|
5
|
|
|
|
|
6
|
local %METHS = (); |
30
|
5
|
|
|
|
|
12
|
$code->(); |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# Let HEAD use GET if not specified. |
33
|
5
|
|
66
|
|
|
23
|
$METHS{HEAD} ||= $METHS{GET}; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Add OPTIONS if requested. |
36
|
5
|
100
|
66
|
|
|
15
|
if ($ROUTER->{auto_options} && !$METHS{OPTIONS}) { |
37
|
1
|
|
|
|
|
7
|
my $methods = join(', ' => 'OPTIONS', keys %METHS); |
38
|
1
|
|
|
1
|
|
4
|
$METHS{OPTIONS} = sub { [200, ['Allow', $methods], []] }; |
|
1
|
|
|
|
|
8
|
|
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# Add the route. |
42
|
5
|
|
|
|
|
8
|
push @{ $ROUTER->{routes} }, Router::Simple::Route->new( |
|
5
|
|
|
|
|
30
|
|
43
|
|
|
|
|
|
|
$path, { meths => { %METHS } } |
44
|
|
|
|
|
|
|
); |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
1
|
|
|
1
|
0
|
53
|
sub missing(&) { $ROUTER->{missing} = shift } |
48
|
6
|
|
|
6
|
1
|
31
|
sub GET(&) { $METHS{GET} = shift } |
49
|
1
|
|
|
1
|
1
|
5
|
sub HEAD(&) { $METHS{HEAD} = shift } |
50
|
2
|
|
|
2
|
1
|
11
|
sub POST(&) { $METHS{POST} = shift } |
51
|
2
|
|
|
2
|
1
|
10
|
sub PUT(&) { $METHS{PUT} = shift } |
52
|
1
|
|
|
1
|
|
6
|
sub DELETE(&) { $METHS{DELETE} = shift } |
53
|
1
|
|
|
1
|
1
|
5
|
sub OPTIONS(&) { $METHS{OPTIONS} = shift } |
54
|
1
|
|
|
1
|
1
|
6
|
sub TRACE(&) { $METHS{TRACE} = shift } |
55
|
1
|
|
|
1
|
1
|
6
|
sub CONNECT(&) { $METHS{CONNECT} = shift } |
56
|
1
|
|
|
1
|
1
|
5
|
sub PATCH(&) { $METHS{PATCH} = shift } |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub dispatch { |
59
|
20
|
|
|
20
|
0
|
10824
|
my ($self, $env) = @_; |
60
|
20
|
|
|
|
|
39
|
my $match = $self->match($env); |
61
|
20
|
100
|
|
|
|
42
|
if (my $meth = $match->{meth}) { |
62
|
15
|
|
|
|
|
52
|
return $meth->($env, $match->{data}); |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
my $missing = $self->{missing} or return [ |
65
|
5
|
100
|
|
|
|
32
|
$match->{code}, $match->{headers}, [$match->{message}] |
66
|
|
|
|
|
|
|
]; |
67
|
2
|
|
|
|
|
4
|
return $missing->($env, $match); |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub match { |
71
|
23
|
|
|
23
|
0
|
1705
|
my ($self, $env) = @_; |
72
|
23
|
50
|
50
|
|
|
71
|
my $meth = uc($env->{REQUEST_METHOD} || '') or return; |
73
|
|
|
|
|
|
|
|
74
|
23
|
|
|
|
|
31
|
for my $route (@{ $self->{routes} }) { |
|
23
|
|
|
|
|
41
|
|
75
|
48
|
100
|
|
|
|
274
|
my $match = $route->match($env) or next; |
76
|
20
|
|
|
|
|
533
|
my $meths = delete $match->{meths}; |
77
|
|
|
|
|
|
|
my $code = $meths->{$meth} or return { |
78
|
|
|
|
|
|
|
code => 405, |
79
|
|
|
|
|
|
|
message => 'not allowed', |
80
|
20
|
100
|
|
|
|
41
|
headers => [Allow => join ', ', sort keys %{ $meths } ], |
|
4
|
|
|
|
|
32
|
|
81
|
|
|
|
|
|
|
}; |
82
|
16
|
|
|
|
|
44
|
return { meth => $code, code => 200, data => $match }; |
83
|
|
|
|
|
|
|
} |
84
|
3
|
|
|
|
|
42
|
return { code => 404, message => 'not found', headers => [] }; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
1; |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
__END__ |