Filename | /usr/local/src/github.com/foswiki/core/lib/Foswiki/UI.pm |
Statements | Executed 93 statements in 5.25ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 2.48ms | 2.75ms | BEGIN@160 | Foswiki::UI::
1 | 1 | 1 | 430µs | 516µs | BEGIN@157 | Foswiki::UI::
1 | 1 | 1 | 305µs | 265s | _execute | Foswiki::UI::
1 | 1 | 1 | 191µs | 265s | handleRequest | Foswiki::UI::
1 | 1 | 1 | 105µs | 105µs | BEGIN@16 | Foswiki::UI::
1 | 1 | 1 | 95µs | 265s | __ANON__[:318] | Foswiki::UI::
1 | 1 | 1 | 29µs | 254µs | checkWebExists | Foswiki::UI::
1 | 1 | 1 | 27µs | 2.31ms | checkAccess | Foswiki::UI::
1 | 1 | 1 | 25µs | 34µs | BEGIN@13 | Foswiki::UI::
1 | 1 | 1 | 22µs | 175µs | BEGIN@165 | Foswiki::UI::
1 | 1 | 1 | 21µs | 44µs | BEGIN@14 | Foswiki::UI::
1 | 1 | 1 | 19µs | 415µs | BEGIN@149 | Foswiki::UI::
1 | 1 | 1 | 17µs | 57µs | BEGIN@150 | Foswiki::UI::
1 | 1 | 1 | 15µs | 15µs | BEGIN@159 | Foswiki::UI::
1 | 1 | 1 | 10µs | 10µs | BEGIN@158 | Foswiki::UI::
1 | 1 | 1 | 10µs | 10µs | BEGIN@151 | Foswiki::UI::
1 | 1 | 1 | 10µs | 10µs | BEGIN@155 | Foswiki::UI::
1 | 1 | 1 | 9µs | 9µs | BEGIN@153 | Foswiki::UI::
1 | 1 | 1 | 9µs | 9µs | BEGIN@154 | Foswiki::UI::
1 | 1 | 1 | 9µs | 9µs | BEGIN@156 | Foswiki::UI::
1 | 1 | 1 | 3µs | 3µs | CORE:subst (opcode) | Foswiki::UI::
0 | 0 | 0 | 0s | 0s | __ANON__[:348] | Foswiki::UI::
0 | 0 | 0 | 0s | 0s | __ANON__[:371] | Foswiki::UI::
0 | 0 | 0 | 0s | 0s | __ANON__[:380] | Foswiki::UI::
0 | 0 | 0 | 0s | 0s | __ANON__[:395] | Foswiki::UI::
0 | 0 | 0 | 0s | 0s | __ANON__[:428] | Foswiki::UI::
0 | 0 | 0 | 0s | 0s | __ANON__[:435] | Foswiki::UI::
0 | 0 | 0 | 0s | 0s | checkTopicExists | Foswiki::UI::
0 | 0 | 0 | 0s | 0s | checkValidationKey | Foswiki::UI::
0 | 0 | 0 | 0s | 0s | logon | Foswiki::UI::
0 | 0 | 0 | 0s | 0s | run | Foswiki::UI::
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 | |||||
7 | Coordinator of execution flow and service functions used by the UI packages | ||||
8 | |||||
9 | =cut | ||||
10 | |||||
11 | package Foswiki::UI; | ||||
12 | |||||
13 | 2 | 46µs | 2 | 44µs | # spent 34µs (25+9) within Foswiki::UI::BEGIN@13 which was called:
# once (25µs+9µs) by main::BEGIN@28 at line 13 # spent 34µs making 1 call to Foswiki::UI::BEGIN@13
# spent 9µs making 1 call to strict::import |
14 | 2 | 642µs | 2 | 68µs | # spent 44µs (21+24) within Foswiki::UI::BEGIN@14 which was called:
# once (21µs+24µs) by main::BEGIN@28 at line 14 # spent 44µs making 1 call to Foswiki::UI::BEGIN@14
# spent 24µs making 1 call to warnings::import |
15 | |||||
16 | # spent 105µs within Foswiki::UI::BEGIN@16 which was called:
# once (105µs+0s) by main::BEGIN@28 at line 147 | ||||
17 | |||||
18 | #Monitor::MARK("Start of BEGIN block in UI.pm"); | ||||
19 | 25 | 105µs | $Foswiki::cfg{SwitchBoard} ||= {}; | ||
20 | |||||
21 | # package - perl package that contains the method for this request | ||||
22 | # function - name of the function in package | ||||
23 | # context - hash of context vars to define | ||||
24 | # allow - hash of HTTP methods to allow (all others are denied) | ||||
25 | # deny - hash of HTTP methods that are denied (all others are allowed) | ||||
26 | # 'deny' is not tested if 'allow' is defined | ||||
27 | |||||
28 | # The switchboard can contain entries either as hashes or as arrays. | ||||
29 | # The array format specifies [0] package, [1] function, [2] context | ||||
30 | # and should be used when declaring scripts from plugins that must work | ||||
31 | # with Foswiki 1.0.0 and 1.0.4. | ||||
32 | |||||
33 | $Foswiki::cfg{SwitchBoard}{attach} = { | ||||
34 | package => 'Foswiki::UI::Attach', | ||||
35 | function => 'attach', | ||||
36 | context => { attach => 1 }, | ||||
37 | }; | ||||
38 | $Foswiki::cfg{SwitchBoard}{changes} = { | ||||
39 | package => 'Foswiki::UI::Changes', | ||||
40 | function => 'changes', | ||||
41 | context => { changes => 1 }, | ||||
42 | }; | ||||
43 | $Foswiki::cfg{SwitchBoard}{edit} = { | ||||
44 | package => 'Foswiki::UI::Edit', | ||||
45 | function => 'edit', | ||||
46 | context => { edit => 1 }, | ||||
47 | }; | ||||
48 | $Foswiki::cfg{SwitchBoard}{login} = { | ||||
49 | package => undef, | ||||
50 | function => 'logon', | ||||
51 | context => { ( login => 1, logon => 1 ) }, | ||||
52 | }; | ||||
53 | $Foswiki::cfg{SwitchBoard}{logon} = { | ||||
54 | package => undef, | ||||
55 | function => 'logon', | ||||
56 | context => { ( login => 1, logon => 1 ) }, | ||||
57 | }; | ||||
58 | $Foswiki::cfg{SwitchBoard}{manage} = { | ||||
59 | package => 'Foswiki::UI::Manage', | ||||
60 | function => 'manage', | ||||
61 | context => { manage => 1 }, | ||||
62 | allow => { POST => 1 }, | ||||
63 | }; | ||||
64 | $Foswiki::cfg{SwitchBoard}{oops} = { | ||||
65 | package => 'Foswiki::UI::Oops', | ||||
66 | function => 'oops_cgi', | ||||
67 | context => { oops => 1 }, | ||||
68 | }; | ||||
69 | $Foswiki::cfg{SwitchBoard}{preview} = { | ||||
70 | package => 'Foswiki::UI::Preview', | ||||
71 | function => 'preview', | ||||
72 | context => { preview => 1 }, | ||||
73 | }; | ||||
74 | $Foswiki::cfg{SwitchBoard}{previewauth} = | ||||
75 | $Foswiki::cfg{SwitchBoard}{preview}; | ||||
76 | $Foswiki::cfg{SwitchBoard}{rdiff} = { | ||||
77 | package => 'Foswiki::UI::RDiff', | ||||
78 | function => 'diff', | ||||
79 | context => { diff => 1 }, | ||||
80 | }; | ||||
81 | $Foswiki::cfg{SwitchBoard}{rdiffauth} = $Foswiki::cfg{SwitchBoard}{rdiff}; | ||||
82 | $Foswiki::cfg{SwitchBoard}{register} = { | ||||
83 | package => 'Foswiki::UI::Register', | ||||
84 | function => 'register_cgi', | ||||
85 | context => { register => 1 }, | ||||
86 | |||||
87 | # method verify must allow GET; protect in Foswiki::UI::Register | ||||
88 | #allow => { POST => 1 }, | ||||
89 | }; | ||||
90 | $Foswiki::cfg{SwitchBoard}{rename} = { | ||||
91 | package => 'Foswiki::UI::Rename', | ||||
92 | function => 'rename', | ||||
93 | context => { rename => 1 }, | ||||
94 | |||||
95 | # Rename is 2 stage; protect in Foswiki::UI::Rename | ||||
96 | #allow => { POST => 1 }, | ||||
97 | }; | ||||
98 | $Foswiki::cfg{SwitchBoard}{resetpasswd} = { | ||||
99 | package => 'Foswiki::UI::Passwords', | ||||
100 | function => 'resetPassword', | ||||
101 | context => { resetpasswd => 1 }, | ||||
102 | allow => { POST => 1 }, | ||||
103 | }; | ||||
104 | $Foswiki::cfg{SwitchBoard}{rest} = { | ||||
105 | package => 'Foswiki::UI::Rest', | ||||
106 | function => 'rest', | ||||
107 | context => { rest => 1 }, | ||||
108 | }; | ||||
109 | $Foswiki::cfg{SwitchBoard}{restauth} = $Foswiki::cfg{SwitchBoard}{rest}; | ||||
110 | $Foswiki::cfg{SwitchBoard}{save} = { | ||||
111 | package => 'Foswiki::UI::Save', | ||||
112 | function => 'save', | ||||
113 | context => { save => 1 }, | ||||
114 | allow => { POST => 1 }, | ||||
115 | }; | ||||
116 | $Foswiki::cfg{SwitchBoard}{search} = { | ||||
117 | package => 'Foswiki::UI::Search', | ||||
118 | function => 'search', | ||||
119 | context => { search => 1 }, | ||||
120 | }; | ||||
121 | $Foswiki::cfg{SwitchBoard}{statistics} = { | ||||
122 | package => 'Foswiki::UI::Statistics', | ||||
123 | function => 'statistics', | ||||
124 | context => { statistics => 1 }, | ||||
125 | }; | ||||
126 | $Foswiki::cfg{SwitchBoard}{upload} = { | ||||
127 | package => 'Foswiki::UI::Upload', | ||||
128 | function => 'upload', | ||||
129 | context => { upload => 1 }, | ||||
130 | allow => { POST => 1 }, | ||||
131 | }; | ||||
132 | $Foswiki::cfg{SwitchBoard}{viewfile} = { | ||||
133 | package => 'Foswiki::UI::Viewfile', | ||||
134 | function => 'viewfile', | ||||
135 | context => { viewfile => 1 }, | ||||
136 | }; | ||||
137 | $Foswiki::cfg{SwitchBoard}{viewfileauth} = | ||||
138 | $Foswiki::cfg{SwitchBoard}{viewfile}; | ||||
139 | $Foswiki::cfg{SwitchBoard}{view} = { | ||||
140 | package => 'Foswiki::UI::View', | ||||
141 | function => 'view', | ||||
142 | context => { view => 1 }, | ||||
143 | }; | ||||
144 | $Foswiki::cfg{SwitchBoard}{viewauth} = $Foswiki::cfg{SwitchBoard}{view}; | ||||
145 | |||||
146 | #Monitor::MARK("End of BEGIN block in UI.pm"); | ||||
147 | 1 | 90µs | 1 | 105µs | } # spent 105µs making 1 call to Foswiki::UI::BEGIN@16 |
148 | |||||
149 | 2 | 50µs | 2 | 811µs | # spent 415µs (19+396) within Foswiki::UI::BEGIN@149 which was called:
# once (19µs+396µs) by main::BEGIN@28 at line 149 # spent 415µs making 1 call to Foswiki::UI::BEGIN@149
# spent 396µs making 1 call to Error::import |
150 | 2 | 95µs | 2 | 97µs | # spent 57µs (17+40) within Foswiki::UI::BEGIN@150 which was called:
# once (17µs+40µs) by main::BEGIN@28 at line 150 # spent 57µs making 1 call to Foswiki::UI::BEGIN@150
# spent 40µs making 1 call to Assert::import |
151 | 2 | 42µs | 1 | 10µs | # spent 10µs within Foswiki::UI::BEGIN@151 which was called:
# once (10µs+0s) by main::BEGIN@28 at line 151 # spent 10µs making 1 call to Foswiki::UI::BEGIN@151 |
152 | |||||
153 | 2 | 40µs | 1 | 9µs | # spent 9µs within Foswiki::UI::BEGIN@153 which was called:
# once (9µs+0s) by main::BEGIN@28 at line 153 # spent 9µs making 1 call to Foswiki::UI::BEGIN@153 |
154 | 2 | 40µs | 1 | 9µs | # spent 9µs within Foswiki::UI::BEGIN@154 which was called:
# once (9µs+0s) by main::BEGIN@28 at line 154 # spent 9µs making 1 call to Foswiki::UI::BEGIN@154 |
155 | 2 | 40µs | 1 | 10µs | # spent 10µs within Foswiki::UI::BEGIN@155 which was called:
# once (10µs+0s) by main::BEGIN@28 at line 155 # spent 10µs making 1 call to Foswiki::UI::BEGIN@155 |
156 | 2 | 37µs | 1 | 9µs | # spent 9µs within Foswiki::UI::BEGIN@156 which was called:
# once (9µs+0s) by main::BEGIN@28 at line 156 # spent 9µs making 1 call to Foswiki::UI::BEGIN@156 |
157 | 2 | 186µs | 1 | 516µs | # spent 516µs (430+85) within Foswiki::UI::BEGIN@157 which was called:
# once (430µs+85µs) by main::BEGIN@28 at line 157 # spent 516µs making 1 call to Foswiki::UI::BEGIN@157 |
158 | 2 | 48µs | 1 | 10µs | # spent 10µs within Foswiki::UI::BEGIN@158 which was called:
# once (10µs+0s) by main::BEGIN@28 at line 158 # spent 10µs making 1 call to Foswiki::UI::BEGIN@158 |
159 | 2 | 37µs | 1 | 15µs | # spent 15µs within Foswiki::UI::BEGIN@159 which was called:
# once (15µs+0s) by main::BEGIN@28 at line 159 # spent 15µs making 1 call to Foswiki::UI::BEGIN@159 |
160 | 2 | 174µs | 1 | 2.75ms | # spent 2.75ms (2.48+269µs) within Foswiki::UI::BEGIN@160 which was called:
# once (2.48ms+269µs) by main::BEGIN@28 at line 160 # spent 2.75ms making 1 call to Foswiki::UI::BEGIN@160 |
161 | |||||
162 | # Used to lazily load UI handler modules | ||||
163 | 1 | 3µs | our %isInitialized = (); | ||
164 | |||||
165 | 2 | 2.97ms | 2 | 328µs | # spent 175µs (22+153) within Foswiki::UI::BEGIN@165 which was called:
# once (22µs+153µs) by main::BEGIN@28 at line 165 # spent 175µs making 1 call to Foswiki::UI::BEGIN@165
# spent 153µs making 1 call to constant::import |
166 | |||||
167 | =begin TML | ||||
168 | |||||
169 | ---++ StaticMethod handleRequest($req) -> $res | ||||
170 | |||||
171 | Main coordinator of request-process-response cycle. | ||||
172 | |||||
173 | =cut | ||||
174 | |||||
175 | # spent 265s (191µs+265) within Foswiki::UI::handleRequest which was called:
# once (191µs+265s) by Foswiki::Engine::CGI::run at line 41 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Engine/CGI.pm | ||||
176 | 17 | 108µs | my $req = shift; | ||
177 | |||||
178 | my $res; | ||||
179 | 1 | 8µs | my $dispatcher = $Foswiki::cfg{SwitchBoard}{ $req->action() }; # spent 8µs making 1 call to Foswiki::Request::action | ||
180 | unless ( defined $dispatcher ) { | ||||
181 | $res = new Foswiki::Response(); | ||||
182 | $res->header( -type => 'text/html', -status => '404' ); | ||||
183 | my $html = CGI::start_html('404 Not Found'); | ||||
184 | $html .= CGI::h1( {}, 'Not Found' ); | ||||
185 | $html .= CGI::p( {}, | ||||
186 | "The requested URL " | ||||
187 | . $req->uri | ||||
188 | . " was not found on this server." ); | ||||
189 | $html .= CGI::end_html(); | ||||
190 | $res->print($html); | ||||
191 | return $res; | ||||
192 | } | ||||
193 | |||||
194 | if ( ref($dispatcher) eq 'ARRAY' ) { | ||||
195 | |||||
196 | # Old-style array entry in switchboard from a plugin | ||||
197 | my @array = @$dispatcher; | ||||
198 | $dispatcher = { | ||||
199 | package => $array[0], | ||||
200 | function => $array[1], | ||||
201 | context => $array[2], | ||||
202 | }; | ||||
203 | } | ||||
204 | |||||
205 | 3 | 64µs | if ( $dispatcher->{package} && !$isInitialized{ $dispatcher->{package} } ) { | ||
206 | eval qq(use $dispatcher->{package}); # spent 158µs executing statements in string eval # includes 3.61ms spent executing 1 call to 1 sub defined therein. | ||||
207 | die $@ if $@; | ||||
208 | $isInitialized{ $dispatcher->{package} } = 1; | ||||
209 | } | ||||
210 | |||||
211 | my $sub; | ||||
212 | $sub = $dispatcher->{package} . '::' if $dispatcher->{package}; | ||||
213 | $sub .= $dispatcher->{function}; | ||||
214 | |||||
215 | # Get the params cache from the path | ||||
216 | 1 | 64µs | my $cache = $req->param('foswiki_redirect_cache'); # spent 64µs making 1 call to Foswiki::Request::param | ||
217 | if ( defined $cache ) { | ||||
218 | $req->delete('foswiki_redirect_cache'); | ||||
219 | } | ||||
220 | |||||
221 | # If the path specifies a cache path, use that. It's arbitrary | ||||
222 | # as to which takes precedence (param or path) because we should | ||||
223 | # never have both at once. | ||||
224 | 1 | 7µs | my $path_info = $req->path_info(); # spent 7µs making 1 call to Foswiki::Request::pathInfo | ||
225 | 1 | 3µs | if ( $path_info =~ s#/foswiki_redirect_cache/([a-f0-9]{32})## ) { # spent 3µs making 1 call to Foswiki::UI::CORE:subst | ||
226 | $cache = $1; | ||||
227 | $req->path_info($path_info); | ||||
228 | } | ||||
229 | |||||
230 | if ( defined $cache && $cache =~ /^([a-f0-9]{32})$/ ) { | ||||
231 | require Foswiki::Request::Cache; | ||||
232 | |||||
233 | # implicit untaint required, because $cache may be used in a filename. | ||||
234 | # Note that the cache serialises the method and path_info, which | ||||
235 | # will be restored. | ||||
236 | Foswiki::Request::Cache->new()->load( $1, $req ); | ||||
237 | } | ||||
238 | |||||
239 | if (TRACE_REQUEST) { | ||||
240 | print STDERR "INCOMING " | ||||
241 | . $req->method() . " " | ||||
242 | . $req->url . " -> " | ||||
243 | . $sub . "\n"; | ||||
244 | print STDERR "validation_key: " | ||||
245 | . ( $req->param('validation_key') || 'no key' ) . "\n"; | ||||
246 | |||||
247 | #require Data::Dumper; | ||||
248 | #print STDERR Data::Dumper->Dump([$req]); | ||||
249 | } | ||||
250 | |||||
251 | 2 | 11µs | if ( UNIVERSAL::isa( $Foswiki::engine, 'Foswiki::Engine::CLI' ) ) { # spent 6µs making 1 call to Foswiki::Request::method
# spent 5µs making 1 call to UNIVERSAL::isa | ||
252 | $dispatcher->{context}->{command_line} = 1; | ||||
253 | } | ||||
254 | elsif ( | ||||
255 | defined $req->method() | ||||
256 | && ( | ||||
257 | ( | ||||
258 | defined $dispatcher->{allow} | ||||
259 | && !$dispatcher->{allow}->{ uc( $req->method() ) } | ||||
260 | ) | ||||
261 | || ( defined $dispatcher->{deny} | ||||
262 | && $dispatcher->{deny}->{ uc( $req->method() ) } ) | ||||
263 | ) | ||||
264 | ) | ||||
265 | { | ||||
266 | $res = new Foswiki::Response(); | ||||
267 | $res->header( -type => 'text/html', -status => '405' ); | ||||
268 | $res->print( 'Bad Request: ' | ||||
269 | . uc( $req->method() ) | ||||
270 | . ' denied for ' | ||||
271 | . $req->action() ); | ||||
272 | return $res; | ||||
273 | } | ||||
274 | 1 | 2µs | 1 | 265s | $res = _execute( $req, \&$sub, %{ $dispatcher->{context} } ); # spent 265s making 1 call to Foswiki::UI::_execute |
275 | return $res; | ||||
276 | } | ||||
277 | |||||
278 | =begin TML | ||||
279 | |||||
280 | ---++ StaticMethod _execute($req, $sub, %initialContext) -> $res | ||||
281 | |||||
282 | Creates a Foswiki session object with %initalContext and calls | ||||
283 | $sub method. Returns the Foswiki::Response object. | ||||
284 | |||||
285 | =cut | ||||
286 | |||||
287 | # spent 265s (305µs+265) within Foswiki::UI::_execute which was called:
# once (305µs+265s) by Foswiki::UI::handleRequest at line 274 | ||||
288 | 6 | 287µs | my ( $req, $sub, %initialContext ) = @_; | ||
289 | |||||
290 | my $session; | ||||
291 | my $res; | ||||
292 | |||||
293 | # If we get a known exception from new Foswiki(), then it must have | ||||
294 | # come from one of the plugin handlers, which are initialised at this | ||||
295 | # time (initPlugin, earlyInitPlugin for example). In this case the | ||||
296 | # setup of the Foswiki object is pretty much complete; we can safely | ||||
297 | # recover it from $Foswiki::Plugins::SESSION and clean it up. | ||||
298 | # Error::Simple and EngineException indicate something more | ||||
299 | # basic, however, that we can't clean up. | ||||
300 | # spent 265s (95µs+265) within Foswiki::UI::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/UI.pm:318] which was called:
# once (95µs+265s) by Error::subs::try at line 416 of Error.pm | ||||
301 | |||||
302 | # DO NOT pass in $req->remoteUser here (even though it appears to be right) | ||||
303 | # because it may occlude the login manager. Exception is when running in | ||||
304 | # CLI environment. | ||||
305 | |||||
306 | 3 | 43µs | 1 | 81.8s | $session = new Foswiki( # spent 81.8s making 1 call to Foswiki::new |
307 | ( defined $ENV{GATEWAY_INTERFACE} || defined $ENV{MOD_PERL} ) | ||||
308 | ? undef | ||||
309 | : $req->remoteUser(), | ||||
310 | $req, \%initialContext | ||||
311 | ); | ||||
312 | |||||
313 | $res = $session->{response}; | ||||
314 | 2 | 50µs | 1 | 15µs | unless ( defined $res->status() && $res->status() =~ /^\s*3\d\d/ ) { # spent 15µs making 1 call to Foswiki::Response::status |
315 | 2 | 85µs | $session->getLoginManager()->checkAccess(); # spent 54µs making 1 call to Foswiki::LoginManager::checkAccess
# spent 30µs making 1 call to Foswiki::getLoginManager | ||
316 | 1 | 184s | &$sub($session); # spent 184s making 1 call to Foswiki::UI::View::view | ||
317 | } | ||||
318 | } | ||||
319 | catch Foswiki::ValidationException with { | ||||
320 | my $e = shift; | ||||
321 | |||||
322 | $session ||= $Foswiki::Plugins::SESSION; | ||||
323 | $res = $session->{response} if $session; | ||||
324 | $res ||= new Foswiki::Response(); | ||||
325 | |||||
326 | my $query = $session->{request}; | ||||
327 | |||||
328 | # Cache the original query, so we can complete if if it is | ||||
329 | # confirmed | ||||
330 | require Foswiki::Request::Cache; | ||||
331 | my $uid = Foswiki::Request::Cache->new()->save($query); | ||||
332 | |||||
333 | print STDERR "ValidationException: redirect with $uid\n" | ||||
334 | if DEBUG; | ||||
335 | |||||
336 | # We use the login script for validation because it already | ||||
337 | # has the correct criteria in httpd.conf for Apache login. | ||||
338 | # URL is absolute as required by | ||||
339 | # http://tools.ietf.org/html/rfc2616#section-14.30 | ||||
340 | my $url = $session->getScriptUrl( | ||||
341 | 1, 'login', | ||||
342 | $session->{webName}, $session->{topicName}, | ||||
343 | foswikiloginaction => 'validate', | ||||
344 | foswikioriginalquery => $uid | ||||
345 | ); | ||||
346 | |||||
347 | $session->redirect($url); # no passthrough | ||||
348 | } | ||||
349 | catch Foswiki::AccessControlException with { | ||||
350 | my $e = shift; | ||||
351 | |||||
352 | $session ||= $Foswiki::Plugins::SESSION; | ||||
353 | $res = $session->{response} if $session; | ||||
354 | $res ||= new Foswiki::Response(); | ||||
355 | |||||
356 | unless ( $session->getLoginManager()->forceAuthentication() ) { | ||||
357 | |||||
358 | # Login manager did not want to authenticate, perhaps because | ||||
359 | # we are already authenticated. | ||||
360 | my $exception = new Foswiki::OopsException( | ||||
361 | 'accessdenied', | ||||
362 | status => 403, | ||||
363 | web => $e->{web}, | ||||
364 | topic => $e->{topic}, | ||||
365 | def => 'topic_access', | ||||
366 | params => [ $e->{mode}, $e->{reason} ] | ||||
367 | ); | ||||
368 | |||||
369 | $exception->generate($session); | ||||
370 | } | ||||
371 | } | ||||
372 | catch Foswiki::OopsException with { | ||||
373 | my $e = shift; | ||||
374 | |||||
375 | $session ||= $Foswiki::Plugins::SESSION; | ||||
376 | $res = $session->{response} if $session; | ||||
377 | $res ||= new Foswiki::Response(); | ||||
378 | |||||
379 | $e->generate($session); | ||||
380 | } | ||||
381 | catch Foswiki::EngineException with { | ||||
382 | my $e = shift; | ||||
383 | my $res = $e->{response}; | ||||
384 | unless ( defined $res ) { | ||||
385 | $res = new Foswiki::Response(); | ||||
386 | $res->header( -type => 'text/html', -status => $e->{status} ); | ||||
387 | my $html = CGI::start_html( $e->{status} . ' Bad Request' ); | ||||
388 | $html .= CGI::h1( {}, 'Bad Request' ); | ||||
389 | $html .= CGI::p( {}, $e->{reason} ); | ||||
390 | $html .= CGI::end_html(); | ||||
391 | $res->print($html); | ||||
392 | } | ||||
393 | $Foswiki::engine->finalizeError( $res, $session->{request} ); | ||||
394 | return $e->{status}; | ||||
395 | } | ||||
396 | catch Error::Simple with { | ||||
397 | |||||
398 | # Most usually a 'die' | ||||
399 | my $e = shift; | ||||
400 | |||||
401 | $session ||= $Foswiki::Plugins::SESSION; | ||||
402 | $res = $session->{response} if $session; | ||||
403 | $res ||= new Foswiki::Response(); | ||||
404 | |||||
405 | $res->header( -type => 'text/plain' ) | ||||
406 | unless $res->outputHasStarted(); | ||||
407 | if (DEBUG) { | ||||
408 | |||||
409 | # output the full message and stacktrace to the browser | ||||
410 | $res->print( $e->stringify() ); | ||||
411 | } | ||||
412 | else { | ||||
413 | my $mess = $e->stringify(); | ||||
414 | print STDERR $mess; | ||||
415 | $session->logger->log( 'warning', $mess ) if $session; | ||||
416 | |||||
417 | # tell the browser where to look for more help | ||||
418 | my $text = | ||||
419 | 'Foswiki detected an internal error - please check your Foswiki logs and webserver logs for more information.' | ||||
420 | . "\n\n"; | ||||
421 | $mess =~ s/ at .*$//s; | ||||
422 | |||||
423 | # cut out pathnames from public announcement | ||||
424 | $mess =~ s#/[\w./]+#path#g unless DEBUG; | ||||
425 | $text .= $mess; | ||||
426 | $res->print($text); | ||||
427 | } | ||||
428 | } | ||||
429 | otherwise { | ||||
430 | |||||
431 | # Aargh! Should never get here | ||||
432 | $res = new Foswiki::Response; | ||||
433 | $res->header( -type => 'text/plain' ); | ||||
434 | $res->print("Unspecified error"); | ||||
435 | 12 | 265s | }; # spent 265s making 1 call to Error::subs::try
# spent 59µs making 5 calls to Error::catch, avg 12µs/call
# spent 20µs making 5 calls to Error::subs::with, avg 4µs/call
# spent 14µs making 1 call to Error::subs::otherwise | ||
436 | 1 | 8.04ms | $session->finish() if $session; # spent 8.04ms making 1 call to Foswiki::finish | ||
437 | |||||
438 | return $res; | ||||
439 | } | ||||
440 | |||||
441 | =begin TML | ||||
442 | |||||
443 | ---++ StaticMethod logon($session) | ||||
444 | |||||
445 | Handler for "logon" action. | ||||
446 | * =$session= is a Foswiki session object | ||||
447 | |||||
448 | =cut | ||||
449 | |||||
450 | sub logon { | ||||
451 | my $session = shift; | ||||
452 | |||||
453 | my $action = $session->{request}->param('foswikiloginaction'); | ||||
454 | $session->{request}->delete('foswikiloginaction'); | ||||
455 | |||||
456 | if ( defined $action && $action eq 'validate' ) { | ||||
457 | Foswiki::Validation::validate($session); | ||||
458 | } | ||||
459 | else { | ||||
460 | $session->getLoginManager()->login( $session->{request}, $session ); | ||||
461 | } | ||||
462 | } | ||||
463 | |||||
464 | =begin TML | ||||
465 | |||||
466 | ---++ StaticMethod checkWebExists( $session, $web, $op ) | ||||
467 | |||||
468 | Check if the web exists. If it doesn't, will throw an oops exception. | ||||
469 | $op is the user operation being performed. | ||||
470 | |||||
471 | =cut | ||||
472 | |||||
473 | # spent 254µs (29+225) within Foswiki::UI::checkWebExists which was called:
# once (29µs+225µs) by Foswiki::UI::View::view at line 99 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/UI/View.pm | ||||
474 | 3 | 23µs | my ( $session, $webName, $op ) = @_; | ||
475 | 1 | 4µs | ASSERT( $session->isa('Foswiki') ) if DEBUG; # spent 4µs making 1 call to Assert::ASSERTS_OFF | ||
476 | |||||
477 | 1 | 222µs | unless ( $session->webExists($webName) ) { # spent 222µs making 1 call to Foswiki::webExists | ||
478 | throw Foswiki::OopsException( | ||||
479 | 'accessdenied', | ||||
480 | status => 404, | ||||
481 | def => 'no_such_web', | ||||
482 | web => $webName, | ||||
483 | topic => $Foswiki::cfg{WebPrefsTopicName}, | ||||
484 | params => [$op] | ||||
485 | ); | ||||
486 | } | ||||
487 | } | ||||
488 | |||||
489 | =begin TML | ||||
490 | |||||
491 | ---++ StaticMethod topicExists( $session, $web, $topic, $op ) => boolean | ||||
492 | |||||
493 | Check if the given topic exists, throwing an OopsException | ||||
494 | if it doesn't. $op is the user operation being performed. | ||||
495 | |||||
496 | =cut | ||||
497 | |||||
498 | sub checkTopicExists { | ||||
499 | my ( $session, $web, $topic, $op ) = @_; | ||||
500 | ASSERT( $session->isa('Foswiki') ) if DEBUG; | ||||
501 | |||||
502 | unless ( $session->topicExists( $web, $topic ) ) { | ||||
503 | throw Foswiki::OopsException( | ||||
504 | 'accessdenied', | ||||
505 | status => 404, | ||||
506 | def => 'no_such_topic', | ||||
507 | web => $web, | ||||
508 | topic => $topic, | ||||
509 | params => [$op] | ||||
510 | ); | ||||
511 | } | ||||
512 | } | ||||
513 | |||||
514 | =begin TML | ||||
515 | |||||
516 | ---++ StaticMethod checkAccess( $session, $mode, $topicObject ) | ||||
517 | |||||
518 | Check if the given mode of access by the given user to the given | ||||
519 | web.topic is permissible, throwing a Foswiki::AccessControlException if not. | ||||
520 | |||||
521 | =cut | ||||
522 | |||||
523 | # spent 2.31ms (27µs+2.28) within Foswiki::UI::checkAccess which was called:
# once (27µs+2.28ms) by Foswiki::UI::View::view at line 116 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/UI/View.pm | ||||
524 | 3 | 26µs | my ( $session, $mode, $topicObject ) = @_; | ||
525 | 1 | 3µs | ASSERT( $session->isa('Foswiki') ) if DEBUG; # spent 3µs making 1 call to Assert::ASSERTS_OFF | ||
526 | |||||
527 | 1 | 2.28ms | unless ( $topicObject->haveAccess($mode) ) { # spent 2.28ms making 1 call to Foswiki::Meta::haveAccess | ||
528 | throw Foswiki::AccessControlException( $mode, $session->{user}, | ||||
529 | $topicObject->web, $topicObject->topic, $Foswiki::Meta::reason ); | ||||
530 | } | ||||
531 | } | ||||
532 | |||||
533 | =begin TML | ||||
534 | |||||
535 | ---++ StaticMethod checkValidationKey( $session ) | ||||
536 | |||||
537 | Check the validation key for the given action. Throws an exception | ||||
538 | if the validation key isn't valid (handled in _execute(), above) | ||||
539 | * =$session= - the current session object | ||||
540 | |||||
541 | See Foswiki::Validation for more information. | ||||
542 | |||||
543 | =cut | ||||
544 | |||||
545 | sub checkValidationKey { | ||||
546 | my ($session) = @_; | ||||
547 | |||||
548 | # If validation is disabled, do nothing | ||||
549 | return if ( $Foswiki::cfg{Validation}{Method} eq 'none' ); | ||||
550 | |||||
551 | # No point in command-line mode | ||||
552 | return if $session->inContext('command_line'); | ||||
553 | |||||
554 | # Check the nonce before we do anything else | ||||
555 | my $nonce = $session->{request}->param('validation_key'); | ||||
556 | $session->{request}->delete('validation_key'); | ||||
557 | if ( !defined($nonce) | ||||
558 | || !Foswiki::Validation::isValidNonce( $session->getCGISession(), | ||||
559 | $nonce ) ) | ||||
560 | { | ||||
561 | throw Foswiki::ValidationException( $session->{request}->action() ); | ||||
562 | } | ||||
563 | if ( defined($nonce) ) { | ||||
564 | |||||
565 | # Expire the nonce. If the user tries to use it again, they will | ||||
566 | # be prompted. | ||||
567 | Foswiki::Validation::expireValidationKeys( $session->getCGISession(), | ||||
568 | $Foswiki::cfg{Validation}{ExpireKeyOnUse} ? $nonce : undef ); | ||||
569 | } | ||||
570 | } | ||||
571 | |||||
572 | =begin TML | ||||
573 | |||||
574 | ---++ StaticMethod run( $method, %context ) | ||||
575 | |||||
576 | Supported for bin scripts that were written for Foswiki < 1.0. The parameters | ||||
577 | are a function reference to the UI method to call and initial context. | ||||
578 | |||||
579 | In Foswiki >= 1.0 it should be replaced by a Config.spec entry such as: | ||||
580 | |||||
581 | # **PERL H** | ||||
582 | # Bin script registration - do not modify | ||||
583 | $Foswiki::cfg{SwitchBoard}{publish} = [ "Foswiki::Contrib::Publish", "publish", { publishing => 1 } ]; | ||||
584 | |||||
585 | =cut | ||||
586 | |||||
587 | sub run { | ||||
588 | my ( $method, %context ) = @_; | ||||
589 | |||||
590 | if ( UNIVERSAL::isa( $Foswiki::engine, 'Foswiki::Engine::CLI' ) ) { | ||||
591 | $context{command_line} = 1; | ||||
592 | } | ||||
593 | _execute( Foswiki::Request->new(), $method, %context ); | ||||
594 | } | ||||
595 | |||||
596 | 1 | 6µs | 1; | ||
597 | __END__ | ||||
# spent 3µs within Foswiki::UI::CORE:subst which was called:
# once (3µs+0s) by Foswiki::UI::handleRequest at line 225 |