blib/lib/CGI/XMLApplication.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 17 | 216 | 7.8 |
branch | 0 | 80 | 0.0 |
condition | 0 | 26 | 0.0 |
subroutine | 5 | 36 | 13.8 |
pod | 23 | 33 | 69.7 |
total | 45 | 391 | 11.5 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package CGI::XMLApplication; | ||||||
2 | |||||||
3 | # ################################################################ | ||||||
4 | # | ||||||
5 | # (c) 2001 Christian Glahn |
||||||
6 | # | ||||||
7 | # This code is free software; you can redistribute it and/or | ||||||
8 | # modify it under the same terms as Perl itself. | ||||||
9 | # | ||||||
10 | # ################################################################ | ||||||
11 | |||||||
12 | ## | ||||||
13 | # CGI::XMLApplication - Application Module for CGI scripts | ||||||
14 | |||||||
15 | # ################################################################ | ||||||
16 | # module loading and global variable initializing | ||||||
17 | # ################################################################ | ||||||
18 | 1 | 1 | 7418 | use strict; | |||
1 | 3 | ||||||
1 | 35 | ||||||
19 | |||||||
20 | 1 | 1 | 18970 | use CGI; | |||
1 | 47674 | ||||||
1 | 8 | ||||||
21 | 1 | 1 | 87 | use Carp; | |||
1 | 7 | ||||||
1 | 3354 | ||||||
22 | #use Data::Dumper; | ||||||
23 | |||||||
24 | # ################################################################ | ||||||
25 | # inheritance | ||||||
26 | # ################################################################ | ||||||
27 | @CGI::XMLApplication::ISA = qw( CGI ); | ||||||
28 | |||||||
29 | # ################################################################ | ||||||
30 | |||||||
31 | $CGI::XMLApplication::VERSION = "1.1.5"; | ||||||
32 | |||||||
33 | # ################################################################ | ||||||
34 | # general configuration | ||||||
35 | # ################################################################ | ||||||
36 | |||||||
37 | # some hardcoded error messages, the application has always, e.g. | ||||||
38 | # to tell that a stylesheet is missing | ||||||
39 | @CGI::XMLApplication::panic = ( | ||||||
40 | 'No Stylesheet specified! ', | ||||||
41 | 'Stylesheet is not available! ', | ||||||
42 | 'Event not implemented', | ||||||
43 | 'Application Error', | ||||||
44 | ); | ||||||
45 | |||||||
46 | # The Debug Level for verbose error messages | ||||||
47 | $CGI::XMLApplication::DEBUG = 0; | ||||||
48 | |||||||
49 | # ################################################################ | ||||||
50 | # methods | ||||||
51 | # ################################################################ | ||||||
52 | sub new { | ||||||
53 | 1 | 1 | 1 | 111 | my $class = shift; | ||
54 | 1 | 13 | my $self = $class->SUPER::new( @_ ); | ||||
55 | 1 | 245 | bless $self, $class; | ||||
56 | |||||||
57 | 1 | 6 | $self->{XML_CGIAPP_HANDLER_} = [$self->registerEvents()]; | ||||
58 | 1 | 3 | $self->{XML_CGIAPP_STYLESHEET_} = []; | ||||
59 | 1 | 4 | $self->{XML_CGIAPP_STYLESDIR_} = ''; | ||||
60 | |||||||
61 | 1 | 2 | return $self; | ||||
62 | } | ||||||
63 | |||||||
64 | # ################################################################ | ||||||
65 | # straight forward coded methods | ||||||
66 | |||||||
67 | # application related ############################################ | ||||||
68 | # both functions are only for backward compatibilty with older scripts | ||||||
69 | sub debug_msg { | ||||||
70 | 0 | 0 | 0 | 0 | my $level = shift; | ||
71 | 0 | 0 | 0 | 0 | if ( $level <= $CGI::XMLApplication::DEBUG && scalar @_ ) { | ||
72 | 0 | 0 | my ($module, undef, $line) = caller(1); | ||||
73 | 0 | 0 | warn "[$module; line: $line] ", join(' ', @_) , "\n"; | ||||
74 | } | ||||||
75 | } | ||||||
76 | |||||||
77 | ## | ||||||
78 | # dummy functions | ||||||
79 | # | ||||||
80 | # each function is required to be overwritten by any class inheritated | ||||||
81 | 1 | 1 | 1 | 5 | sub registerEvents { return (); } | ||
82 | |||||||
83 | # all following function will recieve the context, too | ||||||
84 | 0 | 0 | 1 | sub getDOM { return undef; } | |||
85 | 0 | 0 | 0 | sub requestDOM { return undef; } # old style use getDOM! | |||
86 | |||||||
87 | 0 | 0 | 0 | sub getStylesheetString { return ""; } # return a XSL String | |||
88 | 0 | 0 | 1 | sub getStylesheet { return ""; } # returns either name of a stylesheetfile or the xsl DOM | |||
89 | 0 | 0 | 1 | sub selectStylesheet { return ""; } # old style getStylesheet | |||
90 | |||||||
91 | 0 | 0 | 0 | sub getXSLParameter { return (); } # should return a plain hash of parameters passed to xsl | |||
92 | 0 | 0 | 1 | sub setHttpHeader { return (); } # should return a hash of header | |||
93 | |||||||
94 | sub skipSerialization{ | ||||||
95 | 0 | 0 | 1 | my $self = shift; | |||
96 | 0 | 0 | $self->{CGI_XMLAPP_SKIP_TRANSFORM} = shift if scalar @_; | ||||
97 | 0 | return $self->{CGI_XMLAPP_SKIP_TRANSFORM}; | |||||
98 | } | ||||||
99 | |||||||
100 | # returns boolean | ||||||
101 | sub passthru { | ||||||
102 | 0 | 0 | 1 | my $self = shift; | |||
103 | 0 | 0 | if ( scalar @_ ) { | ||||
0 | |||||||
104 | 0 | $self->{CGI_XMLAPP_PASSXML} = shift; | |||||
105 | 0 | $self->delete( 'passthru' ); # delete any passthru parameter | |||||
106 | } | ||||||
107 | elsif ( defined $self->param( "passthru" ) ) { | ||||||
108 | 0 | $self->{CGI_XMLAPP_PASSXML} = 1 ; | |||||
109 | 0 | $self->delete( 'passthru' ); | |||||
110 | } | ||||||
111 | 0 | return $self->{CGI_XMLAPP_PASSXML}; | |||||
112 | } | ||||||
113 | |||||||
114 | sub redirectToURI { | ||||||
115 | 0 | 0 | 0 | my $self = shift; | |||
116 | 0 | 0 | $self->{CGI_XMLAPP_REDIRECT} = shift if scalar @_; | ||||
117 | 0 | return $self->{CGI_XMLAPP_REDIRECT}; | |||||
118 | } | ||||||
119 | |||||||
120 | # ################################################################ | ||||||
121 | # content related functions | ||||||
122 | |||||||
123 | # stylesheet directory information ############################### | ||||||
124 | 0 | 0 | 1 | sub setStylesheetDir { $_[0]->{XML_CGIAPP_STYLESDIR_} = $_[1];} | |||
125 | 0 | 0 | 1 | sub setStylesheetPath { $_[0]->{XML_CGIAPP_STYLESDIR_} = $_[1];} | |||
126 | 0 | 0 | 0 | sub getStylesheetDir { $_[0]->{XML_CGIAPP_STYLESDIR_}; } | |||
127 | 0 | 0 | 1 | sub getStylesheetPath { $_[0]->{XML_CGIAPP_STYLESDIR_}; } | |||
128 | |||||||
129 | # event control ################################################### | ||||||
130 | |||||||
131 | 0 | 0 | 0 | sub addEvent { my $s=shift; push @{$s->{XML_CGIAPP_HANDLER_}}, @_;} | |||
0 | |||||||
0 | |||||||
132 | |||||||
133 | 0 | 0 | 0 | sub getEventList { @{ $_[0]->{XML_CGIAPP_HANDLER_} }; } | |||
0 | |||||||
134 | 0 | 0 | 1 | sub testEvent { return $_[0]->checkPush( $_[0]->getEventList() ); } | |||
135 | |||||||
136 | sub deleteEvent { | ||||||
137 | 0 | 0 | 0 | my $self = shift; | |||
138 | 0 | 0 | if ( scalar @_ ){ # delete explicit events | ||||
139 | 0 | foreach ( @_ ) { | |||||
140 | 0 | debug_msg( 8, "[XML::CGIApplication] delete event $_" ); | |||||
141 | 0 | $self->delete( $_ ); | |||||
142 | 0 | $self->delete( $_.'.x' ); | |||||
143 | 0 | $self->delete( $_.'.y' ); | |||||
144 | } | ||||||
145 | } | ||||||
146 | else { # delete all | ||||||
147 | 0 | foreach ( @{ $self->{XML_CGIAPP_HANDLER_} } ){ | |||||
0 | |||||||
148 | 0 | debug_msg( 8, "delete event $_" ); | |||||
149 | 0 | $self->delete( $_ ); | |||||
150 | 0 | $self->delete( $_.'.x' ); | |||||
151 | 0 | $self->delete( $_.'.y' ); | |||||
152 | } | ||||||
153 | } | ||||||
154 | } | ||||||
155 | |||||||
156 | sub sendEvent { | ||||||
157 | 0 | 0 | 1 | debug_msg( 10, "send event " . $_[1] ); | |||
158 | 0 | $_[0]->deleteEvent(); | |||||
159 | 0 | $_[0]->param( -name=>$_[1] , -value=>1 ); | |||||
160 | } | ||||||
161 | |||||||
162 | # error handling ################################################# | ||||||
163 | # for internal use only ... | ||||||
164 | 0 | 0 | 1 | sub setPanicMsg { $_[0]->{XML_CGIAPP_PANIC_} = $_[1] } | |||
165 | 0 | 0 | 1 | sub getPanicMsg { $_[0]->{XML_CGIAPP_PANIC_} } | |||
166 | |||||||
167 | # ################################################################ | ||||||
168 | # predefined events | ||||||
169 | |||||||
170 | # default event handler prototypes | ||||||
171 | 0 | 1 | sub event_init {} | ||||
172 | 0 | 1 | sub event_exit {} | ||||
173 | 0 | 0 | 1 | sub event_default { return 0 } | |||
174 | |||||||
175 | # ################################################################ | ||||||
176 | # CGI specific helper functions | ||||||
177 | |||||||
178 | # this is required by the eventhandling | ||||||
179 | sub checkPush { | ||||||
180 | 0 | 0 | 1 | my $self = shift; | |||
181 | my ( $pushed ) = grep { | ||||||
182 | 0 | 0 | defined $self->param( $_ ) || defined $self->param( $_.'.x') | ||||
0 | |||||||
183 | } @_; | ||||||
184 | 0 | 0 | $pushed =~ s/\.x$//i if defined $pushed; | ||||
185 | 0 | return $pushed; | |||||
186 | } | ||||||
187 | |||||||
188 | # helper functions which were missing in CGI.pm | ||||||
189 | sub checkFields{ | ||||||
190 | 0 | 0 | 1 | my $self = shift; | |||
191 | my @missing = grep { | ||||||
192 | 0 | 0 | not length $self->param( $_ ) || $self->param( $_ ) =~ /^\s*$/ | ||||
0 | |||||||
193 | } @_; | ||||||
194 | 0 | 0 | return wantarray ? @missing : ( scalar(@missing) > 0 ? undef : 1 ); | ||||
0 | |||||||
195 | } | ||||||
196 | |||||||
197 | sub getParamHash { | ||||||
198 | 0 | 0 | 1 | my $self = shift; | |||
199 | 0 | my $ptrHash = $self->Vars; | |||||
200 | 0 | my $ptrRV = {}; | |||||
201 | |||||||
202 | 0 | foreach my $k ( keys( %{$ptrHash} ) ){ | |||||
0 | |||||||
203 | 0 | 0 | 0 | next unless exists $ptrHash->{$_} && $ptrHash->{$_} !~ /^[\s\0]*$/; | |||
204 | 0 | $ptrRV->{$k} = $ptrHash->{$k}; | |||||
205 | } | ||||||
206 | |||||||
207 | 0 | 0 | return wantarray ? %{$ptrRV} : $ptrRV; | ||||
0 | |||||||
208 | } | ||||||
209 | |||||||
210 | # ################################################################ | ||||||
211 | # application related methods | ||||||
212 | # ################################################################ | ||||||
213 | # algorithm should be | ||||||
214 | # event registration | ||||||
215 | # app init | ||||||
216 | # event handling | ||||||
217 | # app exit | ||||||
218 | # serialization and output | ||||||
219 | # error handling | ||||||
220 | sub run { | ||||||
221 | 0 | 0 | 1 | my $self = shift; | |||
222 | 0 | my $sid = -1; | |||||
223 | 0 | 0 | 0 | my $ctxt = (!@_ or scalar(@_) > 1) ? {@_} : shift; # nothing, hash or context object | |||
224 | |||||||
225 | 0 | $self->event_init($ctxt); | |||||
226 | |||||||
227 | 0 | 0 | if ( my $n = $self->testEvent($ctxt) ) { | ||||
228 | 0 | 0 | if ( my $func = $self->can('event_'.$n) ) { | ||||
229 | 0 | $sid = $self->$func($ctxt); | |||||
230 | } | ||||||
231 | else { | ||||||
232 | 0 | $sid = -3; | |||||
233 | } | ||||||
234 | } | ||||||
235 | |||||||
236 | 0 | 0 | if ( $sid == -1 ){ | ||||
237 | 0 | $sid = $self->event_default($ctxt); | |||||
238 | } | ||||||
239 | |||||||
240 | 0 | $self->event_exit($ctxt); | |||||
241 | |||||||
242 | # if we allready panic, don't try to render | ||||||
243 | 0 | 0 | if ( $sid >= 0 ) { | ||||
244 | # check if we wanna redirect | ||||||
245 | 0 | 0 | if ( my $uri = $self->redirectToURI() ) { | ||||
0 | |||||||
246 | 0 | my %h = $self->setHttpHeader( $ctxt ); | |||||
247 | 0 | $h{-uri} = $uri; | |||||
248 | 0 | print $self->SUPER::redirect( %h ) . "\n\n"; | |||||
249 | } | ||||||
250 | elsif ( not $self->skipSerialization() ) { | ||||||
251 | # sometimes it is nessecary to skip the serialization | ||||||
252 | # eg. due passing binary data. | ||||||
253 | 0 | $sid = $self->serialization( $ctxt ); | |||||
254 | } | ||||||
255 | } | ||||||
256 | |||||||
257 | 0 | $self->panic( $sid, $ctxt ); | |||||
258 | } | ||||||
259 | |||||||
260 | sub serialization { | ||||||
261 | # i require both modules here, so one can implement his own | ||||||
262 | # serialization | ||||||
263 | 0 | 0 | 0 | require XML::LibXML; | |||
264 | 0 | require XML::LibXSLT; | |||||
265 | |||||||
266 | 0 | my $self = shift; | |||||
267 | 0 | my $ctxt = shift; | |||||
268 | 0 | my $id; | |||||
269 | |||||||
270 | 0 | my %header = $self->setHttpHeader( $ctxt ); | |||||
271 | |||||||
272 | 0 | my $xml_doc = $self->getDOM( $ctxt ); | |||||
273 | 0 | 0 | if ( not defined $xml_doc ) { | ||||
274 | 0 | debug_msg( 10, "use old style interface"); | |||||
275 | 0 | $xml_doc = $self->requestDOM( $ctxt ); | |||||
276 | } | ||||||
277 | # if still no document is available | ||||||
278 | 0 | 0 | if ( not defined $xml_doc ) { | ||||
279 | 0 | debug_msg( 10, "no DOM defined; use empty DOM" ); | |||||
280 | 0 | $xml_doc = XML::LibXML::Document->new; | |||||
281 | # the following line is to keep xpath.c quiet! | ||||||
282 | 0 | $xml_doc->setDocumentElement( $xml_doc->createElement( "dummy" ) ); | |||||
283 | } | ||||||
284 | |||||||
285 | 0 | 0 | 0 | if( defined $self->passthru() && $self->passthru() == 1 ) { | |||
286 | # this is a useful feature for DOM debugging | ||||||
287 | 0 | debug_msg( 10, "attempt to pass the DOM to the client" ); | |||||
288 | 0 | $header{-type} = 'text/xml'; | |||||
289 | 0 | print $self->header( %header ); | |||||
290 | 0 | print $xml_doc->toString(); | |||||
291 | 0 | return 0; | |||||
292 | } | ||||||
293 | |||||||
294 | 0 | my $stylesheet = $self->getStylesheet( $ctxt ); | |||||
295 | |||||||
296 | 0 | my ( $xsl_dom, $style, $res ); | |||||
297 | 0 | my $parser = XML::LibXML->new(); | |||||
298 | 0 | my $xslt = XML::LibXSLT->new(); | |||||
299 | |||||||
300 | 0 | 0 | 0 | if ( ref( $stylesheet ) ) { | |||
0 | |||||||
301 | 0 | debug_msg( 5, "stylesheet is reference" ); | |||||
302 | 0 | $xsl_dom = $stylesheet; | |||||
303 | } | ||||||
304 | elsif ( -f $stylesheet && -r $stylesheet ) { | ||||||
305 | 0 | debug_msg( 5, "filename is $stylesheet" ); | |||||
306 | 0 | eval { | |||||
307 | 0 | $xsl_dom = $parser->parse_file( $stylesheet ); | |||||
308 | }; | ||||||
309 | 0 | 0 | if ( $@ ) { | ||||
310 | 0 | debug_msg( 3, "Corrupted Stylesheet:\n broken XML\n". $@ ); | |||||
311 | 0 | $self->setPanicMsg( "Corrupted document:\n broken XML\n". $@ ); | |||||
312 | 0 | return -2; | |||||
313 | } | ||||||
314 | } | ||||||
315 | else { | ||||||
316 | # first test the new style interface | ||||||
317 | 0 | my $xslstring = $self->getStylesheetString( $ctxt ); | |||||
318 | 0 | 0 | if ( length $xslstring ) { | ||||
319 | 0 | debug_msg( 5, "stylesheet is xml string" ); | |||||
320 | 0 | eval { $xsl_dom = $parser->parse_string( $xslstring ); }; | |||||
0 | |||||||
321 | 0 | 0 | 0 | if ( $@ || not defined $xsl_dom ) { | |||
322 | # the parse failed !!! | ||||||
323 | 0 | debug_msg( 3, "Corrupted Stylesheet String:\n". $@ ."\n" ); | |||||
324 | 0 | $self->setPanicMsg( "Corrupted Stylesheet String:\n". $@ ); | |||||
325 | 0 | return -2; | |||||
326 | } | ||||||
327 | } | ||||||
328 | else { | ||||||
329 | # now test old style interface | ||||||
330 | # will be removed with the next major release | ||||||
331 | |||||||
332 | 0 | debug_msg( 5, "old style interface to select the stylesheet" ); | |||||
333 | 0 | $stylesheet = $self->selectStylesheet( $ctxt ); | |||||
334 | 0 | 0 | 0 | if ( ref( $stylesheet ) ) { | |||
0 | |||||||
335 | 0 | debug_msg( 5, "stylesheet is reference" ); | |||||
336 | 0 | $xsl_dom = $stylesheet; | |||||
337 | } | ||||||
338 | elsif ( -f $stylesheet && -r $stylesheet ) { | ||||||
339 | 0 | debug_msg( 5, "filename is $stylesheet" ); | |||||
340 | 0 | eval { | |||||
341 | 0 | $xsl_dom = $parser->parse_file( $stylesheet ); | |||||
342 | }; | ||||||
343 | 0 | 0 | if ( $@ ) { | ||||
344 | 0 | debug_msg( 3, "Corrupted Stylesheet:\n broken XML\n". $@ ); | |||||
345 | 0 | $self->setPanicMsg( "Corrupted document:\n broken XML\n". $@ ); | |||||
346 | 0 | return -2; | |||||
347 | } | ||||||
348 | } | ||||||
349 | else { | ||||||
350 | 0 | debug_msg( 2 , "panic stylesheet file $stylesheet does not exist" ); | |||||
351 | 0 | $self->setPanicMsg( "$stylesheet" ); | |||||
352 | 0 | 0 | return length $stylesheet ? -2 : -1 ; | ||||
353 | } | ||||||
354 | } | ||||||
355 | } | ||||||
356 | |||||||
357 | 0 | eval { | |||||
358 | 0 | $style = $xslt->parse_stylesheet( $xsl_dom ); | |||||
359 | # $style = $xslt->parse_stylesheet_file( $file ); | ||||||
360 | }; | ||||||
361 | 0 | 0 | if( $@ ) { | ||||
362 | 0 | debug_msg( 3, "Corrupted Stylesheet:\n". $@ ."\n" ); | |||||
363 | 0 | $self->setPanicMsg( "Corrupted Stylesheet:\n". $@ ); | |||||
364 | 0 | return -2; | |||||
365 | } | ||||||
366 | |||||||
367 | 0 | my %xslparam = $self->getXSLParameter( $ctxt ); | |||||
368 | 0 | eval { | |||||
369 | # first do special xpath encoding of the parameter | ||||||
370 | 0 | 0 | 0 | if ( %xslparam && scalar( keys %xslparam ) > 0 ) { | |||
371 | 0 | my @list; | |||||
372 | 0 | foreach my $key ( keys %xslparam ) { | |||||
373 | # check for multivalued parameters stored in a \0 separated string by CGI.pm :-/ | ||||||
374 | 0 | 0 | if ( $xslparam{$key} =~ /\0/ ) { | ||||
375 | 0 | push @list, $key, (split("\0",$xslparam{$key}))[-1]; | |||||
376 | } | ||||||
377 | else { | ||||||
378 | 0 | push @list, $key, $xslparam{$key}; | |||||
379 | } | ||||||
380 | } | ||||||
381 | 0 | $res = $style->transform( $xml_doc, | |||||
382 | XML::LibXSLT::xpath_to_string(@list) | ||||||
383 | ); | ||||||
384 | } | ||||||
385 | else { | ||||||
386 | 0 | $res = $style->transform( $xml_doc ); | |||||
387 | } | ||||||
388 | }; | ||||||
389 | 0 | 0 | if( $@ ) { | ||||
390 | 0 | debug_msg( 3, "Broken Transformation:\n". $@ ."\n" ); | |||||
391 | 0 | $self->setPanicMsg( "Broken Transformation:\n". $@ ); | |||||
392 | 0 | return -2; | |||||
393 | } | ||||||
394 | |||||||
395 | # override content-type with the correct content-type | ||||||
396 | # of the style (is this ok?) | ||||||
397 | 0 | $header{-type} = $style->media_type; | |||||
398 | 0 | $header{-charset} = $style->output_encoding; | |||||
399 | |||||||
400 | 0 | debug_msg( 10, "serialization do output" ); | |||||
401 | # we want nice xhtml and since the output_string does not the | ||||||
402 | # right job | ||||||
403 | 0 | my $out_string= undef; | |||||
404 | |||||||
405 | 0 | debug_msg( 9, "serialization get output string" ); | |||||
406 | 0 | eval { | |||||
407 | 0 | $out_string = $style->output_string( $res ); | |||||
408 | }; | ||||||
409 | 0 | debug_msg( 10, "serialization rendered output" ); | |||||
410 | 0 | 0 | if ( $@ ) { | ||||
411 | 0 | debug_msg( 3, "Corrupted Output:\n", $@ , "\n" ); | |||||
412 | 0 | $self->setPanicMsg( "Corrupted Output:\n". $@ ); | |||||
413 | 0 | return -2; | |||||
414 | } | ||||||
415 | else { | ||||||
416 | # do the output | ||||||
417 | 0 | print $self->header( %header ); | |||||
418 | 0 | print $out_string; | |||||
419 | 0 | debug_msg( 10, "output printed" ); | |||||
420 | } | ||||||
421 | |||||||
422 | 0 | return 0; | |||||
423 | } | ||||||
424 | |||||||
425 | sub panic { | ||||||
426 | 0 | 0 | 1 | my ( $self, $pid ) = @_; | |||
427 | 0 | 0 | return unless $pid < 0; | ||||
428 | 0 | $pid++; | |||||
429 | 0 | $pid*=-1; | |||||
430 | |||||||
431 | 0 | my $str = "Application Panic: "; | |||||
432 | 0 | $str = "PANIC $pid :" . $CGI::XMLApplication::panic[$pid] ; | |||||
433 | # this is nice for debugging from logfiles... | ||||||
434 | 0 | $str = $self->b( $str ) . " \n"; |
|||||
435 | 0 | $str .= $self->pre( $self->getPanicMsg() ); | |||||
436 | 0 | $str .= "Please Contact the Systemadminstrator \n"; |
|||||
437 | |||||||
438 | 0 | debug_msg( 1, "$str" ); | |||||
439 | |||||||
440 | 0 | 0 | if ( $CGI::XMLApplication::Quiet == 1 ) { | ||||
441 | 0 | $str = "Application Panic"; | |||||
442 | } | ||||||
443 | 0 | 0 | if ( $CGI::XMLApplication::Quiet == 2 ) { | ||||
444 | 0 | $str = ""; | |||||
445 | } | ||||||
446 | |||||||
447 | 0 | 0 | my $status = $pid < 3 ? 404 : 500; # default is the application error ... | ||||
448 | 0 | print $self->header( -status => $status ) , $str ,"\n"; | |||||
449 | |||||||
450 | } | ||||||
451 | |||||||
452 | 1; | ||||||
453 | # ################################################################ | ||||||
454 | __END__ |