Filename | /usr/local/src/github.com/foswiki/core/lib/Foswiki/Engine.pm |
Statements | Executed 51 statements in 3.02ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 2.70ms | 4.70ms | prepareCookies | Foswiki::Engine::
1 | 1 | 1 | 98µs | 6.10ms | __ANON__[:102] | Foswiki::Engine::
1 | 1 | 1 | 98µs | 6.28ms | prepare | Foswiki::Engine::
1 | 1 | 1 | 73µs | 2.00ms | finalize | Foswiki::Engine::
1 | 1 | 1 | 73µs | 755µs | finalizeCookies | Foswiki::Engine::
1 | 1 | 1 | 60µs | 180µs | finalizeBody | Foswiki::Engine::
1 | 1 | 1 | 51µs | 820µs | finalizeHeaders | Foswiki::Engine::
1 | 1 | 1 | 24µs | 31µs | BEGIN@17 | Foswiki::Engine::
1 | 1 | 1 | 21µs | 69µs | BEGIN@20 | Foswiki::Engine::
1 | 1 | 1 | 20µs | 20µs | new | Foswiki::Engine::
1 | 1 | 1 | 19µs | 415µs | BEGIN@19 | Foswiki::Engine::
1 | 1 | 1 | 17µs | 34µs | BEGIN@18 | Foswiki::Engine::
1 | 1 | 1 | 9µs | 9µs | BEGIN@21 | Foswiki::Engine::
1 | 1 | 1 | 4µs | 4µs | prepareWrite | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | __ANON__[:117] | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | __ANON__[:144] | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | finalizeError | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | finalizeUploads | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | flush | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | prepareBody | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | prepareBodyParameters | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | prepareConnection | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | prepareHeaders | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | preparePath | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | prepareQueryParameters | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | prepareUploads | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | run | Foswiki::Engine::
0 | 0 | 0 | 0s | 0s | write | Foswiki::Engine::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # See bottom of file for license and copyright information | ||||
2 | |||||
3 | =begin TML | ||||
4 | |||||
5 | ---+!! package Foswiki::Engine | ||||
6 | |||||
7 | The engine class is a singleton that implements details about Foswiki's | ||||
8 | execution mode. This is the base class and implements basic behavior. | ||||
9 | |||||
10 | Each engine should inherits from this and overload methods necessary | ||||
11 | to achieve correct behavior. | ||||
12 | |||||
13 | =cut | ||||
14 | |||||
15 | package Foswiki::Engine; | ||||
16 | |||||
17 | 2 | 45µs | 2 | 38µs | # spent 31µs (24+7) within Foswiki::Engine::BEGIN@17 which was called:
# once (24µs+7µs) by Foswiki::Engine::CGI::BEGIN@18 at line 17 # spent 31µs making 1 call to Foswiki::Engine::BEGIN@17
# spent 7µs making 1 call to strict::import |
18 | 2 | 47µs | 2 | 51µs | # spent 34µs (17+17) within Foswiki::Engine::BEGIN@18 which was called:
# once (17µs+17µs) by Foswiki::Engine::CGI::BEGIN@18 at line 18 # spent 34µs making 1 call to Foswiki::Engine::BEGIN@18
# spent 17µs making 1 call to warnings::import |
19 | 2 | 50µs | 2 | 811µs | # spent 415µs (19+396) within Foswiki::Engine::BEGIN@19 which was called:
# once (19µs+396µs) by Foswiki::Engine::CGI::BEGIN@18 at line 19 # spent 415µs making 1 call to Foswiki::Engine::BEGIN@19
# spent 396µs making 1 call to Error::import |
20 | 2 | 48µs | 2 | 117µs | # spent 69µs (21+48) within Foswiki::Engine::BEGIN@20 which was called:
# once (21µs+48µs) by Foswiki::Engine::CGI::BEGIN@18 at line 20 # spent 69µs making 1 call to Foswiki::Engine::BEGIN@20
# spent 48µs making 1 call to Assert::import |
21 | 2 | 2.20ms | 1 | 9µs | # spent 9µs within Foswiki::Engine::BEGIN@21 which was called:
# once (9µs+0s) by Foswiki::Engine::CGI::BEGIN@18 at line 21 # spent 9µs making 1 call to Foswiki::Engine::BEGIN@21 |
22 | |||||
23 | =begin TML | ||||
24 | |||||
25 | ---++ ClassMethod new() -> $engine | ||||
26 | |||||
27 | Constructs an engine object. | ||||
28 | |||||
29 | =cut | ||||
30 | |||||
31 | # spent 20µs within Foswiki::Engine::new which was called:
# once (20µs+0s) by Foswiki::BEGIN@134 at line 1 of (eval 33)[/usr/local/src/github.com/foswiki/core/lib/Foswiki.pm:597] | ||||
32 | 4 | 23µs | my $proto = shift; | ||
33 | my $class = ref($proto) || $proto; | ||||
34 | my $this = {}; | ||||
35 | return bless $this, $class; | ||||
36 | } | ||||
37 | |||||
38 | =begin TML | ||||
39 | |||||
40 | ---++ ObjectMethod run() | ||||
41 | |||||
42 | Start point to Runtime Engines. | ||||
43 | |||||
44 | =cut | ||||
45 | |||||
46 | sub run { | ||||
47 | my $this = shift; | ||||
48 | my $req = $this->prepare(); | ||||
49 | if ( defined $req ) { | ||||
50 | my $res = Foswiki::UI::handleRequest($req); | ||||
51 | $this->finalize( $res, $req ); | ||||
52 | } | ||||
53 | } | ||||
54 | |||||
55 | =begin TML | ||||
56 | |||||
57 | ---++ ObjectMethod prepare() -> $req | ||||
58 | |||||
59 | Initialize a Foswiki::Request object by calling many preparation methods | ||||
60 | and returns it, or a status code in case of error. | ||||
61 | |||||
62 | =cut | ||||
63 | |||||
64 | # spent 6.28ms (98µs+6.19) within Foswiki::Engine::prepare which was called:
# once (98µs+6.19ms) by Foswiki::Engine::CGI::run at line 39 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Engine/CGI.pm | ||||
65 | 5 | 88µs | my $this = shift; | ||
66 | my $req; | ||||
67 | |||||
68 | if ( $Foswiki::cfg{RCS}{overrideUmask} && $Foswiki::cfg{OS} ne 'WINDOWS' ) { | ||||
69 | |||||
70 | # Note: The addition of zero is required to force dirPermission and filePermission | ||||
71 | # to be numeric. Without the additition, certain values of the permissions cause | ||||
72 | # runtime errors about illegal characters in subtraction. "and" with 777 to prevent | ||||
73 | # sticky-bits from breaking the umask. | ||||
74 | my $oldUmask = umask( | ||||
75 | ( | ||||
76 | oct(777) - ( | ||||
77 | ( | ||||
78 | $Foswiki::cfg{RCS}{dirPermission} + 0 | | ||||
79 | $Foswiki::cfg{RCS}{filePermission} + 0 | ||||
80 | ) | ||||
81 | ) & oct(777) | ||||
82 | ) | ||||
83 | ); | ||||
84 | |||||
85 | #my $umask = sprintf('%04o', umask() ); | ||||
86 | #$oldUmask = sprintf('%04o', $oldUmask ); | ||||
87 | #my $dirPerm = sprintf('%04o', $Foswiki::cfg{RCS}{dirPermission}+0 ); | ||||
88 | #my $filePerm = sprintf('%04o', $Foswiki::cfg{RCS}{filePermission}+0 ); | ||||
89 | #print STDERR " ENGINE changes $oldUmask to $umask from $dirPerm and $filePerm \n"; | ||||
90 | } | ||||
91 | |||||
92 | # spent 6.10ms (98µs+6.01) within Foswiki::Engine::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Engine.pm:102] which was called:
# once (98µs+6.01ms) by Error::subs::try at line 416 of Error.pm | ||||
93 | 9 | 69µs | 1 | 42µs | $req = Foswiki::Request->new(); # spent 42µs making 1 call to Foswiki::Request::new |
94 | 1 | 122µs | $this->prepareConnection($req); # spent 122µs making 1 call to Foswiki::Engine::CGI::prepareConnection | ||
95 | 1 | 8µs | $this->prepareQueryParameters($req); # spent 8µs making 1 call to Foswiki::Engine::CGI::prepareQueryParameters | ||
96 | 1 | 919µs | $this->prepareHeaders($req); # spent 919µs making 1 call to Foswiki::Engine::CGI::prepareHeaders | ||
97 | 1 | 4.70ms | $this->prepareCookies($req); # spent 4.70ms making 1 call to Foswiki::Engine::prepareCookies | ||
98 | 1 | 195µs | $this->preparePath($req); # spent 195µs making 1 call to Foswiki::Engine::CGI::preparePath | ||
99 | 1 | 8µs | $this->prepareBody($req); # spent 8µs making 1 call to Foswiki::Engine::CGI::prepareBody | ||
100 | 1 | 7µs | $this->prepareBodyParameters($req); # spent 7µs making 1 call to Foswiki::Engine::CGI::prepareBodyParameters | ||
101 | 1 | 7µs | $this->prepareUploads($req); # spent 7µs making 1 call to Foswiki::Engine::CGI::prepareUploads | ||
102 | } | ||||
103 | catch Foswiki::EngineException with { | ||||
104 | my $e = shift; | ||||
105 | my $res = $e->{response}; | ||||
106 | unless ( defined $res ) { | ||||
107 | $res = new Foswiki::Response(); | ||||
108 | $res->header( -type => 'text/html', -status => $e->{status} ); | ||||
109 | my $html = CGI::start_html( $e->{status} . ' Bad Request' ); | ||||
110 | $html .= CGI::h1( {}, 'Bad Request' ); | ||||
111 | $html .= CGI::p( {}, $e->{reason} ); | ||||
112 | $html .= CGI::end_html(); | ||||
113 | $res->print($html); | ||||
114 | } | ||||
115 | $this->finalizeError( $res, $req ); | ||||
116 | return $e->{status}; | ||||
117 | } | ||||
118 | otherwise { | ||||
119 | my $e = shift; | ||||
120 | my $res = Foswiki::Response->new(); | ||||
121 | $res->header( -type => 'text/plain' ); | ||||
122 | if (DEBUG) { | ||||
123 | |||||
124 | # output the full message and stacktrace to the browser | ||||
125 | $res->print( $e->stringify() ); | ||||
126 | } | ||||
127 | else { | ||||
128 | my $mess = $e->stringify(); | ||||
129 | print STDERR $mess; | ||||
130 | |||||
131 | # tell the browser where to look for more help | ||||
132 | my $text = | ||||
133 | 'Foswiki detected an internal error - please check your Foswiki logs and webserver logs for more information.' | ||||
134 | . "\n\n"; | ||||
135 | $mess =~ s/ at .*$//s; | ||||
136 | |||||
137 | # cut out pathnames from public announcement | ||||
138 | $mess =~ s#/[\w./]+#path#g; | ||||
139 | $text .= $mess; | ||||
140 | $res->print($text); | ||||
141 | } | ||||
142 | $this->finalizeError( $res, $req ); | ||||
143 | return 500; # Internal server error | ||||
144 | 4 | 6.19ms | }; # spent 6.15ms making 1 call to Error::subs::try
# spent 14µs making 1 call to Error::catch
# spent 14µs making 1 call to Error::subs::otherwise
# spent 5µs making 1 call to Error::subs::with | ||
145 | return $req; | ||||
146 | } | ||||
147 | |||||
148 | =begin TML | ||||
149 | |||||
150 | ---++ ObjectMethod prepareConnection( $req ) | ||||
151 | |||||
152 | Abstract method, must be defined by inherited classes. | ||||
153 | * =$req= - Foswiki::Request object to populate | ||||
154 | |||||
155 | Should fill remoteAddr, method and secure fields of =$req= object. | ||||
156 | |||||
157 | =cut | ||||
158 | |||||
159 | sub prepareConnection { } | ||||
160 | |||||
161 | =begin TML | ||||
162 | |||||
163 | ---++ ObjectMethod prepareQueryParameters( $req, $queryString ) | ||||
164 | |||||
165 | Should fill $req's query parameters field. | ||||
166 | |||||
167 | This method populates $req as it should if given $queryString parameter. | ||||
168 | Subclasses may redefine this method and call SUPER with query string obtained. | ||||
169 | |||||
170 | =cut | ||||
171 | |||||
172 | sub prepareQueryParameters { | ||||
173 | my ( $this, $req, $queryString ) = @_; | ||||
174 | my @pairs = split /[&;]/, $queryString; | ||||
175 | my ( $param, $value, %params, @plist ); | ||||
176 | foreach my $pair (@pairs) { | ||||
177 | ( $param, $value ) = split( '=', $pair, 2 ); | ||||
178 | |||||
179 | # url decode | ||||
180 | if ( defined $value ) { | ||||
181 | $value =~ tr/+/ /; | ||||
182 | $value =~ s/%([0-9A-F]{2})/chr(hex($1))/gei; | ||||
183 | } | ||||
184 | if ( defined $param ) { | ||||
185 | $param =~ tr/+/ /; | ||||
186 | $param =~ s/%([0-9A-F]{2})/chr(hex($1))/gei; | ||||
187 | push @{ $params{$param} }, $value; | ||||
188 | push @plist, $param; | ||||
189 | } | ||||
190 | } | ||||
191 | foreach my $param (@plist) { | ||||
192 | $req->queryParam( $param, $params{$param} ); | ||||
193 | } | ||||
194 | } | ||||
195 | |||||
196 | =begin TML | ||||
197 | |||||
198 | ---++ ObjectMethod prepareHeaders( $req ) | ||||
199 | |||||
200 | Abstract method, must be defined by inherited classes. | ||||
201 | * =$req= - Foswiki::Request object to populate | ||||
202 | |||||
203 | Should fill $req's headers and remoteUser fields. | ||||
204 | |||||
205 | =cut | ||||
206 | |||||
207 | sub prepareHeaders { } | ||||
208 | |||||
209 | =begin TML | ||||
210 | |||||
211 | ---++ ObjectMethod preparePath( $req ) | ||||
212 | |||||
213 | Abstract method, must be defined by inherited classes. | ||||
214 | * =$req= - Foswiki::Request object to populate | ||||
215 | |||||
216 | Should fill $req's uri and pathInfo fields. | ||||
217 | |||||
218 | =cut | ||||
219 | |||||
220 | sub preparePath { } | ||||
221 | |||||
222 | =begin TML | ||||
223 | |||||
224 | ---++ ObjectMethod prepareCookies( $req ) | ||||
225 | |||||
226 | * =$req= - Foswiki::Request object to populate | ||||
227 | |||||
228 | Should fill $req's cookie field. This method take cookie data from | ||||
229 | previously populated headers field and initializes from it. Maybe | ||||
230 | doesn't need to overload in children classes. | ||||
231 | |||||
232 | =cut | ||||
233 | |||||
234 | # spent 4.70ms (2.70+2.00) within Foswiki::Engine::prepareCookies which was called:
# once (2.70ms+2.00ms) by Foswiki::Engine::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Engine.pm:102] at line 97 | ||||
235 | 4 | 37µs | my ( $this, $req ) = @_; | ||
236 | 1 | 152µs | eval { require CGI::Cookie }; | ||
237 | throw Error::Simple($@) if $@; | ||||
238 | 4 | 1.61ms | $req->cookies( scalar CGI::Cookie->parse( $req->header('Cookie') ) ) # spent 1.49ms making 1 call to CGI::Cookie::parse
# spent 116µs making 2 calls to Foswiki::Request::header, avg 58µs/call
# spent 7µs making 1 call to Foswiki::Request::cookies | ||
239 | if $req->header('Cookie'); | ||||
240 | } | ||||
241 | |||||
242 | =begin TML | ||||
243 | |||||
244 | ---++ ObjectMethod prepareBody( $req ) | ||||
245 | |||||
246 | Abstract method, must be defined by inherited classes. | ||||
247 | * =$req= - Foswiki::Request object to populate | ||||
248 | |||||
249 | Should perform any initialization tasks related to body processing. | ||||
250 | |||||
251 | =cut | ||||
252 | |||||
253 | sub prepareBody { } | ||||
254 | |||||
255 | =begin TML | ||||
256 | |||||
257 | ---++ ObjectMethod prepareBodyParameters( $req ) | ||||
258 | |||||
259 | Abstract method, must be defined by inherited classes. | ||||
260 | * =$req= - Foswiki::Request object to populate | ||||
261 | |||||
262 | Should fill $req's body parameters. | ||||
263 | |||||
264 | =cut | ||||
265 | |||||
266 | sub prepareBodyParameters { } | ||||
267 | |||||
268 | =begin TML | ||||
269 | |||||
270 | ---++ ObjectMethod prepareUploads( $req ) | ||||
271 | |||||
272 | Abstract method, must be defined by inherited classes. | ||||
273 | * =$req= - Foswiki::Request object to populate | ||||
274 | |||||
275 | Should fill $req's uploads field. Its a hashref whose keys are | ||||
276 | parameter names and values Foswiki::Request::Upload objects. | ||||
277 | |||||
278 | =cut | ||||
279 | |||||
280 | sub prepareUploads { } | ||||
281 | |||||
282 | =begin TML | ||||
283 | |||||
284 | ---++ ObjectMethod finalize($res, $req) | ||||
285 | |||||
286 | Finalizes the request by calling many methods to send response to client and | ||||
287 | take any appropriate finalize actions, such as delete temporary files. | ||||
288 | * =$res= is the Foswiki::Response object | ||||
289 | * =$req= it the Foswiki::Request object. | ||||
290 | |||||
291 | =cut | ||||
292 | |||||
293 | # spent 2.00ms (73µs+1.93) within Foswiki::Engine::finalize which was called:
# once (73µs+1.93ms) by Foswiki::Engine::CGI::run at line 42 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Engine/CGI.pm | ||||
294 | 2 | 23µs | my ( $this, $res, $req ) = @_; | ||
295 | 3 | 32µs | 1 | 10µs | if ( $res->outputHasStarted() ) { # spent 10µs making 1 call to Foswiki::Response::outputHasStarted |
296 | $this->flush( $res, $req ); | ||||
297 | } | ||||
298 | else { | ||||
299 | 1 | 42µs | $this->finalizeUploads( $res, $req ); # spent 42µs making 1 call to Foswiki::Engine::CGI::finalizeUploads | ||
300 | 1 | 1.70ms | $this->finalizeHeaders( $res, $req ); # spent 1.70ms making 1 call to Foswiki::Engine::CGI::finalizeHeaders | ||
301 | 1 | 180µs | $this->finalizeBody($res); # spent 180µs making 1 call to Foswiki::Engine::finalizeBody | ||
302 | } | ||||
303 | } | ||||
304 | |||||
305 | =begin TML | ||||
306 | |||||
307 | ---++ ObjectMethod finalizeUploads( $res, $req ) | ||||
308 | |||||
309 | Abstract method, must be defined by inherited classes. | ||||
310 | * =$res= - Foswiki::Response object to get data from | ||||
311 | * =$req= - Foswiki::Request object to get data from | ||||
312 | |||||
313 | Should delete any temp files created in preparation phase. | ||||
314 | |||||
315 | =cut | ||||
316 | |||||
317 | sub finalizeUploads { } | ||||
318 | |||||
319 | =begin TML | ||||
320 | |||||
321 | ---++ ObjectMethod finalizeError( $res, $req ) | ||||
322 | |||||
323 | Called if some engine especific error happens. | ||||
324 | |||||
325 | * =$res= - Foswiki::Response object to get data from | ||||
326 | * =$req= - Foswiki::Request object to get data from | ||||
327 | |||||
328 | =cut | ||||
329 | |||||
330 | sub finalizeError { | ||||
331 | my ( $this, $res, $req ) = @_; | ||||
332 | $this->finalizeHeaders( $res, $req ); | ||||
333 | $this->finalizeBody( $res, $req ); | ||||
334 | } | ||||
335 | |||||
336 | =begin TML | ||||
337 | |||||
338 | ---++ ObjectMethod finalizeHeaders( $res, $req ) | ||||
339 | |||||
340 | Base method, must be redefined by inherited classes. For convenience | ||||
341 | this method deals with HEAD requests related stuff. Children classes | ||||
342 | should call SUPER. | ||||
343 | * =$res= - Foswiki::Response object to get data from | ||||
344 | * =$req= - Foswiki::Request object to get data from | ||||
345 | |||||
346 | Should call finalizeCookies and then send $res' headers to client. | ||||
347 | |||||
348 | =cut | ||||
349 | |||||
350 | # spent 820µs (51+769) within Foswiki::Engine::finalizeHeaders which was called:
# once (51µs+769µs) by Foswiki::Engine::CGI::finalizeHeaders at line 193 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Engine/CGI.pm | ||||
351 | 3 | 40µs | my ( $this, $res, $req ) = @_; | ||
352 | 1 | 755µs | $this->finalizeCookies($res); # spent 755µs making 1 call to Foswiki::Engine::finalizeCookies | ||
353 | 2 | 14µs | if ( $req && $req->method() && uc( $req->method() ) eq 'HEAD' ) { # spent 14µs making 2 calls to Foswiki::Request::method, avg 7µs/call | ||
354 | $res->body(''); | ||||
355 | $res->deleteHeader('Content-Length'); | ||||
356 | } | ||||
357 | } | ||||
358 | |||||
359 | =begin TML | ||||
360 | |||||
361 | ---++ ObjectMethod finalizeCookies( $res ) | ||||
362 | |||||
363 | * =$res= - Foswiki::Response object to both get data from and populate | ||||
364 | |||||
365 | Should populate $res' headers field with cookies, if any. | ||||
366 | |||||
367 | =cut | ||||
368 | |||||
369 | # spent 755µs (73+682) within Foswiki::Engine::finalizeCookies which was called:
# once (73µs+682µs) by Foswiki::Engine::finalizeHeaders at line 352 | ||||
370 | 2 | 85µs | my ( $this, $res ) = @_; | ||
371 | |||||
372 | # SMELL: Review comment below, from CGI: | ||||
373 | # if the user indicates an expiration time, then we need | ||||
374 | # both an Expires and a Date header (so that the browser is | ||||
375 | # uses OUR clock) | ||||
376 | $res->pushHeader( 'Set-Cookie', | ||||
377 | Scalar::Util::blessed $_ | ||||
378 | && $_->isa('CGI::Cookie') ? $_->as_string : $_ ) | ||||
379 | 9 | 682µs | foreach $res->cookies; # spent 525µs making 2 calls to CGI::Cookie::as_string, avg 262µs/call
# spent 135µs making 2 calls to Foswiki::Response::pushHeader, avg 68µs/call
# spent 9µs making 1 call to Foswiki::Response::cookies
# spent 7µs making 2 calls to Scalar::Util::blessed, avg 4µs/call
# spent 6µs making 2 calls to UNIVERSAL::isa, avg 3µs/call | ||
380 | } | ||||
381 | |||||
382 | =begin TML | ||||
383 | |||||
384 | ---++ ObjectMethod finalizeBody( $res, $req ) | ||||
385 | |||||
386 | * =$res= - Foswiki::Response object to get data from | ||||
387 | * =$req= - Foswiki::Request object to get data from | ||||
388 | |||||
389 | Should send $res' body to client. This method calls =write()= | ||||
390 | as needed, sou engines should redefine that method insted of this one. | ||||
391 | |||||
392 | =cut | ||||
393 | |||||
394 | # spent 180µs (60+120) within Foswiki::Engine::finalizeBody which was called:
# once (60µs+120µs) by Foswiki::Engine::finalize at line 301 | ||||
395 | 5 | 57µs | my ( $this, $res, $req ) = @_; | ||
396 | 1 | 35µs | my $body = $res->body; # spent 35µs making 1 call to Foswiki::Response::body | ||
397 | return unless defined $body; | ||||
398 | 1 | 4µs | $this->prepareWrite($res); # spent 4µs making 1 call to Foswiki::Engine::prepareWrite | ||
399 | 1 | 7µs | 1 | 10µs | if ( Scalar::Util::blessed($body) && $body->can('read') # spent 10µs making 1 call to Scalar::Util::blessed |
400 | or ref $body eq 'GLOB' ) | ||||
401 | { | ||||
402 | while ( !eof $body ) { | ||||
403 | read $body, my $buffer, 4096; | ||||
404 | last unless $this->write($buffer); | ||||
405 | } | ||||
406 | close $body; | ||||
407 | } | ||||
408 | else { | ||||
409 | 1 | 72µs | $this->write($body); # spent 72µs making 1 call to Foswiki::Engine::CGI::write | ||
410 | } | ||||
411 | } | ||||
412 | |||||
413 | =begin TML | ||||
414 | |||||
415 | ---++ flush($res, $req) | ||||
416 | |||||
417 | Forces the response headers to be emitted if they haven't already been sent | ||||
418 | (note that this may in some circumstances result in cookies being missed) | ||||
419 | before flushing what is in the body so far. | ||||
420 | |||||
421 | Before headers are sent, any Content-length is removed, as a call to | ||||
422 | flush is a statement that there's more to follow, but we don't know | ||||
423 | how much at this point. | ||||
424 | |||||
425 | This function should be used with great care! It requires that the output | ||||
426 | headers are fully complete before it is first called. Once it *has* been | ||||
427 | called, the response object will refuse any modifications that would alter | ||||
428 | the header. | ||||
429 | |||||
430 | =cut | ||||
431 | |||||
432 | sub flush { | ||||
433 | my ( $this, $res, $req ) = @_; | ||||
434 | |||||
435 | unless ( $res->outputHasStarted() ) { | ||||
436 | $res->deleteHeader('Content-Length'); | ||||
437 | $this->finalizeUploads( $res, $req ); | ||||
438 | $this->finalizeHeaders( $res, $req ); | ||||
439 | $this->prepareWrite($res); | ||||
440 | $res->outputHasStarted(1); | ||||
441 | } | ||||
442 | |||||
443 | my $body = $res->body(); | ||||
444 | |||||
445 | if ( Scalar::Util::blessed($body) || ref($body) eq 'GLOB' ) { | ||||
446 | throw Foswiki::EngineException('Cannot flush non-text response body'); | ||||
447 | } | ||||
448 | |||||
449 | $this->write($body); | ||||
450 | $res->body(''); | ||||
451 | } | ||||
452 | |||||
453 | =begin TML | ||||
454 | |||||
455 | ---++ ObjectMethod prepareWrite( $res ) | ||||
456 | |||||
457 | Abstract method, may be defined by inherited classes. | ||||
458 | * =$res= - Foswiki::Response object to get data from | ||||
459 | |||||
460 | Should perform any task needed before writing. | ||||
461 | That's ok if none needed ;-) | ||||
462 | |||||
463 | =cut | ||||
464 | |||||
465 | 1 | 9µs | # spent 4µs within Foswiki::Engine::prepareWrite which was called:
# once (4µs+0s) by Foswiki::Engine::finalizeBody at line 398 | ||
466 | |||||
467 | =begin TML | ||||
468 | |||||
469 | ---++ ObjectMethod write( $buffer ) | ||||
470 | |||||
471 | Abstract method, must be defined by inherited classes. | ||||
472 | * =$buffer= - chunk of data to be sent | ||||
473 | |||||
474 | Should send $buffer to client. | ||||
475 | |||||
476 | =cut | ||||
477 | |||||
478 | sub write { | ||||
479 | ASSERT('Pure virtual method - should never be called'); | ||||
480 | } | ||||
481 | |||||
482 | 1 | 4µs | 1; | ||
483 | __END__ |