Filename | /usr/local/share/perl/5.18.2/Plack/Util.pm |
Statements | Executed 3900094 statements in 13.7s |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
100001 | 1 | 1 | 2.35s | 2.98s | header_iter | Plack::Util::
100001 | 1 | 1 | 2.09s | 11.8s | response_cb | Plack::Util::
100001 | 1 | 1 | 1.74s | 2.62s | headers | Plack::Util::
100001 | 1 | 1 | 1.46s | 12.7s | foreach | Plack::Util::
100001 | 1 | 1 | 1.40s | 3.04s | AUTOLOAD | Plack::Util::Prototype::
100001 | 1 | 1 | 1.12s | 950s | run_app | Plack::Util::
100001 | 1 | 1 | 1.02s | 9.72s | __ANON__[:313] | Plack::Util::
100001 | 1 | 1 | 889ms | 889ms | inline_object | Plack::Util::
100001 | 1 | 1 | 700ms | 700ms | content_length | Plack::Util::
100001 | 1 | 1 | 634ms | 1.24s | __ANON__[:159] | Plack::Util::
100001 | 1 | 1 | 610ms | 610ms | header_exists | Plack::Util::
100001 | 1 | 1 | 396ms | 396ms | CORE:subst (opcode) | Plack::Util::Prototype::
100001 | 1 | 1 | 341ms | 341ms | status_with_no_entity_body | Plack::Util::
5 | 3 | 2 | 4.23ms | 41.9ms | load_class | Plack::Util::
5 | 1 | 1 | 30µs | 30µs | CORE:regcomp (opcode) | Plack::Util::
10 | 2 | 1 | 23µs | 23µs | CORE:subst (opcode) | Plack::Util::
1 | 1 | 1 | 10µs | 25µs | BEGIN@5 | Plack::Util::
1 | 1 | 1 | 10µs | 36µs | BEGIN@368 | Plack::Util::IOWithPath::
1 | 1 | 1 | 9µs | 18µs | BEGIN@2 | Plack::Util::
1 | 1 | 1 | 7µs | 41µs | BEGIN@13 | Plack::Util::
1 | 1 | 1 | 7µs | 18µs | BEGIN@35 | Plack::Util::
1 | 1 | 1 | 6µs | 27µs | BEGIN@4 | Plack::Util::
1 | 1 | 1 | 4µs | 4µs | BEGIN@6 | Plack::Util::
5 | 1 | 1 | 3µs | 3µs | CORE:match (opcode) | Plack::Util::
1 | 1 | 1 | 2µs | 2µs | BEGIN@7 | Plack::Util::
1 | 1 | 1 | 2µs | 2µs | BEGIN@3 | Plack::Util::
0 | 0 | 0 | 0s | 0s | path | Plack::Util::IOWithPath::
0 | 0 | 0 | 0s | 0s | DESTROY | Plack::Util::Prototype::
0 | 0 | 0 | 0s | 0s | can | Plack::Util::Prototype::
0 | 0 | 0 | 0s | 0s | __ANON__[:155] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:156] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:157] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:158] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:160] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:161] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:304] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:306] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:307] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:329] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:334] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:339] | Plack::Util::
0 | 0 | 0 | 0s | 0s | __ANON__[:340] | Plack::Util::
0 | 0 | 0 | 0s | 0s | _load_sandbox | Plack::Util::
0 | 0 | 0 | 0s | 0s | class_to_file | Plack::Util::
0 | 0 | 0 | 0s | 0s | encode_html | Plack::Util::
0 | 0 | 0 | 0s | 0s | header_get | Plack::Util::
0 | 0 | 0 | 0s | 0s | header_push | Plack::Util::
0 | 0 | 0 | 0s | 0s | header_remove | Plack::Util::
0 | 0 | 0 | 0s | 0s | header_set | Plack::Util::
0 | 0 | 0 | 0s | 0s | is_real_fh | Plack::Util::
0 | 0 | 0 | 0s | 0s | load_psgi | Plack::Util::
0 | 0 | 0 | 0s | 0s | set_io_path | Plack::Util::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Plack::Util; | ||||
2 | 2 | 17µs | 2 | 26µs | # spent 18µs (9+8) within Plack::Util::BEGIN@2 which was called:
# once (9µs+8µs) by Plack::Runner::BEGIN@5 at line 2 # spent 18µs making 1 call to Plack::Util::BEGIN@2
# spent 8µs making 1 call to strict::import |
3 | 2 | 14µs | 1 | 2µs | # spent 2µs within Plack::Util::BEGIN@3 which was called:
# once (2µs+0s) by Plack::Runner::BEGIN@5 at line 3 # spent 2µs making 1 call to Plack::Util::BEGIN@3 |
4 | 2 | 21µs | 2 | 47µs | # spent 27µs (6+20) within Plack::Util::BEGIN@4 which was called:
# once (6µs+20µs) by Plack::Runner::BEGIN@5 at line 4 # spent 27µs making 1 call to Plack::Util::BEGIN@4
# spent 20µs making 1 call to Exporter::import |
5 | 2 | 22µs | 2 | 40µs | # spent 25µs (10+15) within Plack::Util::BEGIN@5 which was called:
# once (10µs+15µs) by Plack::Runner::BEGIN@5 at line 5 # spent 25µs making 1 call to Plack::Util::BEGIN@5
# spent 15µs making 1 call to Exporter::import |
6 | 2 | 14µs | 1 | 4µs | # spent 4µs within Plack::Util::BEGIN@6 which was called:
# once (4µs+0s) by Plack::Runner::BEGIN@5 at line 6 # spent 4µs making 1 call to Plack::Util::BEGIN@6 |
7 | 2 | 48µs | 1 | 2µs | # spent 2µs within Plack::Util::BEGIN@7 which was called:
# once (2µs+0s) by Plack::Runner::BEGIN@5 at line 7 # spent 2µs making 1 call to Plack::Util::BEGIN@7 |
8 | |||||
9 | sub TRUE() { 1==1 } | ||||
10 | sub FALSE() { !TRUE } | ||||
11 | |||||
12 | # there does not seem to be a relevant RT or perldelta entry for this | ||||
13 | 2 | 120µs | 2 | 74µs | # spent 41µs (7+34) within Plack::Util::BEGIN@13 which was called:
# once (7µs+34µs) by Plack::Runner::BEGIN@5 at line 13 # spent 41µs making 1 call to Plack::Util::BEGIN@13
# spent 34µs making 1 call to constant::import |
14 | |||||
15 | # spent 41.9ms (4.23+37.7) within Plack::Util::load_class which was called 5 times, avg 8.38ms/call:
# 3 times (3.57ms+13.1ms) by Plack::Runner::apply_middleware at line 192 of Plack/Runner.pm, avg 5.57ms/call
# once (142µs+24.4ms) by Plack::Loader::try {...} at line 41 of Plack/Loader.pm
# once (522µs+85µs) by Plack::Runner::loader at line 220 of Plack/Runner.pm | ||||
16 | 5 | 4µs | my($class, $prefix) = @_; | ||
17 | |||||
18 | 5 | 4µs | if ($prefix) { | ||
19 | 5 | 98µs | 15 | 38µs | unless ($class =~ s/^\+// || $class =~ /^$prefix/) { # spent 30µs making 5 calls to Plack::Util::CORE:regcomp, avg 6µs/call
# spent 4µs making 5 calls to Plack::Util::CORE:subst, avg 800ns/call
# spent 3µs making 5 calls to Plack::Util::CORE:match, avg 660ns/call |
20 | $class = "$prefix\::$class"; | ||||
21 | } | ||||
22 | } | ||||
23 | |||||
24 | 5 | 2µs | my $file = $class; | ||
25 | 5 | 29µs | 5 | 19µs | $file =~ s!::!/!g; # spent 19µs making 5 calls to Plack::Util::CORE:subst, avg 4µs/call |
26 | 5 | 1.81ms | require "$file.pm"; ## no critic | ||
27 | |||||
28 | 5 | 37µs | return $class; | ||
29 | } | ||||
30 | |||||
31 | sub is_real_fh ($) { | ||||
32 | my $fh = shift; | ||||
33 | |||||
34 | { | ||||
35 | 2 | 1.49ms | 2 | 30µs | # spent 18µs (7+11) within Plack::Util::BEGIN@35 which was called:
# once (7µs+11µs) by Plack::Runner::BEGIN@5 at line 35 # spent 18µs making 1 call to Plack::Util::BEGIN@35
# spent 11µs making 1 call to warnings::unimport |
36 | return FALSE if -p $fh or -c _ or -b _; | ||||
37 | } | ||||
38 | |||||
39 | my $reftype = Scalar::Util::reftype($fh) or return; | ||||
40 | if ( $reftype eq 'IO' | ||||
41 | or $reftype eq 'GLOB' && *{$fh}{IO} | ||||
42 | ) { | ||||
43 | # if it's a blessed glob make sure to not break encapsulation with | ||||
44 | # fileno($fh) (e.g. if you are filtering output then file descriptor | ||||
45 | # based operations might no longer be valid). | ||||
46 | # then ensure that the fileno *opcode* agrees too, that there is a | ||||
47 | # valid IO object inside $fh either directly or indirectly and that it | ||||
48 | # corresponds to a real file descriptor. | ||||
49 | my $m_fileno = $fh->fileno; | ||||
50 | return FALSE unless defined $m_fileno; | ||||
51 | return FALSE unless $m_fileno >= 0; | ||||
52 | |||||
53 | my $f_fileno = fileno($fh); | ||||
54 | return FALSE unless defined $f_fileno; | ||||
55 | return FALSE unless $f_fileno >= 0; | ||||
56 | return TRUE; | ||||
57 | } else { | ||||
58 | # anything else, including GLOBS without IO (even if they are blessed) | ||||
59 | # and non GLOB objects that look like filehandle objects cannot have a | ||||
60 | # valid file descriptor in fileno($fh) context so may break. | ||||
61 | return FALSE; | ||||
62 | } | ||||
63 | } | ||||
64 | |||||
65 | sub set_io_path { | ||||
66 | my($fh, $path) = @_; | ||||
67 | bless $fh, 'Plack::Util::IOWithPath'; | ||||
68 | $fh->path($path); | ||||
69 | } | ||||
70 | |||||
71 | # spent 700ms within Plack::Util::content_length which was called 100001 times, avg 7µs/call:
# 100001 times (700ms+0s) by Plack::Middleware::AccessLog::call at line 27 of Plack/Middleware/AccessLog.pm, avg 7µs/call | ||||
72 | 100001 | 52.5ms | my $body = shift; | ||
73 | |||||
74 | 100001 | 37.9ms | return unless defined $body; | ||
75 | |||||
76 | 100001 | 70.9ms | if (ref $body eq 'ARRAY') { | ||
77 | 100001 | 34.4ms | my $cl = 0; | ||
78 | 100001 | 125ms | for my $chunk (@$body) { | ||
79 | 100001 | 133ms | $cl += length $chunk; | ||
80 | } | ||||
81 | 100001 | 490ms | return $cl; | ||
82 | } elsif ( is_real_fh($body) ) { | ||||
83 | return (-s $body) - tell($body); | ||||
84 | } | ||||
85 | |||||
86 | return; | ||||
87 | } | ||||
88 | |||||
89 | # spent 12.7s (1.46+11.2) within Plack::Util::foreach which was called 100001 times, avg 127µs/call:
# 100001 times (1.46s+11.2s) by HTTP::Server::PSGI::_handle_response at line 225 of HTTP/Server/PSGI.pm, avg 127µs/call | ||||
90 | 100001 | 82.7ms | my($body, $cb) = @_; | ||
91 | |||||
92 | 100001 | 642ms | if (ref $body eq 'ARRAY') { | ||
93 | for my $line (@$body) { | ||||
94 | 100001 | 338ms | 100001 | 11.2s | $cb->($line) if length $line; # spent 11.2s making 100001 calls to HTTP::Server::PSGI::__ANON__[HTTP/Server/PSGI.pm:224], avg 112µs/call |
95 | } | ||||
96 | } else { | ||||
97 | local $/ = \65536 unless ref $/; | ||||
98 | while (defined(my $line = $body->getline)) { | ||||
99 | $cb->($line) if length $line; | ||||
100 | } | ||||
101 | $body->close; | ||||
102 | } | ||||
103 | } | ||||
104 | |||||
105 | sub class_to_file { | ||||
106 | my $class = shift; | ||||
107 | $class =~ s!::!/!g; | ||||
108 | $class . ".pm"; | ||||
109 | } | ||||
110 | |||||
111 | sub _load_sandbox { | ||||
112 | my $_file = shift; | ||||
113 | |||||
114 | my $_package = $_file; | ||||
115 | $_package =~ s/([^A-Za-z0-9_])/sprintf("_%2x", unpack("C", $1))/eg; | ||||
116 | |||||
117 | local $0 = $_file; # so FindBin etc. works | ||||
118 | local @ARGV = (); # Some frameworks might try to parse @ARGV | ||||
119 | |||||
120 | return eval sprintf <<'END_EVAL', $_package; | ||||
121 | package Plack::Sandbox::%s; | ||||
122 | { | ||||
123 | my $app = do $_file; | ||||
124 | if ( !$app && ( my $error = $@ || $! )) { die $error; } | ||||
125 | $app; | ||||
126 | } | ||||
127 | END_EVAL | ||||
128 | } | ||||
129 | |||||
130 | sub load_psgi { | ||||
131 | my $stuff = shift; | ||||
132 | |||||
133 | local $ENV{PLACK_ENV} = $ENV{PLACK_ENV} || 'development'; | ||||
134 | |||||
135 | my $file = $stuff =~ /^[a-zA-Z0-9\_\:]+$/ ? class_to_file($stuff) : File::Spec->rel2abs($stuff); | ||||
136 | my $app = _load_sandbox($file); | ||||
137 | die "Error while loading $file: $@" if $@; | ||||
138 | |||||
139 | return $app; | ||||
140 | } | ||||
141 | |||||
142 | # spent 950s (1.12+948) within Plack::Util::run_app which was called 100001 times, avg 9.50ms/call:
# 100001 times (1.12s+948s) by HTTP::Server::PSGI::handle_connection at line 170 of HTTP/Server/PSGI.pm, avg 9.50ms/call | ||||
143 | 100001 | 68.1ms | my($app, $env) = @_; | ||
144 | |||||
145 | 200002 | 912ms | 100001 | 948s | return eval { $app->($env) } || do { # spent 948s making 100001 calls to Plack::Component::__ANON__[Plack/Component.pm:50], avg 9.48ms/call |
146 | my $body = "Internal Server Error"; | ||||
147 | $env->{'psgi.errors'}->print($@); | ||||
148 | [ 500, [ 'Content-Type' => 'text/plain', 'Content-Length' => length($body) ], [ $body ] ]; | ||||
149 | }; | ||||
150 | } | ||||
151 | |||||
152 | # spent 2.62s (1.74+889ms) within Plack::Util::headers which was called 100001 times, avg 26µs/call:
# 100001 times (1.74s+889ms) by Plack::Middleware::ContentLength::__ANON__[/usr/local/share/perl/5.18.2/Plack/Middleware/ContentLength.pm:21] at line 14 of Plack/Middleware/ContentLength.pm, avg 26µs/call | ||||
153 | 100001 | 47.6ms | my $headers = shift; | ||
154 | inline_object( | ||||
155 | iter => sub { header_iter($headers, @_) }, | ||||
156 | get => sub { header_get($headers, @_) }, | ||||
157 | set => sub { header_set($headers, @_) }, | ||||
158 | push => sub { header_push($headers, @_) }, | ||||
159 | 100001 | 759ms | 100001 | 610ms | # spent 1.24s (634ms+610ms) within Plack::Util::__ANON__[/usr/local/share/perl/5.18.2/Plack/Util.pm:159] which was called 100001 times, avg 12µs/call:
# 100001 times (634ms+610ms) by Plack::Util::Prototype::AUTOLOAD at line 358, avg 12µs/call # spent 610ms making 100001 calls to Plack::Util::header_exists, avg 6µs/call |
160 | remove => sub { header_remove($headers, @_) }, | ||||
161 | headers => sub { $headers }, | ||||
162 | 100001 | 1.72s | 100001 | 889ms | ); # spent 889ms making 100001 calls to Plack::Util::inline_object, avg 9µs/call |
163 | } | ||||
164 | |||||
165 | # spent 2.98s (2.35+625ms) within Plack::Util::header_iter which was called 100001 times, avg 30µs/call:
# 100001 times (2.35s+625ms) by HTTP::Server::PSGI::_handle_response at line 205 of HTTP/Server/PSGI.pm, avg 30µs/call | ||||
166 | 100001 | 58.8ms | my($headers, $code) = @_; | ||
167 | |||||
168 | 100001 | 188ms | my @headers = @$headers; # copy | ||
169 | 100001 | 1.02s | 300003 | 625ms | while (my($key, $val) = splice @headers, 0, 2) { # spent 625ms making 300003 calls to HTTP::Server::PSGI::__ANON__[HTTP/Server/PSGI.pm:205], avg 2µs/call |
170 | $code->($key, $val); | ||||
171 | } | ||||
172 | } | ||||
173 | |||||
174 | sub header_get { | ||||
175 | my($headers, $key) = (shift, lc shift); | ||||
176 | |||||
177 | return () if not @$headers; | ||||
178 | |||||
179 | my $i = 0; | ||||
180 | |||||
181 | if (wantarray) { | ||||
182 | return map { | ||||
183 | $key eq lc $headers->[$i++] ? $headers->[$i++] : ++$i && (); | ||||
184 | } 1 .. @$headers/2; | ||||
185 | } | ||||
186 | |||||
187 | while ($i < @$headers) { | ||||
188 | return $headers->[$i+1] if $key eq lc $headers->[$i]; | ||||
189 | $i += 2; | ||||
190 | } | ||||
191 | |||||
192 | (); | ||||
193 | } | ||||
194 | |||||
195 | sub header_set { | ||||
196 | my($headers, $key, $val) = @_; | ||||
197 | |||||
198 | @$headers = ($key, $val), return if not @$headers; | ||||
199 | |||||
200 | my ($i, $_key) = (0, lc $key); | ||||
201 | |||||
202 | # locate and change existing header | ||||
203 | while ($i < @$headers) { | ||||
204 | $headers->[$i+1] = $val, last if $_key eq lc $headers->[$i]; | ||||
205 | $i += 2; | ||||
206 | } | ||||
207 | |||||
208 | if ($i > $#$headers) { # didn't find it? | ||||
209 | push @$headers, $key, $val; | ||||
210 | return; | ||||
211 | } | ||||
212 | |||||
213 | $i += 2; # found and changed it; so, first, skip that pair | ||||
214 | |||||
215 | return if $i > $#$headers; # anything left? | ||||
216 | |||||
217 | # yes... so do the same thing as header_remove | ||||
218 | # but for the tail of the array only, starting at $i | ||||
219 | |||||
220 | my $keep; | ||||
221 | my @keep = grep { | ||||
222 | $_ & 1 ? $keep : ($keep = $_key ne lc $headers->[$_]); | ||||
223 | } $i .. $#$headers; | ||||
224 | |||||
225 | my $remainder = @$headers - $i; | ||||
226 | return if @keep == $remainder; # if we're not changing anything... | ||||
227 | |||||
228 | splice @$headers, $i, $remainder, ( _SPLICE_SAME_ARRAY_SEGFAULT | ||||
229 | ? @{[ @$headers[@keep] ]} # force different source array | ||||
230 | : @$headers[@keep] | ||||
231 | ); | ||||
232 | (); | ||||
233 | } | ||||
234 | |||||
235 | sub header_push { | ||||
236 | my($headers, $key, $val) = @_; | ||||
237 | push @$headers, $key, $val; | ||||
238 | } | ||||
239 | |||||
240 | # spent 610ms within Plack::Util::header_exists which was called 100001 times, avg 6µs/call:
# 100001 times (610ms+0s) by Plack::Util::__ANON__[/usr/local/share/perl/5.18.2/Plack/Util.pm:159] at line 159, avg 6µs/call | ||||
241 | 100001 | 111ms | my($headers, $key) = (shift, lc shift); | ||
242 | |||||
243 | 100001 | 24.9ms | my $check; | ||
244 | 100001 | 122ms | for (@$headers) { | ||
245 | 100001 | 662ms | return 1 if ($check = not $check) and $key eq lc; | ||
246 | } | ||||
247 | |||||
248 | return !1; | ||||
249 | } | ||||
250 | |||||
251 | sub header_remove { | ||||
252 | my($headers, $key) = (shift, lc shift); | ||||
253 | |||||
254 | return if not @$headers; | ||||
255 | |||||
256 | my $keep; | ||||
257 | my @keep = grep { | ||||
258 | $_ & 1 ? $keep : ($keep = $key ne lc $headers->[$_]); | ||||
259 | } 0 .. $#$headers; | ||||
260 | |||||
261 | @$headers = @$headers[@keep] if @keep < @$headers; | ||||
262 | (); | ||||
263 | } | ||||
264 | |||||
265 | # spent 341ms within Plack::Util::status_with_no_entity_body which was called 100001 times, avg 3µs/call:
# 100001 times (341ms+0s) by Plack::Middleware::ContentLength::__ANON__[/usr/local/share/perl/5.18.2/Plack/Middleware/ContentLength.pm:21] at line 15 of Plack/Middleware/ContentLength.pm, avg 3µs/call | ||||
266 | 100001 | 66.8ms | my $status = shift; | ||
267 | 100001 | 499ms | return $status < 200 || $status == 204 || $status == 304; | ||
268 | } | ||||
269 | |||||
270 | sub encode_html { | ||||
271 | my $str = shift; | ||||
272 | $str =~ s/&/&/g; | ||||
273 | $str =~ s/>/>/g; | ||||
274 | $str =~ s/</</g; | ||||
275 | $str =~ s/"/"/g; | ||||
276 | $str =~ s/'/'/g; | ||||
277 | return $str; | ||||
278 | } | ||||
279 | |||||
280 | # spent 889ms within Plack::Util::inline_object which was called 100001 times, avg 9µs/call:
# 100001 times (889ms+0s) by Plack::Util::headers at line 162, avg 9µs/call | ||||
281 | 100001 | 475ms | my %args = @_; | ||
282 | 100001 | 612ms | bless \%args, 'Plack::Util::Prototype'; | ||
283 | } | ||||
284 | |||||
285 | # spent 11.8s (2.09+9.72) within Plack::Util::response_cb which was called 100001 times, avg 118µs/call:
# 100001 times (2.09s+9.72s) by Plack::Component::response_cb at line 56 of Plack/Component.pm, avg 118µs/call | ||||
286 | 100001 | 44.5ms | my($res, $cb) = @_; | ||
287 | |||||
288 | # spent 9.72s (1.02+8.70) within Plack::Util::__ANON__[/usr/local/share/perl/5.18.2/Plack/Util.pm:313] which was called 100001 times, avg 97µs/call:
# 100001 times (1.02s+8.70s) by Plack::Util::response_cb at line 316, avg 97µs/call | ||||
289 | 100001 | 50.1ms | my($cb, $res) = @_; | ||
290 | 100001 | 194ms | 100001 | 8.70s | my $filter_cb = $cb->($res); # spent 8.70s making 100001 calls to Plack::Middleware::ContentLength::__ANON__[Plack/Middleware/ContentLength.pm:21], avg 87µs/call |
291 | # If response_cb returns a callback, treat it as a $body filter | ||||
292 | 100001 | 541ms | if (defined $filter_cb && ref $filter_cb eq 'CODE') { | ||
293 | Plack::Util::header_remove($res->[1], 'Content-Length'); | ||||
294 | if (defined $res->[2]) { | ||||
295 | if (ref $res->[2] eq 'ARRAY') { | ||||
296 | for my $line (@{$res->[2]}) { | ||||
297 | $line = $filter_cb->($line); | ||||
298 | } | ||||
299 | # Send EOF. | ||||
300 | my $eof = $filter_cb->( undef ); | ||||
301 | push @{ $res->[2] }, $eof if defined $eof; | ||||
302 | } else { | ||||
303 | my $body = $res->[2]; | ||||
304 | my $getline = sub { $body->getline }; | ||||
305 | $res->[2] = Plack::Util::inline_object | ||||
306 | getline => sub { $filter_cb->($getline->()) }, | ||||
307 | close => sub { $body->close }; | ||||
308 | } | ||||
309 | } else { | ||||
310 | return $filter_cb; | ||||
311 | } | ||||
312 | } | ||||
313 | 100001 | 458ms | }; | ||
314 | |||||
315 | 100001 | 118ms | if (ref $res eq 'ARRAY') { | ||
316 | 100001 | 163ms | 100001 | 9.72s | $body_filter->($cb, $res); # spent 9.72s making 100001 calls to Plack::Util::__ANON__[Plack/Util.pm:313], avg 97µs/call |
317 | 100001 | 1.17s | return $res; | ||
318 | } elsif (ref $res eq 'CODE') { | ||||
319 | return sub { | ||||
320 | my $respond = shift; | ||||
321 | my $cb = $cb; # To avoid the nested closure leak for 5.8.x | ||||
322 | $res->(sub { | ||||
323 | my $res = shift; | ||||
324 | my $filter_cb = $body_filter->($cb, $res); | ||||
325 | if ($filter_cb) { | ||||
326 | my $writer = $respond->($res); | ||||
327 | if ($writer) { | ||||
328 | return Plack::Util::inline_object | ||||
329 | write => sub { $writer->write($filter_cb->(@_)) }, | ||||
330 | close => sub { | ||||
331 | my $chunk = $filter_cb->(undef); | ||||
332 | $writer->write($chunk) if defined $chunk; | ||||
333 | $writer->close; | ||||
334 | }; | ||||
335 | } | ||||
336 | } else { | ||||
337 | return $respond->($res); | ||||
338 | } | ||||
339 | }); | ||||
340 | }; | ||||
341 | } | ||||
342 | |||||
343 | return $res; | ||||
344 | } | ||||
345 | |||||
346 | package Plack::Util::Prototype; | ||||
347 | |||||
348 | 1 | 100ns | our $AUTOLOAD; | ||
349 | sub can { | ||||
350 | return $_[0]->{$_[1]} if Scalar::Util::blessed($_[0]); | ||||
351 | goto &UNIVERSAL::can; | ||||
352 | } | ||||
353 | |||||
354 | # spent 3.04s (1.40+1.64) within Plack::Util::Prototype::AUTOLOAD which was called 100001 times, avg 30µs/call:
# 100001 times (1.40s+1.64s) by Plack::Middleware::ContentLength::__ANON__[/usr/local/share/perl/5.18.2/Plack/Middleware/ContentLength.pm:21] at line 15 of Plack/Middleware/ContentLength.pm, avg 30µs/call | ||||
355 | 100001 | 50.1ms | my $self = shift; | ||
356 | 100001 | 41.1ms | my $attr = $AUTOLOAD; | ||
357 | 100001 | 810ms | 100001 | 396ms | $attr =~ s/.*://; # spent 396ms making 100001 calls to Plack::Util::Prototype::CORE:subst, avg 4µs/call |
358 | 100001 | 711ms | 100001 | 1.24s | if (ref($self->{$attr}) eq 'CODE') { # spent 1.24s making 100001 calls to Plack::Util::__ANON__[Plack/Util.pm:159], avg 12µs/call |
359 | $self->{$attr}->(@_); | ||||
360 | } else { | ||||
361 | Carp::croak(qq/Can't locate object method "$attr" via package "Plack::Util::Prototype"/); | ||||
362 | } | ||||
363 | } | ||||
364 | |||||
365 | sub DESTROY { } | ||||
366 | |||||
367 | package Plack::Util::IOWithPath; | ||||
368 | 2 | 68µs | 2 | 62µs | # spent 36µs (10+26) within Plack::Util::IOWithPath::BEGIN@368 which was called:
# once (10µs+26µs) by Plack::Runner::BEGIN@5 at line 368 # spent 36µs making 1 call to Plack::Util::IOWithPath::BEGIN@368
# spent 26µs making 1 call to parent::import |
369 | |||||
370 | sub path { | ||||
371 | my $self = shift; | ||||
372 | if (@_) { | ||||
373 | ${*$self}{+__PACKAGE__} = shift; | ||||
374 | } | ||||
375 | ${*$self}{+__PACKAGE__}; | ||||
376 | } | ||||
377 | |||||
378 | package Plack::Util; | ||||
379 | |||||
380 | 1 | 2µs | 1; | ||
381 | |||||
382 | __END__ | ||||
# spent 3µs within Plack::Util::CORE:match which was called 5 times, avg 660ns/call:
# 5 times (3µs+0s) by Plack::Util::load_class at line 19, avg 660ns/call | |||||
# spent 30µs within Plack::Util::CORE:regcomp which was called 5 times, avg 6µs/call:
# 5 times (30µs+0s) by Plack::Util::load_class at line 19, avg 6µs/call | |||||
sub Plack::Util::CORE:subst; # opcode | |||||
# spent 396ms within Plack::Util::Prototype::CORE:subst which was called 100001 times, avg 4µs/call:
# 100001 times (396ms+0s) by Plack::Util::Prototype::AUTOLOAD at line 357, avg 4µs/call |