← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:14 2015

Filename/var/www/foswikidev/core/lib/Foswiki/UI.pm
StatementsExecuted 100 statements in 3.24ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1111.28ms1.40msFoswiki::UI::::BEGIN@176Foswiki::UI::BEGIN@176
111256µs301µsFoswiki::UI::::BEGIN@171Foswiki::UI::BEGIN@171
111252µs296µsFoswiki::UI::::BEGIN@173Foswiki::UI::BEGIN@173
111170µs137sFoswiki::UI::::_executeFoswiki::UI::_execute
11181µs138sFoswiki::UI::::handleRequestFoswiki::UI::handleRequest
11155µs55µsFoswiki::UI::::BEGIN@16Foswiki::UI::BEGIN@16
11137µs137sFoswiki::UI::::__ANON__[:376]Foswiki::UI::__ANON__[:376]
11113µs28µsFoswiki::UI::::BEGIN@13Foswiki::UI::BEGIN@13
11110µs34µsFoswiki::UI::::BEGIN@164Foswiki::UI::BEGIN@164
11110µs136µsFoswiki::UI::::BEGIN@163Foswiki::UI::BEGIN@163
1119µs16µsFoswiki::UI::::BEGIN@14Foswiki::UI::BEGIN@14
1119µs38µsFoswiki::UI::::BEGIN@181Foswiki::UI::BEGIN@181
1118µs37µsFoswiki::UI::::checkAccessFoswiki::UI::checkAccess
1118µs90µsFoswiki::UI::::checkWebExistsFoswiki::UI::checkWebExists
1114µs4µsFoswiki::UI::::BEGIN@172Foswiki::UI::BEGIN@172
1114µs4µsFoswiki::UI::::BEGIN@174Foswiki::UI::BEGIN@174
1114µs4µsFoswiki::UI::::BEGIN@165Foswiki::UI::BEGIN@165
1114µs4µsFoswiki::UI::::BEGIN@166Foswiki::UI::BEGIN@166
1113µs3µsFoswiki::UI::::BEGIN@168Foswiki::UI::BEGIN@168
1113µs3µsFoswiki::UI::::BEGIN@170Foswiki::UI::BEGIN@170
1113µs3µsFoswiki::UI::::BEGIN@175Foswiki::UI::BEGIN@175
1113µs3µsFoswiki::UI::::BEGIN@169Foswiki::UI::BEGIN@169
0000s0sFoswiki::UI::::__ANON__[:406]Foswiki::UI::__ANON__[:406]
0000s0sFoswiki::UI::::__ANON__[:429]Foswiki::UI::__ANON__[:429]
0000s0sFoswiki::UI::::__ANON__[:438]Foswiki::UI::__ANON__[:438]
0000s0sFoswiki::UI::::__ANON__[:455]Foswiki::UI::__ANON__[:455]
0000s0sFoswiki::UI::::__ANON__[:488]Foswiki::UI::__ANON__[:488]
0000s0sFoswiki::UI::::__ANON__[:500]Foswiki::UI::__ANON__[:500]
0000s0sFoswiki::UI::::checkTopicExistsFoswiki::UI::checkTopicExists
0000s0sFoswiki::UI::::checkValidationKeyFoswiki::UI::checkValidationKey
0000s0sFoswiki::UI::::logonFoswiki::UI::logon
0000s0sFoswiki::UI::::runFoswiki::UI::run
Call graph for these subroutines as a Graphviz dot language file.
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::UI
6
7Coordinator of execution flow and service functions used by the UI packages
8
9=cut
10
11package Foswiki::UI;
12
13228µs242µs
# spent 28µs (13+14) within Foswiki::UI::BEGIN@13 which was called: # once (13µs+14µs) by main::BEGIN@28 at line 13
use strict;
# spent 28µs making 1 call to Foswiki::UI::BEGIN@13 # spent 14µs making 1 call to strict::import
142380µs222µs
# spent 16µs (9+6) within Foswiki::UI::BEGIN@14 which was called: # once (9µs+6µs) by main::BEGIN@28 at line 14
use warnings;
# spent 16µs making 1 call to Foswiki::UI::BEGIN@14 # spent 6µs making 1 call to warnings::import
15
16
# spent 55µs within Foswiki::UI::BEGIN@16 which was called: # once (55µs+0s) by main::BEGIN@28 at line 161
BEGIN {
17
181900ns if ( $Foswiki::cfg{UseLocale} ) {
19 require locale;
20 import locale();
21 }
22
23 #Monitor::MARK("Start of BEGIN block in UI.pm");
2411µs $Foswiki::cfg{SwitchBoard} ||= {};
25
26 # package - perl package that contains the method for this request
27 # function - name of the function in package
28 # context - hash of context vars to define
29 # allow - hash of HTTP methods to allow (all others are denied)
30 # deny - hash of HTTP methods that are denied (all others are allowed)
31 # 'deny' is not tested if 'allow' is defined
32
33 # The switchboard can contain entries either as hashes or as arrays.
34 # The array format specifies [0] package, [1] function, [2] context
35 # and should be used when declaring scripts from plugins that must work
36 # with Foswiki 1.0.0 and 1.0.4.
37
3813µs $Foswiki::cfg{SwitchBoard}{attach} = {
39 package => 'Foswiki::UI::Attach',
40 function => 'attach',
41 context => { attach => 1 },
42 };
4312µs $Foswiki::cfg{SwitchBoard}{changes} = {
44 package => 'Foswiki::UI::Changes',
45 function => 'changes',
46 context => { changes => 1 },
47 };
4811µs $Foswiki::cfg{SwitchBoard}{configure} = {
49 package => 'Foswiki::UI::Configure',
50 function => 'configure'
51 };
5212µs $Foswiki::cfg{SwitchBoard}{edit} = {
53 package => 'Foswiki::UI::Edit',
54 function => 'edit',
55 context => { edit => 1 },
56 };
5714µs $Foswiki::cfg{SwitchBoard}{jsonrpc} = {
58 package => 'Foswiki::Contrib::JsonRpcContrib',
59 function => 'dispatch',
60 context => { jsonrpc => 1 },
61 };
6212µs $Foswiki::cfg{SwitchBoard}{login} = {
63 package => undef,
64 function => 'logon',
65 context => { ( login => 1, logon => 1 ) },
66 };
6714µs $Foswiki::cfg{SwitchBoard}{logon} = {
68 package => undef,
69 function => 'logon',
70 context => { ( login => 1, logon => 1 ) },
71 };
7214µs $Foswiki::cfg{SwitchBoard}{manage} = {
73 package => 'Foswiki::UI::Manage',
74 function => 'manage',
75 context => { manage => 1 },
76 allow => { POST => 1 },
77 };
7812µs $Foswiki::cfg{SwitchBoard}{oops} = {
79 package => 'Foswiki::UI::Oops',
80 function => 'oops_cgi',
81 context => { oops => 1 },
82 };
8311µs $Foswiki::cfg{SwitchBoard}{preview} = {
84 package => 'Foswiki::UI::Preview',
85 function => 'preview',
86 context => { preview => 1 },
87 };
881500ns $Foswiki::cfg{SwitchBoard}{previewauth} =
89 $Foswiki::cfg{SwitchBoard}{preview};
9011µs $Foswiki::cfg{SwitchBoard}{rdiff} = {
91 package => 'Foswiki::UI::RDiff',
92 function => 'diff',
93 context => { diff => 1 },
94 };
951500ns $Foswiki::cfg{SwitchBoard}{rdiffauth} = $Foswiki::cfg{SwitchBoard}{rdiff};
9612µs $Foswiki::cfg{SwitchBoard}{register} = {
97 package => 'Foswiki::UI::Register',
98 function => 'register_cgi',
99 context => { register => 1 },
100
101 # method verify must allow GET; protect in Foswiki::UI::Register
102 #allow => { POST => 1 },
103 };
10411µs $Foswiki::cfg{SwitchBoard}{rename} = {
105 package => 'Foswiki::UI::Rename',
106 function => 'rename',
107 context => { rename => 1 },
108
109 # Rename is 2 stage; protect in Foswiki::UI::Rename
110 #allow => { POST => 1 },
111 };
11212µs $Foswiki::cfg{SwitchBoard}{resetpasswd} = {
113 package => 'Foswiki::UI::Passwords',
114 function => 'resetPassword',
115 context => { resetpasswd => 1 },
116 allow => { POST => 1 },
117 };
11813µs $Foswiki::cfg{SwitchBoard}{rest} = {
119 package => 'Foswiki::UI::Rest',
120 function => 'rest',
121 context => { rest => 1 },
122 };
1231400ns $Foswiki::cfg{SwitchBoard}{restauth} = $Foswiki::cfg{SwitchBoard}{rest};
12412µs $Foswiki::cfg{SwitchBoard}{save} = {
125 package => 'Foswiki::UI::Save',
126 function => 'save',
127 context => { save => 1 },
128 allow => { POST => 1 },
129 };
13011µs $Foswiki::cfg{SwitchBoard}{search} = {
131 package => 'Foswiki::UI::Search',
132 function => 'search',
133 context => { search => 1 },
134 };
13511µs $Foswiki::cfg{SwitchBoard}{statistics} = {
136 package => 'Foswiki::UI::Statistics',
137 function => 'statistics',
138 context => { statistics => 1 },
139 };
14012µs $Foswiki::cfg{SwitchBoard}{upload} = {
141 package => 'Foswiki::UI::Upload',
142 function => 'upload',
143 context => { upload => 1 },
144 allow => { POST => 1 },
145 };
14616µs $Foswiki::cfg{SwitchBoard}{viewfile} = {
147 package => 'Foswiki::UI::Viewfile',
148 function => 'viewfile',
149 context => { viewfile => 1 },
150 };
1511500ns $Foswiki::cfg{SwitchBoard}{viewfileauth} =
152 $Foswiki::cfg{SwitchBoard}{viewfile};
15311µs $Foswiki::cfg{SwitchBoard}{view} = {
154 package => 'Foswiki::UI::View',
155 function => 'view',
156 context => { view => 1 },
157 };
15815µs $Foswiki::cfg{SwitchBoard}{viewauth} = $Foswiki::cfg{SwitchBoard}{view};
159
160 #Monitor::MARK("End of BEGIN block in UI.pm");
161154µs155µs}
# spent 55µs making 1 call to Foswiki::UI::BEGIN@16
162
163230µs2262µs
# spent 136µs (10+126) within Foswiki::UI::BEGIN@163 which was called: # once (10µs+126µs) by main::BEGIN@28 at line 163
use Error qw(:try);
# spent 136µs making 1 call to Foswiki::UI::BEGIN@163 # spent 126µs making 1 call to Error::import
164225µs257µs
# spent 34µs (10+23) within Foswiki::UI::BEGIN@164 which was called: # once (10µs+23µs) by main::BEGIN@28 at line 164
use Assert;
# spent 34µs making 1 call to Foswiki::UI::BEGIN@164 # spent 23µs making 1 call to Exporter::import
165218µs14µs
# spent 4µs within Foswiki::UI::BEGIN@165 which was called: # once (4µs+0s) by main::BEGIN@28 at line 165
use CGI ();
# spent 4µs making 1 call to Foswiki::UI::BEGIN@165
166218µs14µs
# spent 4µs within Foswiki::UI::BEGIN@166 which was called: # once (4µs+0s) by main::BEGIN@28 at line 166
use JSON ();
# spent 4µs making 1 call to Foswiki::UI::BEGIN@166
167
168216µs13µs
# spent 3µs within Foswiki::UI::BEGIN@168 which was called: # once (3µs+0s) by main::BEGIN@28 at line 168
use Foswiki ();
# spent 3µs making 1 call to Foswiki::UI::BEGIN@168
169216µs13µs
# spent 3µs within Foswiki::UI::BEGIN@169 which was called: # once (3µs+0s) by main::BEGIN@28 at line 169
use Foswiki::Request ();
# spent 3µs making 1 call to Foswiki::UI::BEGIN@169
170217µs13µs
# spent 3µs within Foswiki::UI::BEGIN@170 which was called: # once (3µs+0s) by main::BEGIN@28 at line 170
use Foswiki::Response ();
# spent 3µs making 1 call to Foswiki::UI::BEGIN@170
171293µs1301µs
# spent 301µs (256+45) within Foswiki::UI::BEGIN@171 which was called: # once (256µs+45µs) by main::BEGIN@28 at line 171
use Foswiki::Infix::Error ();
# spent 301µs making 1 call to Foswiki::UI::BEGIN@171
172225µs14µs
# spent 4µs within Foswiki::UI::BEGIN@172 which was called: # once (4µs+0s) by main::BEGIN@28 at line 172
use Foswiki::OopsException ();
# spent 4µs making 1 call to Foswiki::UI::BEGIN@172
173286µs1296µs
# spent 296µs (252+44) within Foswiki::UI::BEGIN@173 which was called: # once (252µs+44µs) by main::BEGIN@28 at line 173
use Foswiki::EngineException ();
# spent 296µs making 1 call to Foswiki::UI::BEGIN@173
174217µs14µs
# spent 4µs within Foswiki::UI::BEGIN@174 which was called: # once (4µs+0s) by main::BEGIN@28 at line 174
use Foswiki::ValidationException ();
# spent 4µs making 1 call to Foswiki::UI::BEGIN@174
175218µs13µs
# spent 3µs within Foswiki::UI::BEGIN@175 which was called: # once (3µs+0s) by main::BEGIN@28 at line 175
use Foswiki::AccessControlException ();
# spent 3µs making 1 call to Foswiki::UI::BEGIN@175
1762100µs11.40ms
# spent 1.40ms (1.28+118µs) within Foswiki::UI::BEGIN@176 which was called: # once (1.28ms+118µs) by main::BEGIN@28 at line 176
use Foswiki::Validation ();
# spent 1.40ms making 1 call to Foswiki::UI::BEGIN@176
177
178# Used to lazily load UI handler modules
17911µsour %isInitialized = ();
180
18121.97ms267µs
# spent 38µs (9+29) within Foswiki::UI::BEGIN@181 which was called: # once (9µs+29µs) by main::BEGIN@28 at line 181
use constant TRACE_REQUEST => 0;
# spent 38µs making 1 call to Foswiki::UI::BEGIN@181 # spent 29µs making 1 call to constant::import
182
183=begin TML
184
185---++ StaticMethod handleRequest($req) -> $res
186
187Main coordinator of request-process-response cycle.
188
189=cut
190
191
# spent 138s (81µs+138) within Foswiki::UI::handleRequest which was called: # once (81µs+138s) by Foswiki::Engine::CLI::run at line 60 of /var/www/foswikidev/core/lib/Foswiki/Engine/CLI.pm
sub handleRequest {
1921300ns my $req = shift;
193
1941100ns my $res;
195
19612µs13µs my $dispatcher = $Foswiki::cfg{SwitchBoard}{ $req->action() };
# spent 3µs making 1 call to Foswiki::Request::action
1971200ns unless ( defined $dispatcher ) {
198 $res = new Foswiki::Response();
199 $res->header( -type => 'text/html', -status => '404' );
200 my $html = CGI::start_html('404 Not Found');
201 $html .= CGI::h1( {}, 'Not Found' );
202 $html .= CGI::p( {},
203 "The requested URL "
204 . $req->uri
205 . " was not found on this server." );
206 $html .= CGI::end_html();
207 $res->print($html);
208 return $res;
209 }
210
2111600ns if ( ref($dispatcher) eq 'ARRAY' ) {
212
213 # Old-style array entry in switchboard from a plugin
214 my @array = @$dispatcher;
215 $dispatcher = {
216 package => $array[0],
217 function => $array[1],
218 context => $array[2],
219 };
220 }
221
22211µs if ( $dispatcher->{package} && !$isInitialized{ $dispatcher->{package} } ) {
223135µs eval qq(use $dispatcher->{package});
# spent 95µs executing statements in string eval
# includes 2.21ms spent executing 1 call to 1 sub defined therein.
2241200ns die Foswiki::encode_utf8($@) if $@;
22512µs $isInitialized{ $dispatcher->{package} } = 1;
226 }
227
2281500ns my $sub = '';
2291800ns $sub = $dispatcher->{package} . '::' if $dispatcher->{package};
2301300ns $sub .= $dispatcher->{function};
231
232 # If the X-Foswiki-Tickle header is present, this request is an
233 # attempt to verify that the requested function is available on
234 # this Foswiki. Respond with the serialised dispatcher, and
235 # finish the request.
236 # Need to stringify since VERSION is a version object.
23714µs128µs if ( $req->header('X-Foswiki-Tickle') ) {
# spent 28µs making 1 call to Foswiki::Request::header
238 my $data = {
239 SCRIPT_NAME => $ENV{SCRIPT_NAME},
240 VERSION => $Foswiki::VERSION->stringify(),
241 RELEASE => $Foswiki::RELEASE,
242 };
243 my $res = new Foswiki::Response();
244 $res->header( -type => 'application/json', -status => '200' );
245
246 my $d = JSON->new->allow_nonref->encode($data);
247 $res->print($d);
248 return $res;
249 }
250
251 # Get the params cache from the path
25212µs114µs my $cache = $req->param('foswiki_redirect_cache');
# spent 14µs making 1 call to Foswiki::Request::param
2531400ns if ( defined $cache ) {
254 $req->delete('foswiki_redirect_cache');
255 }
256
257 # If the path specifies a cache path, use that. It's arbitrary
258 # as to which takes precedence (param or path) because we should
259 # never have both at once.
26013µs14µs my $path_info = $req->path_info();
# spent 4µs making 1 call to Foswiki::Request::pathInfo
2611500ns if ( $path_info =~ s#/foswiki_redirect_cache/([a-f0-9]{32})## ) {
262 $cache = $1;
263 $req->path_info($path_info);
264 }
265
2661200ns if ( defined $cache && $cache =~ m/^([a-f0-9]{32})$/ ) {
267 require Foswiki::Request::Cache;
268
269 # implicit untaint required, because $cache may be used in a filename.
270 # Note that the cache serialises the method and path_info, which
271 # will be restored.
272 Foswiki::Request::Cache->new()->load( $1, $req );
273 }
274
275 if (TRACE_REQUEST) {
276 print STDERR "INCOMING "
277 . $req->method() . " "
278 . $req->url . " -> "
279 . $sub . "\n";
280 print STDERR "validation_key: "
281 . ( $req->param('validation_key') || 'no key' ) . "\n";
282
283 #require Data::Dumper;
284 #print STDERR Data::Dumper->Dump([$req]);
285 }
286
28716µs12µs if ( UNIVERSAL::isa( $Foswiki::engine, 'Foswiki::Engine::CLI' ) ) {
# spent 2µs making 1 call to UNIVERSAL::isa
288 $dispatcher->{context}->{command_line} = 1;
289 }
290 elsif (
291 defined $req->method()
292 && (
293 (
294 defined $dispatcher->{allow}
295 && !$dispatcher->{allow}->{ uc( $req->method() ) }
296 )
297 || ( defined $dispatcher->{deny}
298 && $dispatcher->{deny}->{ uc( $req->method() ) } )
299 )
300 )
301 {
302 $res = new Foswiki::Response();
303 $res->header( -type => 'text/html', -status => '405' );
304 $res->print( '<H1>Bad Request:</H1> The request method: '
305 . uc( $req->method() )
306 . ' is denied for the '
307 . $req->action()
308 . ' action.' );
309 if ( uc( $req->method() ) eq 'GET' ) {
310 $res->print( '<br/><br/>'
311 . 'The <tt><b>'
312 . $req->action()
313 . '</b></tt> script can only be called with the <tt>POST</tt> type method'
314 . '<br/><br/>'
315 . 'For example:<br/>'
316 . '&nbsp;&nbsp;&nbsp;<tt>&lt;form method="post" action="%SCRIPTURL{'
317 . $req->action()
318 . '}%/%WEB%/%TOPIC%"&gt;</tt><br/>'
319 . '<br/><br/>See <a href="http://foswiki.org/System/CommandAndCGIScripts#A_61'
320 . $req->action()
321 . '_61">System.CommandAndCGIScripts</a> for more information.'
322 );
323 }
324 return $res;
325 }
32615µs1137s $res = _execute( $req, \&$sub, %{ $dispatcher->{context} } );
# spent 137s making 1 call to Foswiki::UI::_execute
32718µs return $res;
328}
329
330=begin TML
331
332---++ StaticMethod _execute($req, $sub, %initialContext) -> $res
333
334Creates a Foswiki session object with %initalContext and calls
335$sub method. Returns the Foswiki::Response object.
336
337=cut
338
339
# spent 137s (170µs+137) within Foswiki::UI::_execute which was called: # once (170µs+137s) by Foswiki::UI::handleRequest at line 326
sub _execute {
34012µs my ( $req, $sub, %initialContext ) = @_;
341
3421100ns my $session;
3431100ns my $res;
344
345 # If we get a known exception from new Foswiki(), then it must have
346 # come from one of the plugin methods which are called at this
347 # time (initPlugin, earlyInitPlugin for example). The
348 # setup of the Foswiki object is pretty much complete; we can safely
349 # recover it from $Foswiki::Plugins::SESSION and clean it up.
350 # Error::Simple and EngineException indicate something more
351 # basic, however, that we can't easily clean up.
352 # Exception handling note: We need a session and a response for
353 # cleanup; depending on where the exception was raised, the session
354 # may have to be grabbed from $Foswiki::Plugins. Exception handlers
355 # need to be careful about using the response from the session, as
356 # it may already be polluted with non-exception-related crud.
357
# spent 137s (37µs+137) within Foswiki::UI::__ANON__[/var/www/foswikidev/core/lib/Foswiki/UI.pm:376] which was called: # once (37µs+137s) by Error::subs::try at line 419 of Error.pm
try {
358
359 # DO NOT pass in $req->remoteUser here (even though may seem
360 # to be right) because it may occlude the login manager.
361 # Exception is when running in CLI environment.
362
36316µs2251ms $session = new Foswiki(
# spent 251ms making 1 call to Foswiki::new # spent 2µs making 1 call to Foswiki::Request::remoteUser
364 ( defined $ENV{GATEWAY_INTERFACE} || defined $ENV{MOD_PERL} )
365 ? undef
366 : $req->remoteUser(),
367 $req, \%initialContext
368 );
369
37011µs $res = $session->{response};
371
372110µs14µs unless ( defined $res->status() && $res->status() =~ m/^\s*3\d\d/ ) {
# spent 4µs making 1 call to Foswiki::Response::status
37317µs217µs $session->getLoginManager()->checkAccess();
# spent 10µs making 1 call to Foswiki::LoginManager::checkAccess # spent 7µs making 1 call to Foswiki::getLoginManager
37414µs1137s &$sub($session);
# spent 137s making 1 call to Foswiki::UI::View::view
375 }
376 }
377 catch Foswiki::ValidationException with {
378 my $e = shift;
379
380 $session ||= $Foswiki::Plugins::SESSION;
381 $res = $session->{response} if $session;
382 $res ||= new Foswiki::Response();
383
384 my $query = $session->{request};
385
386 # Cache the original query, so we can complete if if it is
387 # confirmed
388 require Foswiki::Request::Cache;
389 my $uid = Foswiki::Request::Cache->new()->save($query);
390
391 print STDERR "ValidationException: redirect with $uid\n"
392 if DEBUG;
393
394 # We use the login script for validation because it already
395 # has the correct criteria in httpd.conf for Apache login.
396 # URL is absolute as required by
397 # http://tools.ietf.org/html/rfc2616#section-14.30
398 my $url = $session->getScriptUrl(
399 1, 'login',
400 $session->{webName}, $session->{topicName},
401 foswikiloginaction => 'validate',
402 foswikioriginalquery => $uid
403 );
404
405 $session->redirect($url); # no passthrough
406 }
407 catch Foswiki::AccessControlException with {
408 my $e = shift;
409
410 $session ||= $Foswiki::Plugins::SESSION;
411 $res = $session->{response} if $session;
412 $res ||= new Foswiki::Response();
413
414 unless ( $session->getLoginManager()->forceAuthentication() ) {
415
416 # Login manager did not want to authenticate, perhaps because
417 # we are already authenticated.
418 my $exception = new Foswiki::OopsException(
419 'accessdenied',
420 status => 403,
421 web => $e->{web},
422 topic => $e->{topic},
423 def => 'topic_access',
424 params => [ $e->{mode}, $e->{reason} ]
425 );
426
427 $exception->generate($session);
428 }
429 }
430 catch Foswiki::OopsException with {
431 my $e = shift;
432
433 $session ||= $Foswiki::Plugins::SESSION;
434 $res = $session->{response} if $session;
435 $res ||= new Foswiki::Response();
436
437 $e->generate($session);
438 }
439 catch Foswiki::EngineException with {
440 my $e = shift;
441 $session ||= $Foswiki::Plugins::SESSION;
442 $res = $e->{response};
443
444 # Note: do *not* use the response from the session; see notes above
445 unless ( defined $res ) {
446 $res = new Foswiki::Response();
447 $res->header( -type => 'text/html', -status => $e->{status} );
448 my $html = CGI::start_html( $e->{status} . ' Bad Request' );
449 $html .= CGI::h1( {}, 'Bad Request' );
450 $html .= CGI::p( {}, $e->{reason} );
451 $html .= CGI::end_html();
452 $res->print( Foswiki::encode_utf8($html) );
453 }
454 $Foswiki::engine->finalizeError( $res, $session->{request} );
455 }
456 catch Error with {
457
458 # Most usually a 'die'
459 my $e = shift;
460
461 $session ||= $Foswiki::Plugins::SESSION;
462 $res = $session->{response} if $session;
463 $res ||= new Foswiki::Response();
464
465 $res->header( -type => 'text/plain', -status => '500' )
466 unless $res->outputHasStarted();
467 if (DEBUG) {
468
469 # output the full message and stacktrace to the browser
470 $res->print( Foswiki::encode_utf8( $e->stringify() ) );
471 }
472 else {
473 my $mess = $e->stringify();
474 print STDERR $mess;
475 $session->logger->log( 'warning', $mess ) if $session;
476
477 # tell the browser where to look for more help
478 my $text =
479'Foswiki detected an internal error - please check your Foswiki logs and webserver logs for more information.'
480 . "\n\n";
481 $mess =~ s/ at .*$//s;
482
483 # cut out pathnames from public announcement
484 $mess =~ s#/[\w./]+#path#g unless DEBUG;
485 $text .= $mess;
486 $res->print( Foswiki::encode_utf8($text) );
487 }
488 }
489 otherwise {
490
491 # Aargh! Should never get here
492 my $e = shift;
493 $res = new Foswiki::Response;
494 $res->header( -type => 'text/plain' );
495 $res->print("Unspecified internal error\n\n");
496 if (DEBUG) {
497 eval "require Data::Dumper";
498 $res->print( Data::Dumper::Dumper( \$e ) );
499 }
500184µs12137s };
# spent 137s making 1 call to Error::subs::try # spent 12µs making 5 calls to Error::catch, avg 2µs/call # spent 4µs making 5 calls to Error::subs::with, avg 880ns/call # spent 3µs making 1 call to Error::subs::otherwise
50114µs111.5ms $session->finish() if $session;
# spent 11.5ms making 1 call to Foswiki::finish
502169µs return $res;
503}
504
505=begin TML
506
507---++ StaticMethod logon($session)
508
509Handler for "logon" action.
510 * =$session= is a Foswiki session object
511
512=cut
513
514sub logon {
515 my $session = shift;
516
517 if ( defined $Foswiki::cfg{LoginManager}
518 && $Foswiki::cfg{LoginManager} eq 'none' )
519 {
520 throw Foswiki::OopsException(
521 'attention',
522 status => 500,
523 def => 'login_disabled',
524 );
525 }
526
527 my $action = $session->{request}->param('foswikiloginaction');
528 $session->{request}->delete('foswikiloginaction');
529
530 if ( defined $action && $action eq 'validate' ) {
531 Foswiki::Validation::validate($session);
532 }
533 else {
534 $session->getLoginManager()->login( $session->{request}, $session );
535 }
536}
537
538=begin TML
539
540---++ StaticMethod checkWebExists( $session, $web, $op )
541
542Check if the web exists. If it doesn't, will throw an oops exception.
543 $op is the user operation being performed.
544
545=cut
546
547
# spent 90µs (8+82) within Foswiki::UI::checkWebExists which was called: # once (8µs+82µs) by Foswiki::UI::View::view at line 104 of /var/www/foswikidev/core/lib/Foswiki/UI/View.pm
sub checkWebExists {
5481900ns my ( $session, $webName, $op ) = @_;
549 ASSERT( $session->isa('Foswiki') ) if DEBUG;
550
5511700ns if ( $session->{invalidWeb} ) {
552 throw Foswiki::OopsException(
553 'accessdenied',
554 status => 404,
555 def => 'bad_web_name',
556 web => $webName,
557 topic => $Foswiki::cfg{WebPrefsTopicName},
558 params => [ $op, $session->{invalidWeb} ]
559 );
560 }
5611400ns unless ($webName) {
562 throw Foswiki::OopsException(
563 'accessdenied',
564 status => 404,
565 def => 'bad_web_name',
566 web => $webName,
567 topic => $Foswiki::cfg{WebPrefsTopicName},
568 params => [$op]
569 );
570 }
571
57215µs182µs unless ( $session->webExists($webName) ) {
# spent 82µs making 1 call to Foswiki::webExists
573 throw Foswiki::OopsException(
574 'accessdenied',
575 status => 404,
576 def => 'no_such_web',
577 web => $webName,
578 topic => $Foswiki::cfg{WebPrefsTopicName},
579 params => [$op]
580 );
581 }
582}
583
584=begin TML
585
586---++ StaticMethod topicExists( $session, $web, $topic, $op ) => boolean
587
588Check if the given topic exists, throwing an OopsException
589if it doesn't. $op is the user operation being performed.
590
591=cut
592
593sub checkTopicExists {
594 my ( $session, $web, $topic, $op ) = @_;
595 ASSERT( $session->isa('Foswiki') ) if DEBUG;
596
597 if ( $session->{invalidTopic} ) {
598 throw Foswiki::OopsException(
599 'accessdenied',
600 status => 404,
601 def => 'invalid_topic_name',
602 web => $web,
603 topic => $topic,
604 params => [ $op, $session->{invalidTopic} ]
605 );
606 }
607
608 unless ( $session->topicExists( $web, $topic ) ) {
609 throw Foswiki::OopsException(
610 'accessdenied',
611 status => 404,
612 def => 'no_such_topic',
613 web => $web,
614 topic => $topic,
615 params => [$op]
616 );
617 }
618}
619
620=begin TML
621
622---++ StaticMethod checkAccess( $session, $mode, $topicObject )
623
624Check if the given mode of access by the given user to the given
625web.topic is permissible, throwing a Foswiki::AccessControlException if not.
626
627=cut
628
629
# spent 37µs (8+29) within Foswiki::UI::checkAccess which was called: # once (8µs+29µs) by Foswiki::UI::View::view at line 130 of /var/www/foswikidev/core/lib/Foswiki/UI/View.pm
sub checkAccess {
63011µs my ( $session, $mode, $topicObject ) = @_;
631 ASSERT( $session->isa('Foswiki') ) if DEBUG;
632
63316µs129µs unless ( $topicObject->haveAccess($mode) ) {
# spent 29µs making 1 call to Foswiki::Meta::haveAccess
634 throw Foswiki::AccessControlException( $mode, $session->{user},
635 $topicObject->web, $topicObject->topic, $Foswiki::Meta::reason );
636 }
637}
638
639=begin TML
640
641---++ StaticMethod checkValidationKey( $session )
642
643Check the validation key for the given action. Throws an exception
644if the validation key isn't valid (handled in _execute(), above)
645 * =$session= - the current session object
646
647See Foswiki::Validation for more information.
648
649=cut
650
651sub checkValidationKey {
652 my ($session) = @_;
653
654 # If validation is disabled, do nothing
655 return if ( $Foswiki::cfg{Validation}{Method} eq 'none' );
656
657 # No point in command-line mode
658 return if $session->inContext('command_line');
659
660 # Check the nonce before we do anything else
661 my $nonce = $session->{request}->param('validation_key');
662 $session->{request}->delete('validation_key');
663 if ( !defined($nonce)
664 || !Foswiki::Validation::isValidNonce( $session->getCGISession(),
665 $nonce ) )
666 {
667 throw Foswiki::ValidationException( $session->{request}->action() );
668 }
669 if ( defined($nonce) && !$session->{request}->param('preserve_vk') ) {
670
671 # Expire the nonce. If the user tries to use it again, they will
672 # be prompted. Note that if preserve_vk is provided we don't
673 # expire the nonce - this is to support browsers that don't
674 # implement FormData in javascript (such as IE8)
675 Foswiki::Validation::expireValidationKeys( $session->getCGISession(),
676 $Foswiki::cfg{Validation}{ExpireKeyOnUse} ? $nonce : undef );
677
678 # Write a new validation code into the response
679 my $context =
680 $session->{request}->url( -full => 1, -path => 1, -query => 1 )
681 . time();
682 my $cgis = $session->getCGISession();
683 if ($cgis) {
684 my $nonce =
685 Foswiki::Validation::generateValidationKey( $cgis, $context, 1 );
686 $session->{response}
687 ->pushHeader( 'X-Foswiki-Validation' => $nonce );
688 }
689 }
690 $session->{request}->delete('preserve_vk');
691}
692
693=begin TML
694
695---++ StaticMethod run( $method, %context )
696
697Supported for bin scripts that were written for Foswiki < 1.0. The parameters
698are a function reference to the UI method to call and initial context.
699
700In Foswiki >= 1.0 it should be replaced by a Config.spec entry such as:
701
702# **PERL H**
703# Bin script registration - do not modify
704$Foswiki::cfg{SwitchBoard}{publish} = [ "Foswiki::Contrib::Publish", "publish", { publishing => 1 } ];
705
706=cut
707
708sub run {
709 my ( $method, %context ) = @_;
710
711 if ( UNIVERSAL::isa( $Foswiki::engine, 'Foswiki::Engine::CLI' ) ) {
712 $context{command_line} = 1;
713 }
714 _execute( Foswiki::Request->new(), $method, %context );
715}
716
71713µs1;
718__END__