| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Amon2::Lite; |
|
2
|
13
|
|
|
13
|
|
1613669
|
use strict; |
|
|
13
|
|
|
|
|
36
|
|
|
|
13
|
|
|
|
|
453
|
|
|
3
|
13
|
|
|
13
|
|
73
|
use warnings; |
|
|
13
|
|
|
|
|
29
|
|
|
|
13
|
|
|
|
|
365
|
|
|
4
|
13
|
|
|
13
|
|
295
|
use 5.008008; |
|
|
13
|
|
|
|
|
51
|
|
|
|
13
|
|
|
|
|
750
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = '0.13'; |
|
6
|
|
|
|
|
|
|
|
|
7
|
13
|
|
|
13
|
|
1296
|
use parent qw/Amon2 Amon2::Web/; |
|
|
13
|
|
|
|
|
402
|
|
|
|
13
|
|
|
|
|
112
|
|
|
8
|
13
|
|
|
13
|
|
1435613
|
use Router::Simple 0.04; |
|
|
13
|
|
|
|
|
77889
|
|
|
|
13
|
|
|
|
|
388
|
|
|
9
|
13
|
|
|
13
|
|
12165
|
use Text::Xslate; |
|
|
13
|
|
|
|
|
141952
|
|
|
|
13
|
|
|
|
|
793
|
|
|
10
|
13
|
|
|
13
|
|
14035
|
use Text::Xslate::Bridge::TT2Like; |
|
|
13
|
|
|
|
|
98425
|
|
|
|
13
|
|
|
|
|
449
|
|
|
11
|
13
|
|
|
13
|
|
134
|
use File::Spec; |
|
|
13
|
|
|
|
|
25
|
|
|
|
13
|
|
|
|
|
348
|
|
|
12
|
13
|
|
|
13
|
|
75
|
use File::Basename qw(dirname); |
|
|
13
|
|
|
|
|
26
|
|
|
|
13
|
|
|
|
|
1187
|
|
|
13
|
13
|
|
|
13
|
|
6566
|
use Data::Section::Simple (); |
|
|
13
|
|
|
|
|
3674
|
|
|
|
13
|
|
|
|
|
235
|
|
|
14
|
13
|
|
|
13
|
|
75
|
use Amon2::Config::Simple; |
|
|
13
|
|
|
|
|
19
|
|
|
|
13
|
|
|
|
|
537
|
|
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
my $COUNTER; |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
sub import { |
|
19
|
14
|
|
|
14
|
|
116
|
my $class = shift; |
|
20
|
13
|
|
|
13
|
|
61
|
no strict 'refs'; |
|
|
13
|
|
|
|
|
24
|
|
|
|
13
|
|
|
|
|
825
|
|
|
21
|
|
|
|
|
|
|
|
|
22
|
14
|
|
|
|
|
112
|
my $router = Router::Simple->new(); |
|
23
|
14
|
|
|
|
|
126
|
my $caller = caller(0); |
|
24
|
|
|
|
|
|
|
|
|
25
|
14
|
|
|
|
|
51
|
my $base_class = 'Amon2::Lite::_child_' . $COUNTER++; |
|
26
|
|
|
|
|
|
|
{ |
|
27
|
13
|
|
|
13
|
|
63
|
no warnings; |
|
|
13
|
|
|
|
|
21
|
|
|
|
13
|
|
|
|
|
22721
|
|
|
|
14
|
|
|
|
|
24
|
|
|
28
|
14
|
|
|
|
|
21
|
unshift @{"$base_class\::ISA"}, qw/Amon2 Amon2::Web/; |
|
|
14
|
|
|
|
|
393
|
|
|
29
|
14
|
|
|
|
|
48
|
unshift @{"$caller\::ISA"}, $base_class; |
|
|
14
|
|
|
|
|
145
|
|
|
30
|
|
|
|
|
|
|
} |
|
31
|
|
|
|
|
|
|
|
|
32
|
14
|
|
|
|
|
75
|
*{"$caller\::to_app"} = sub { |
|
33
|
12
|
|
|
12
|
|
816
|
my ($class, %opts) = @_; |
|
34
|
|
|
|
|
|
|
|
|
35
|
12
|
|
|
|
|
136
|
my $app = $class->Amon2::Web::to_app(); |
|
36
|
12
|
100
|
|
|
|
142
|
if (delete $opts{handle_static}) { |
|
37
|
1
|
|
|
|
|
12
|
my $vpath = Data::Section::Simple->new($caller)->get_data_section(); |
|
38
|
1
|
|
|
|
|
424694
|
require Plack::App::File; |
|
39
|
1
|
|
|
|
|
11302
|
my $orig_app = $app; |
|
40
|
1
|
|
|
|
|
2
|
my $app_file_1; |
|
41
|
|
|
|
|
|
|
my $app_file_2; |
|
42
|
1
|
|
|
|
|
84
|
my $root1 = File::Spec->catdir( dirname((caller(0))[1]), 'static' ); |
|
43
|
1
|
|
|
|
|
38
|
my $root2 = File::Spec->catdir( dirname((caller(0))[1]) ); |
|
44
|
|
|
|
|
|
|
$app = sub { |
|
45
|
4
|
|
|
4
|
|
47039
|
my $env = shift; |
|
46
|
4
|
100
|
66
|
|
|
60
|
if ((my $content = $vpath->{$env->{PATH_INFO}}) && $env->{PATH_INFO} =~ m{^/}) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
47
|
1
|
|
|
|
|
8
|
my $ct = Plack::MIME->mime_type($env->{PATH_INFO}); |
|
48
|
1
|
|
|
|
|
21
|
return [200, ['Content-Type' => $ct, 'Content-Length' => length($content)], [$content]]; |
|
49
|
|
|
|
|
|
|
} elsif ($env->{PATH_INFO} =~ qr{^(?:/robots\.txt|/favicon\.ico)$}) { |
|
50
|
1
|
|
33
|
|
|
16
|
$app_file_1 ||= Plack::App::File->new({ root => $root1 }); |
|
51
|
1
|
|
|
|
|
21
|
return $app_file_1->call($env); |
|
52
|
|
|
|
|
|
|
} elsif ($env->{PATH_INFO} =~ m{^/static/}) { |
|
53
|
1
|
|
33
|
|
|
25
|
$app_file_2 ||= Plack::App::File->new({ root => $root2 }); |
|
54
|
1
|
|
|
|
|
99
|
return $app_file_2->call($env); |
|
55
|
|
|
|
|
|
|
} else { |
|
56
|
1
|
|
|
|
|
6
|
return $orig_app->($env); |
|
57
|
|
|
|
|
|
|
} |
|
58
|
1
|
|
|
|
|
10
|
}; |
|
59
|
|
|
|
|
|
|
} |
|
60
|
12
|
100
|
|
|
|
30
|
if (my @middlewares = @{"${caller}::_MIDDLEWARES"}) { |
|
|
12
|
|
|
|
|
114
|
|
|
61
|
2
|
|
|
|
|
5
|
for my $middleware (@middlewares) { |
|
62
|
2
|
|
|
|
|
6
|
my ($klass, $args) = @$middleware; |
|
63
|
2
|
|
|
|
|
13
|
$klass = Plack::Util::load_class($klass, 'Plack::Middleware'); |
|
64
|
2
|
|
|
|
|
3543
|
$app = $klass->wrap($app, %$args); |
|
65
|
|
|
|
|
|
|
} |
|
66
|
|
|
|
|
|
|
} |
|
67
|
12
|
100
|
|
|
|
1280
|
unless ($opts{no_x_content_type_options}) { |
|
68
|
|
|
|
|
|
|
$class->add_trigger(AFTER_DISPATCH => sub { |
|
69
|
27
|
|
|
27
|
|
311102
|
my ($c, $res) = @_; |
|
70
|
27
|
|
|
|
|
161
|
$res->header( 'X-Content-Type-Options' => 'nosniff' ); |
|
71
|
11
|
|
|
|
|
189
|
}); |
|
72
|
|
|
|
|
|
|
} |
|
73
|
12
|
100
|
|
|
|
271
|
unless ($opts{no_x_frame_options}) { |
|
74
|
|
|
|
|
|
|
$class->add_trigger(AFTER_DISPATCH => sub { |
|
75
|
27
|
|
|
27
|
|
1616
|
my ($c, $res) = @_; |
|
76
|
27
|
|
|
|
|
103
|
$res->header( 'X-Frame-Options' => 'DENY' ); |
|
77
|
11
|
|
|
|
|
76
|
}); |
|
78
|
|
|
|
|
|
|
} |
|
79
|
12
|
|
|
|
|
193
|
return $app; |
|
80
|
14
|
|
|
|
|
110
|
}; |
|
81
|
|
|
|
|
|
|
|
|
82
|
14
|
|
|
|
|
92
|
*{"${base_class}::enable_middleware"} = sub { |
|
83
|
2
|
|
|
2
|
|
98
|
my ($class, $klass, %args) = @_; |
|
84
|
2
|
|
|
|
|
4
|
push @{"${caller}::_MIDDLEWARES"}, [$klass, \%args]; |
|
|
2
|
|
|
|
|
17
|
|
|
85
|
14
|
|
|
|
|
54
|
}; |
|
86
|
14
|
|
|
|
|
109
|
*{"${base_class}::enable_session"} = sub { |
|
87
|
1
|
|
|
1
|
|
119
|
my ($class, %args) = @_; |
|
88
|
1
|
|
33
|
|
|
6
|
$args{state} ||= do { |
|
89
|
1
|
|
|
|
|
890
|
require Plack::Session::State::Cookie; |
|
90
|
1
|
|
|
|
|
5643
|
Plack::Session::State::Cookie->new(httponly => 1); # for security |
|
91
|
|
|
|
|
|
|
}; |
|
92
|
1
|
|
|
|
|
743
|
require Plack::Middleware::Session; |
|
93
|
1
|
|
|
|
|
2877
|
$class->enable_middleware('Plack::Middleware::Session', %args); |
|
94
|
|
|
|
|
|
|
$class->add_trigger(AFTER_DISPATCH => sub { |
|
95
|
2
|
|
|
2
|
|
1496
|
my ($c, $res) = @_; |
|
96
|
2
|
|
|
|
|
11
|
$res->header('Cache-Control' => 'private'); |
|
97
|
1
|
|
|
|
|
17
|
}); |
|
98
|
14
|
|
|
|
|
78
|
}; |
|
99
|
|
|
|
|
|
|
|
|
100
|
14
|
|
|
0
|
|
57
|
*{"$caller\::router"} = sub { $router }; |
|
|
14
|
|
|
|
|
82
|
|
|
|
0
|
|
|
|
|
0
|
|
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# any [qw/get post delete/] => '/bye' => sub { ... }; |
|
103
|
|
|
|
|
|
|
# any '/bye' => sub { ... }; |
|
104
|
14
|
|
|
|
|
69
|
*{"$caller\::any"} = sub ($$;$) { |
|
105
|
2
|
|
|
2
|
|
114
|
my $pkg = caller(0); |
|
106
|
2
|
100
|
|
|
|
6
|
if (@_==3) { |
|
107
|
1
|
|
|
|
|
4
|
my ($methods, $pattern, $code) = @_; |
|
108
|
1
|
|
|
|
|
6
|
$router->connect( |
|
109
|
|
|
|
|
|
|
$pattern, |
|
110
|
1
|
|
|
|
|
6
|
{code => $code, method => [ map { uc $_ } @$methods ]}, |
|
111
|
1
|
|
|
|
|
3
|
{method => [map { uc $_ } @$methods]}, |
|
112
|
|
|
|
|
|
|
); |
|
113
|
|
|
|
|
|
|
} else { |
|
114
|
1
|
|
|
|
|
2
|
my ($pattern, $code) = @_; |
|
115
|
1
|
|
|
|
|
5
|
$router->connect( |
|
116
|
|
|
|
|
|
|
$pattern, |
|
117
|
|
|
|
|
|
|
{code => $code}, |
|
118
|
|
|
|
|
|
|
); |
|
119
|
|
|
|
|
|
|
} |
|
120
|
14
|
|
|
|
|
74
|
}; |
|
121
|
|
|
|
|
|
|
|
|
122
|
14
|
|
|
|
|
64
|
*{"$caller\::get"} = sub { |
|
123
|
18
|
|
|
18
|
|
255772
|
$router->connect($_[0], {code => $_[1], method => ['GET', 'HEAD']}, {method => 'GET'}); |
|
124
|
14
|
|
|
|
|
42
|
}; |
|
125
|
|
|
|
|
|
|
|
|
126
|
14
|
|
|
|
|
75
|
*{"$caller\::post"} = sub { |
|
127
|
2
|
|
|
2
|
|
225
|
$router->connect($_[0], {code => $_[1], method => ['POST']}, {method => ['POST']}); |
|
128
|
14
|
|
|
|
|
45
|
}; |
|
129
|
|
|
|
|
|
|
|
|
130
|
14
|
|
|
|
|
83
|
*{"${base_class}\::dispatch"} = sub { |
|
131
|
28
|
|
|
28
|
|
388229
|
my ($c) = @_; |
|
132
|
28
|
100
|
|
|
|
186
|
if (my $p = $router->match($c->request->env)) { |
|
133
|
23
|
|
|
|
|
7785
|
return $p->{code}->( $c, $p ); |
|
134
|
|
|
|
|
|
|
} else { |
|
135
|
5
|
100
|
|
|
|
347
|
if ($router->method_not_allowed) { |
|
136
|
4
|
|
|
|
|
22
|
my $content = '405 Method Not Allowed'; |
|
137
|
4
|
|
|
|
|
25
|
return $c->create_response( |
|
138
|
|
|
|
|
|
|
405, |
|
139
|
|
|
|
|
|
|
[ |
|
140
|
|
|
|
|
|
|
'Content-Type' => 'text/plain; charset=utf-8', |
|
141
|
|
|
|
|
|
|
'Content-Length' => length($content), |
|
142
|
|
|
|
|
|
|
], |
|
143
|
|
|
|
|
|
|
[$content] |
|
144
|
|
|
|
|
|
|
); |
|
145
|
|
|
|
|
|
|
} else { |
|
146
|
1
|
|
|
|
|
13
|
return $c->res_404(); |
|
147
|
|
|
|
|
|
|
} |
|
148
|
|
|
|
|
|
|
} |
|
149
|
14
|
|
|
|
|
47
|
}; |
|
150
|
|
|
|
|
|
|
|
|
151
|
14
|
|
|
|
|
1076
|
my $tmpl_dir = File::Spec->catdir(dirname((caller(0))[1]), 'tmpl'); |
|
152
|
14
|
|
|
|
|
98
|
*{"${base_class}::create_view"} = sub { |
|
153
|
2
|
|
|
2
|
|
1055
|
$base_class->template_options(); |
|
154
|
14
|
|
|
|
|
63
|
}; |
|
155
|
14
|
|
|
|
|
82
|
*{"${base_class}::template_options"} = sub { |
|
156
|
4
|
|
|
4
|
|
86
|
my ($class, %options) = @_; |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# using lazy loading to read __DATA__ section. |
|
159
|
4
|
|
|
|
|
50
|
my $vpath = Data::Section::Simple->new($caller)->get_data_section(); |
|
160
|
|
|
|
|
|
|
my %params = ( |
|
161
|
|
|
|
|
|
|
'syntax' => 'TTerse', |
|
162
|
|
|
|
|
|
|
'module' => [ 'Text::Xslate::Bridge::TT2Like' ], |
|
163
|
|
|
|
|
|
|
'path' => [ $vpath, $tmpl_dir ], |
|
164
|
|
|
|
|
|
|
'function' => { |
|
165
|
0
|
|
|
0
|
|
0
|
c => sub { Amon2->context() }, |
|
166
|
0
|
|
|
0
|
|
0
|
uri_with => sub { Amon2->context()->req->uri_with(@_) }, |
|
167
|
0
|
|
|
0
|
|
0
|
uri_for => sub { Amon2->context()->uri_for(@_) }, |
|
168
|
|
|
|
|
|
|
}, |
|
169
|
4
|
|
|
|
|
585
|
); |
|
170
|
|
|
|
|
|
|
my $merge = sub { |
|
171
|
3
|
|
|
3
|
|
8
|
my ($stuff) = @_; |
|
172
|
3
|
|
|
|
|
8
|
for (qw(module path)) { |
|
173
|
6
|
100
|
|
|
|
25
|
if ($stuff->{$_}) { |
|
174
|
1
|
|
|
|
|
2
|
unshift @{$params{$_}}, @{delete $stuff->{$_}}; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
5
|
|
|
175
|
|
|
|
|
|
|
} |
|
176
|
|
|
|
|
|
|
} |
|
177
|
3
|
|
|
|
|
6
|
for (qw(function)) { |
|
178
|
3
|
100
|
|
|
|
14
|
if ($stuff->{$_}) { |
|
179
|
1
|
|
|
|
|
1
|
$params{$_} = +{ %{$params{$_}}, %{delete $stuff->{$_}} }; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
7
|
|
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
} |
|
182
|
3
|
|
|
|
|
18
|
while (my ($k, $v) = each %$stuff) { |
|
183
|
3
|
|
|
|
|
14
|
$params{$k} = $v; |
|
184
|
|
|
|
|
|
|
} |
|
185
|
4
|
|
|
|
|
24
|
}; |
|
186
|
4
|
100
|
|
|
|
43
|
if (my $config = $caller->config->{'Text::Xslate'}) { |
|
187
|
1
|
|
|
|
|
11
|
$merge->($config); |
|
188
|
|
|
|
|
|
|
} |
|
189
|
4
|
100
|
|
|
|
74
|
if (%options) { |
|
190
|
2
|
|
|
|
|
6
|
$merge->(\%options); |
|
191
|
|
|
|
|
|
|
} |
|
192
|
4
|
|
|
|
|
65
|
my $xslate = Text::Xslate->new(%params); |
|
193
|
13
|
|
|
13
|
|
104
|
no warnings 'redefine'; |
|
|
13
|
|
|
|
|
35
|
|
|
|
13
|
|
|
|
|
2963
|
|
|
194
|
4
|
|
|
3
|
|
11589
|
*{"${caller}::create_view"} = sub { $xslate }; |
|
|
4
|
|
|
|
|
25
|
|
|
|
3
|
|
|
|
|
568
|
|
|
195
|
4
|
|
|
|
|
87
|
$xslate; |
|
196
|
14
|
|
|
|
|
70
|
}; |
|
197
|
|
|
|
|
|
|
|
|
198
|
14
|
50
|
|
|
|
169
|
if (-d File::Spec->catdir($caller->base_dir, 'config')) { |
|
199
|
0
|
|
|
0
|
|
0
|
*{"${base_class}::load_config"} = sub { Amon2::Config::Simple->load(shift) }; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
200
|
|
|
|
|
|
|
} else { |
|
201
|
14
|
|
|
3
|
|
1424
|
*{"${base_class}::load_config"} = sub { +{ } }; |
|
|
14
|
|
|
|
|
27689
|
|
|
|
3
|
|
|
|
|
42
|
|
|
202
|
|
|
|
|
|
|
} |
|
203
|
|
|
|
|
|
|
} |
|
204
|
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
1; |
|
207
|
|
|
|
|
|
|
__END__ |